From 6b7760a8be5fa63fcdf79e8ec2b29dc13fa082e6 Mon Sep 17 00:00:00 2001 From: Hector van der Aa Date: Mon, 8 Jun 2026 14:10:44 +0200 Subject: [PATCH] Added map to lap recap --- src/dataflux/app.py | 16 ++--- src/dataflux/ui/windows.py | 126 ++++++++++++++++++++++--------------- src/dataflux/ui/worker.py | 17 +++-- 3 files changed, 98 insertions(+), 61 deletions(-) diff --git a/src/dataflux/app.py b/src/dataflux/app.py index 81941b0..8ad1a44 100644 --- a/src/dataflux/app.py +++ b/src/dataflux/app.py @@ -2,7 +2,7 @@ # Copyright (C) 2026 Association Exergie # SPDX-License-Identifier: GPL-3.0-or-later -from datetime import datetime +from datetime import datetime, timezone from pathlib import Path import sys from threading import Thread @@ -43,10 +43,12 @@ def _asset_path(relative_path: str) -> str: def run() -> None: state: AppState = AppState() - state.start_time = datetime.now() + state.start_time = datetime.now(timezone.utc) dpgm.configure( - user_agent="DataFlux/0.1 contact:h3cx@h3cx.dev", cache_dir="./.cache" + user_agent="DataFlux/0.1 contact:h3cx@h3cx.dev", + cache_dir="./.cache", + disk_cache_max_bytes=200_000_000, ) dpg.create_context() @@ -56,7 +58,9 @@ def run() -> None: dpg.create_viewport(title="DataFlux", width=600, height=600) with dpg.font_registry(): - app_font = dpg.add_font(_asset_path("assets/fonts/Inter-Regular.ttf"), 18 * 2) + app_font = dpg.add_font( + _asset_path("assets/fonts/Inter-Regular.ttf"), 18 * 2 + ) mono_font = dpg.add_font( _asset_path("assets/fonts/JetBrainsMono-Regular.ttf"), size=36, @@ -84,9 +88,7 @@ def run() -> None: state.telemetry_thread.start() state.ports_thread_running = True - state.ports_thread = Thread( - target=dataflux.services.ports.ports_worker, args=(state,), daemon=True - ) + state.ports_thread = Thread() state.ports_thread.start() ui_updater = dataflux.ui.worker.UiFrameUpdater() diff --git a/src/dataflux/ui/windows.py b/src/dataflux/ui/windows.py index 4877a7e..4bb819a 100644 --- a/src/dataflux/ui/windows.py +++ b/src/dataflux/ui/windows.py @@ -340,55 +340,83 @@ def build_windows(state: AppState) -> None: ) with dpg.group(tag=PAGE_LAP_RECAP, show=False): - dpg.add_text("Lap Recap") - dpg.add_separator() - - with dpg.plot(label="Speed", height=250, width=-1, no_inputs=True): - dpg.add_plot_legend() - dpg.add_plot_axis( - dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_SPEED_LR - ) - y_axis_speed = dpg.add_plot_axis( - dpg.mvYAxis, label="Speed", tag=GRAPH_Y_AXIS_SPEED_LR - ) - dpg.set_axis_limits(GRAPH_Y_AXIS_SPEED_LR, ymin=0, ymax=50) - dpg.set_axis_limits(GRAPH_X_AXIS_SPEED_LR, ymin=-30, ymax=0) - dpg.add_line_series( - [], [], parent=y_axis_speed, tag=GRAPH_SERIES_SPEED_LR - ) - with dpg.plot( - label="Battery Voltage", - height=250, - width=-1, - no_inputs=True, - ): - dpg.add_plot_legend() - dpg.add_plot_axis( - dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_VBAT_LR - ) - y_axis_vbat = dpg.add_plot_axis( - dpg.mvYAxis, label="Voltage", tag=GRAPH_Y_AXIS_VBAT_LR - ) - dpg.set_axis_limits(GRAPH_Y_AXIS_VBAT_LR, ymin=0, ymax=20) - dpg.set_axis_limits(GRAPH_X_AXIS_VBAT_LR, ymin=-30, ymax=0) - dpg.add_line_series( - [], [], parent=y_axis_vbat, tag=GRAPH_SERIES_VBAT_LR - ) - with dpg.plot( - label="Engine Temp", height=250, width=-1, no_inputs=True - ): - dpg.add_plot_legend() - dpg.add_plot_axis( - dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_TENG_LR - ) - y_axis_teng = dpg.add_plot_axis( - dpg.mvYAxis, label="Temperature", tag=GRAPH_Y_AXIS_TENG_LR - ) - dpg.set_axis_limits(GRAPH_Y_AXIS_TENG_LR, ymin=0, ymax=120) - dpg.set_axis_limits(GRAPH_X_AXIS_TENG_LR, ymin=-30, ymax=0) - dpg.add_line_series( - [], [], parent=y_axis_teng, tag=GRAPH_SERIES_TENG_LR - ) + with dpg.group(horizontal=True): + with dpg.child_window( + # tag=SUB_PAGE_MAP, + width=1000, + autosize_y=True, + border=True, + show=True, + no_scrollbar=True, + ): + with dpg.plot( + label="Speed", height=250, width=-1, no_inputs=True + ): + dpg.add_plot_legend() + dpg.add_plot_axis( + dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_SPEED_LR + ) + y_axis_speed = dpg.add_plot_axis( + dpg.mvYAxis, label="Speed", tag=GRAPH_Y_AXIS_SPEED_LR + ) + dpg.set_axis_limits(GRAPH_Y_AXIS_SPEED_LR, ymin=0, ymax=50) + dpg.set_axis_limits(GRAPH_X_AXIS_SPEED_LR, ymin=-30, ymax=0) + dpg.add_line_series( + [], [], parent=y_axis_speed, tag=GRAPH_SERIES_SPEED_LR + ) + with dpg.plot( + label="Battery Voltage", + height=250, + width=-1, + no_inputs=True, + ): + dpg.add_plot_legend() + dpg.add_plot_axis( + dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_VBAT_LR + ) + y_axis_vbat = dpg.add_plot_axis( + dpg.mvYAxis, label="Voltage", tag=GRAPH_Y_AXIS_VBAT_LR + ) + dpg.set_axis_limits(GRAPH_Y_AXIS_VBAT_LR, ymin=0, ymax=20) + dpg.set_axis_limits(GRAPH_X_AXIS_VBAT_LR, ymin=-30, ymax=0) + dpg.add_line_series( + [], [], parent=y_axis_vbat, tag=GRAPH_SERIES_VBAT_LR + ) + with dpg.plot( + label="Engine Temp", height=250, width=-1, no_inputs=True + ): + dpg.add_plot_legend() + dpg.add_plot_axis( + dpg.mvXAxis, label="Time", tag=GRAPH_X_AXIS_TENG_LR + ) + y_axis_teng = dpg.add_plot_axis( + dpg.mvYAxis, + label="Temperature", + tag=GRAPH_Y_AXIS_TENG_LR, + ) + dpg.set_axis_limits(GRAPH_Y_AXIS_TENG_LR, ymin=0, ymax=120) + dpg.set_axis_limits(GRAPH_X_AXIS_TENG_LR, ymin=-30, ymax=0) + dpg.add_line_series( + [], [], parent=y_axis_teng, tag=GRAPH_SERIES_TENG_LR + ) + with dpg.child_window( + # tag=SUB_PAGE_MAP, + autosize_x=True, + autosize_y=True, + border=True, + show=True, + no_scrollbar=True, + ): + with dpgm.map_widget( + tag="recap_map", + center=(47.843834, 1.937727), + zoom=15, + width=-1, + height=-1, + ): + dpgm.add_trajectory(tag="recap_trajectory", show=False) + # pass + # dpgm.add_trajectory("recap_trajectory") with dpg.group(tag=PAGE_SERIAL_CONSOLE, show=False): with dpg.child_window( diff --git a/src/dataflux/ui/worker.py b/src/dataflux/ui/worker.py index 0524528..15c8763 100644 --- a/src/dataflux/ui/worker.py +++ b/src/dataflux/ui/worker.py @@ -115,7 +115,7 @@ class UiFrameUpdater: try: flash_until = max(flash_until, now + float(duration)) - except (TypeError, ValueError): + except TypeError, ValueError: continue dpg.bind_item_theme(tag, THEME_STATUS_CONNECTED_BRIGHT) @@ -167,6 +167,13 @@ class UiFrameUpdater: dpg.set_axis_limits(GRAPH_X_AXIS_SPEED_LR, ymin=axis_min, ymax=axis_max) dpg.set_axis_limits(GRAPH_X_AXIS_VBAT_LR, ymin=axis_min, ymax=axis_max) dpg.set_axis_limits(GRAPH_X_AXIS_TENG_LR, ymin=axis_min, ymax=axis_max) + dpgm.update_trajectory( + tag="recap_trajectory", + lats=state.lap_recap_buffers.lat, + lons=state.lap_recap_buffers.lng, + map_tag="recap_map", + ) + dpgm.set_overlay_show(tag="recap_trajectory", show=True, map_tag="recap_map") def _update_live_telemetry(self, state: AppState) -> None: if not (state.lora_thread_running and state.telemetry_valid): @@ -185,7 +192,7 @@ class UiFrameUpdater: veh_speed = float(state.latest_telemetry["speed"]) vbat = float(state.latest_telemetry["vbat"]) teng = float(state.latest_telemetry["teng"]) - except (KeyError, TypeError, ValueError): + except KeyError, TypeError, ValueError: state.telemetry_valid = False self._write_no_data() return @@ -244,12 +251,12 @@ class UiFrameUpdater: with state.lock: try: lat = float(state.latest_telemetry.get("lat", DEFAULT_LAT)) - except (TypeError, ValueError): + except TypeError, ValueError: lat = DEFAULT_LAT try: lon = float(state.latest_telemetry.get("lng", DEFAULT_LNG)) - except (TypeError, ValueError): + except TypeError, ValueError: lon = DEFAULT_LNG try: dpgm.set_center(lat=lat, lon=lon, map_tag="live_map") @@ -283,7 +290,7 @@ class UiFrameUpdater: try: lat = float(state.latest_telemetry["lat"]) lon = float(state.latest_telemetry["lng"]) - except (KeyError, TypeError, ValueError): + except KeyError, TypeError, ValueError: return try: