chore: update the base version

main
kiruba-vec 2025-09-29 11:52:20 +05:30
parent 2c910cfcc5
commit fa41798552
3 changed files with 19 additions and 67 deletions

View File

@ -5,8 +5,7 @@ import json
import csv import csv
import io import io
import time import time
from datetime import datetime, timedelta, timezone, time as dt_time from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
from flask import Flask, jsonify, request, Response from flask import Flask, jsonify, request, Response
from flask_socketio import SocketIO, join_room from flask_socketio import SocketIO, join_room
from flask_cors import CORS from flask_cors import CORS
@ -56,8 +55,6 @@ app.config['SECRET_KEY'] = os.getenv("SECRET_KEY", "a_very_secret_key")
db.init_app(app) db.init_app(app)
socketio = SocketIO(app, cors_allowed_origins="*") socketio = SocketIO(app, cors_allowed_origins="*")
IST = ZoneInfo("Asia/Kolkata")
# --- User Loader for Flask-Login --- # --- User Loader for Flask-Login ---
@login_manager.user_loader @login_manager.user_loader
def load_user(user_id): def load_user(user_id):
@ -286,29 +283,25 @@ def get_stations():
@app.route('/api/stations/daily-stats', methods=['GET']) @app.route('/api/stations/daily-stats', methods=['GET'])
def get_all_station_stats(): def get_all_station_stats():
""" """
Calculates the swap statistics for the current calendar day in the IST timezone. Calculates the swap statistics for today for all stations.
""" """
try: try:
# Get the current time and date in your timezone (IST is defined globally) # --- CHANGE THESE TWO LINES ---
now_ist = datetime.now(IST) today_start = datetime.combine(datetime.utcnow().date(), time.min)
today_ist = now_ist.date() today_end = datetime.combine(datetime.utcnow().date(), time.max)
# Calculate the precise start and end of that day # This is an efficient query that groups by station_id and counts events in one go
start_of_day_ist = datetime.combine(today_ist, dt_time.min, tzinfo=IST)
end_of_day_ist = datetime.combine(today_ist, dt_time.max, tzinfo=IST)
# --- The rest of the query uses this new date range ---
stats = db.session.query( stats = db.session.query(
MqttLog.station_id, MqttLog.station_id,
func.count(case((MqttLog.payload['eventType'].astext == 'EVENT_SWAP_START', 1))).label('total_starts'), func.count(case((MqttLog.payload['eventType'] == 'EVENT_SWAP_START', 1))).label('total_starts'),
func.count(case((MqttLog.payload['eventType'].astext == 'EVENT_SWAP_ENDED', 1))).label('completed'), func.count(case((MqttLog.payload['eventType'] == 'EVENT_SWAP_ENDED', 1))).label('completed'),
func.count(case((MqttLog.payload['eventType'].astext == 'EVENT_SWAP_ABORTED', 1))).label('aborted') func.count(case((MqttLog.payload['eventType'] == 'EVENT_SWAP_ABORTED', 1))).label('aborted')
).filter( ).filter(
MqttLog.topic_type == 'EVENTS', MqttLog.topic_type == 'EVENTS',
# Use the new timezone-aware date range MqttLog.timestamp.between(today_start, today_end)
MqttLog.timestamp.between(start_of_day_ist, end_of_day_ist)
).group_by(MqttLog.station_id).all() ).group_by(MqttLog.station_id).all()
# Convert the list of tuples into a dictionary for easy lookup
stats_dict = { stats_dict = {
station_id: { station_id: {
"total_starts": total_starts, "total_starts": total_starts,

View File

@ -117,10 +117,7 @@ document.addEventListener('DOMContentLoaded', () => {
//-- NEW: Fetch and apply daily stats to each card --- //-- NEW: Fetch and apply daily stats to each card ---
const fetchAndApplyStats = async () => { const fetchAndApplyStats = async () => {
try { try {
const response = await fetch(`${API_BASE}/stations/daily-stats`, { const response = await fetch(`${API_BASE}/stations/daily-stats`);
method: 'GET',
credentials: 'include' // <-- ADD THIS LINE
});
if (!response.ok) return; // Fail silently if stats aren't available if (!response.ok) return; // Fail silently if stats aren't available
const stats = await response.json(); const stats = await response.json();
@ -161,10 +158,7 @@ document.addEventListener('DOMContentLoaded', () => {
} }
try { try {
const response = await fetch(`${API_BASE}/stations/${stationId}`, { const response = await fetch(`${API_BASE}/stations/${stationId}`, { method: 'DELETE' });
method: 'DELETE',
credentials: 'include' // <-- ADD THIS LINE
});
if (response.ok) { if (response.ok) {
alert(`Station "${stationName}" removed successfully.`); alert(`Station "${stationName}" removed successfully.`);
allStations = []; // Force a full refresh on next poll allStations = []; // Force a full refresh on next poll
@ -181,61 +175,26 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
// --- DATA FETCHING & POLLING --- // --- DATA FETCHING & POLLING ---
// const loadAndPollStations = async () => {
// try {
// const response = await fetch(`${API_BASE}/stations`, {
// method: 'GET',
// credentials: 'include' // <-- ADD THIS LINE
// });
// if (!response.ok) throw new Error('Failed to fetch stations');
// const newStationList = await response.json();
// // If the number of stations has changed, we must do a full re-render.
// if (newStationList.length !== allStations.length) {
// allStations = newStationList;
// renderStations(allStations);
// } else {
// // Otherwise, we can do a more efficient status-only update.
// allStations = newStationList;
// updateStationStatuses(allStations);
// fetchAndApplyStats(); // Fetch and update daily stats
// }
// } catch (error) {
// console.error(error);
// stationCountEl.textContent = 'Could not load stations. Is the backend running?';
// if (pollingInterval) clearInterval(pollingInterval);
// }
// };
const loadAndPollStations = async () => { const loadAndPollStations = async () => {
try { try {
const response = await fetch(`${API_BASE}/stations`, { credentials: 'include' }); const response = await fetch(`${API_BASE}/stations`);
if (response.status === 401) {
localStorage.clear();
window.location.href = 'index.html';
return;
}
if (!response.ok) throw new Error('Failed to fetch stations'); if (!response.ok) throw new Error('Failed to fetch stations');
const newStationList = await response.json(); const newStationList = await response.json();
// If the number of stations has changed, we must do a full re-render.
if (newStationList.length !== allStations.length) { if (newStationList.length !== allStations.length) {
allStations = newStationList; allStations = newStationList;
renderStations(allStations); renderStations(allStations);
} else { } else {
// Otherwise, we can do a more efficient status-only update.
allStations = newStationList; allStations = newStationList;
// A more efficient status-only update could go here later updateStationStatuses(allStations);
renderStations(allStations); // Re-render to update statuses fetchAndApplyStats(); // Fetch and update daily stats
} }
// --- THIS IS THE FIX ---
// Call this AFTER the if/else, so it always runs on a successful fetch.
fetchAndApplyStats();
} catch (error) { } catch (error) {
console.error(error); console.error(error);
if (stationCountEl) stationCountEl.textContent = 'Could not load stations. Is the backend running?'; stationCountEl.textContent = 'Could not load stations. Is the backend running?';
if (pollingInterval) clearInterval(pollingInterval); if (pollingInterval) clearInterval(pollingInterval);
} }
}; };