From fa41798552b6d6bfdd403cd5459646a5039d1263 Mon Sep 17 00:00:00 2001 From: kiruba-vec Date: Mon, 29 Sep 2025 11:52:20 +0530 Subject: [PATCH] chore: update the base version --- backend/__pycache__/models.cpython-313.pyc | Bin 3839 -> 3832 bytes backend/main.py | 29 ++++------- frontend/js/station_selection.js | 57 +++------------------ 3 files changed, 19 insertions(+), 67 deletions(-) diff --git a/backend/__pycache__/models.cpython-313.pyc b/backend/__pycache__/models.cpython-313.pyc index 38b37e55abc5e05990793a23a350c06f102ef07c..4825daaf2ccab0d9c350f33d54958665d9aa7afa 100644 GIT binary patch delta 62 zcmew_`$LxdGcPX}0}#k;I=+!Ridn_W*(xTqIJKxa#yhj9G$}DVu_!Sw#wE2lyClCL QCM-2MH$Qpv1m=8h0FNXU(EtDd delta 46 zcmew%`(Kv(GcPX}0}#yCytI)!idi7g*(xTqIJKxa#yhj9G%0a%6|?N-ZsuHW09y(U A?*IS* diff --git a/backend/main.py b/backend/main.py index 6eb51d1..3fac265 100644 --- a/backend/main.py +++ b/backend/main.py @@ -5,8 +5,7 @@ import json import csv import io import time -from datetime import datetime, timedelta, timezone, time as dt_time -from zoneinfo import ZoneInfo +from datetime import datetime, timedelta from flask import Flask, jsonify, request, Response from flask_socketio import SocketIO, join_room 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) socketio = SocketIO(app, cors_allowed_origins="*") -IST = ZoneInfo("Asia/Kolkata") - # --- User Loader for Flask-Login --- @login_manager.user_loader def load_user(user_id): @@ -286,29 +283,25 @@ def get_stations(): @app.route('/api/stations/daily-stats', methods=['GET']) 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: - # Get the current time and date in your timezone (IST is defined globally) - now_ist = datetime.now(IST) - today_ist = now_ist.date() + # --- CHANGE THESE TWO LINES --- + today_start = datetime.combine(datetime.utcnow().date(), time.min) + today_end = datetime.combine(datetime.utcnow().date(), time.max) - # Calculate the precise start and end of that day - 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 --- + # This is an efficient query that groups by station_id and counts events in one go stats = db.session.query( MqttLog.station_id, - func.count(case((MqttLog.payload['eventType'].astext == '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'].astext == 'EVENT_SWAP_ABORTED', 1))).label('aborted') + func.count(case((MqttLog.payload['eventType'] == 'EVENT_SWAP_START', 1))).label('total_starts'), + func.count(case((MqttLog.payload['eventType'] == 'EVENT_SWAP_ENDED', 1))).label('completed'), + func.count(case((MqttLog.payload['eventType'] == 'EVENT_SWAP_ABORTED', 1))).label('aborted') ).filter( MqttLog.topic_type == 'EVENTS', - # Use the new timezone-aware date range - MqttLog.timestamp.between(start_of_day_ist, end_of_day_ist) + MqttLog.timestamp.between(today_start, today_end) ).group_by(MqttLog.station_id).all() + # Convert the list of tuples into a dictionary for easy lookup stats_dict = { station_id: { "total_starts": total_starts, diff --git a/frontend/js/station_selection.js b/frontend/js/station_selection.js index 6f719fa..9433cd7 100644 --- a/frontend/js/station_selection.js +++ b/frontend/js/station_selection.js @@ -117,10 +117,7 @@ document.addEventListener('DOMContentLoaded', () => { //-- NEW: Fetch and apply daily stats to each card --- const fetchAndApplyStats = async () => { try { - const response = await fetch(`${API_BASE}/stations/daily-stats`, { - method: 'GET', - credentials: 'include' // <-- ADD THIS LINE - }); + const response = await fetch(`${API_BASE}/stations/daily-stats`); if (!response.ok) return; // Fail silently if stats aren't available const stats = await response.json(); @@ -161,10 +158,7 @@ document.addEventListener('DOMContentLoaded', () => { } try { - const response = await fetch(`${API_BASE}/stations/${stationId}`, { - method: 'DELETE', - credentials: 'include' // <-- ADD THIS LINE - }); + const response = await fetch(`${API_BASE}/stations/${stationId}`, { method: 'DELETE' }); if (response.ok) { alert(`Station "${stationName}" removed successfully.`); allStations = []; // Force a full refresh on next poll @@ -181,61 +175,26 @@ document.addEventListener('DOMContentLoaded', () => { }); // --- 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 () => { try { - const response = await fetch(`${API_BASE}/stations`, { credentials: 'include' }); - if (response.status === 401) { - localStorage.clear(); - window.location.href = 'index.html'; - return; - } + const response = await fetch(`${API_BASE}/stations`); 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; - // A more efficient status-only update could go here later - renderStations(allStations); // Re-render to update statuses + updateStationStatuses(allStations); + 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) { 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); } };