fix: update_trips loop

This commit is contained in:
Florian Bezannier
2025-09-30 12:54:02 +02:00
parent 2fab264881
commit b658859c67
2 changed files with 73 additions and 44 deletions
+11
View File
@@ -1,3 +1,4 @@
import contextlib
from functools import wraps
from threading import Semaphore, Timer
from typing import List
@@ -60,3 +61,13 @@ def get_positions(locations):
params={"locations": locations_str},
timeout=TIMEOUT_IN_S)
return res.json()["results"]
@contextlib.contextmanager
def nonblocking(lock):
locked = lock.acquire(False)
try:
yield locked
finally:
if locked:
lock.release()
+62 -44
View File
@@ -1,4 +1,5 @@
from datetime import datetime
from threading import Lock
from typing import List
from urllib.parse import parse_qs, urlparse
@@ -9,6 +10,7 @@ from dash.exceptions import PreventUpdate
import time
from flask import request
from psa_car_controller.common import utils
from psa_car_controller.common.mylogger import CustomLogger
from psa_car_controller.psacc.application.car_controller import PSACarController
from psa_car_controller.psacc.model.car import Cars, Car
@@ -175,57 +177,73 @@ def create_callback(): # noqa: MC0001
CALLBACK_CREATED = True
no_concurrent_update_trip = Lock()
DATA_READY = False
def update_trips():
global trips, chargings, cached_layout, min_date, max_date, min_millis, max_millis, step, marks
logger.info("update_data")
conn = Database.get_db()
Database.add_altitude_to_db(conn)
min_date = None
max_date = None
if APP.is_good:
car = get_default_car() # todo handle multiple car
global trips, chargings, cached_layout, min_date, max_date, min_millis, max_millis, step, marks, DATA_READY
# we allow on thread waiting for no_concurrent_update_trip lock
with utils.nonblocking(no_concurrent_update_trip) as locked:
if not locked:
logger.debug("update_trips already in progress")
return
try:
trips_by_vin = Trips.get_trips(Cars([car]))
trips = trips_by_vin[car.vin]
assert len(trips) > 0
min_date = trips[0].start_at
max_date = trips[-1].start_at
figures.get_figures(trips[0].car)
except (AssertionError, KeyError):
logger.debug("No trips yet")
figures.get_figures(Car("vin", "vid", "brand"))
try:
chargings = Charging.get_chargings()
assert len(chargings) > 0
if min_date:
min_date = min(min_date, chargings[0]["start_at"])
max_date = max(max_date, chargings[-1]["start_at"])
else:
min_date = chargings[0]["start_at"]
max_date = chargings[-1]["start_at"]
except AssertionError:
logger.debug("No chargings yet")
if min_date is None:
return
# update for slider
try:
logger.debug("min_date:%s - max_date:%s", min_date, max_date)
min_millis = unix_time_millis(min_date)
max_millis = unix_time_millis(max_date)
step = (max_millis - min_millis) / 100
marks = get_marks_from_start_end(min_date, max_date)
cached_layout = None # force regenerate layout
figures.get_figures(car)
except (ValueError, IndexError):
logger.error("update_trips (slider): %s", exc_info=True)
except AttributeError:
logger.debug("position table is probably empty :", exc_info=True)
return
logger.info("update_trips")
conn = Database.get_db()
Database.add_altitude_to_db(conn)
min_date = None
max_date = None
if APP.is_good:
car = get_default_car() # todo handle multiple car
try:
trips_by_vin = Trips.get_trips(Cars([car]))
trips = trips_by_vin[car.vin]
assert len(trips) > 0
min_date = trips[0].start_at
max_date = trips[-1].start_at
figures.get_figures(trips[0].car)
except (AssertionError, KeyError):
logger.debug("No trips yet")
figures.get_figures(Car("vin", "vid", "brand"))
try:
chargings = Charging.get_chargings()
assert len(chargings) > 0
if min_date:
min_date = min(min_date, chargings[0]["start_at"])
max_date = max(max_date, chargings[-1]["start_at"])
else:
min_date = chargings[0]["start_at"]
max_date = chargings[-1]["start_at"]
except AssertionError:
logger.debug("No chargings yet")
if min_date is None:
return
# update for slider
try:
logger.debug("min_date:%s - max_date:%s", min_date, max_date)
min_millis = unix_time_millis(min_date)
max_millis = unix_time_millis(max_date)
step = (max_millis - min_millis) / 100
marks = get_marks_from_start_end(min_date, max_date)
cached_layout = None # force regenerate layout
figures.get_figures(car)
except (ValueError, IndexError):
logger.error("update_trips (slider): %s", exc_info=True)
except AttributeError:
logger.debug("position table is probably empty :", exc_info=True)
finally:
DATA_READY = True
logger.debug("trips updated !")
return
def serve_layout():
global cached_layout
if cached_layout is None:
while not DATA_READY:
logger.debug("wait for trips data...")
time.sleep(3)
logger.debug("Create new layout")
fig_filter = FigureFilter()
try: