Segmentation stage 1

This commit is contained in:
2026-04-05 14:55:04 +02:00
parent 5241d06e7b
commit fb35d6c3d4
20 changed files with 467 additions and 117 deletions

0
src/dataflux/__init__.py Normal file
View File

40
src/dataflux/app.py Normal file
View File

@@ -0,0 +1,40 @@
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
import dearpygui.dearpygui as dpg
from dataflux.state import AppState
import dataflux.ui.windows
def run() -> None:
state: AppState = AppState()
# Create application context and viewport
dpg.create_context()
dpg.create_viewport(title='DataFlux', width=600, height=600)
# Add Inter font to registry and bind as main app font
with dpg.font_registry():
app_font = dpg.add_font("./Inter-Regular.ttf", 18)
dpg.bind_font(app_font)
dataflux.ui.windows.build_windows()
dpg.setup_dearpygui()
dpg.show_viewport()
vp_w = dpg.get_viewport_client_width()
vp_h = dpg.get_viewport_client_height()
dpg.configure_item("main_window", pos=(0, 0), width=vp_w, height=vp_h)
dpg.set_primary_window("main_window", True)
dpg.start_dearpygui()
dpg.destroy_context()

View File

View File

@@ -0,0 +1,11 @@
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
import dearpygui.dearpygui as dpg
import dataflux.ui.routines.windows
from dataflux.tags import WINDOW_CONNECTION_MENU
def open_connection_window(sender, app_data, user_data) -> None:
dataflux.ui.routines.windows.update_window_connection_menu_combo()
dpg.show_item(WINDOW_CONNECTION_MENU)

0
src/dataflux/config.py Normal file
View File

View File

View File

@@ -0,0 +1,18 @@
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
import serial.tools.list_ports
def list_serial_ports() -> list[str]:
ports = serial.tools.list_ports.comports()
valid_ports: list[str] = []
for port in ports:
if port.vid is not None and port.pid is not None:
valid_ports.append(port.device)
return valid_ports

18
src/dataflux/state.py Normal file
View File

@@ -0,0 +1,18 @@
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
from dataclasses import dataclass, field
from threading import Lock, Thread
from serial import Serial
@dataclass
class AppState:
running: bool = True
serial_port: Serial | None = None
serial_thread: Thread | None = None
telemetry_thread: Thread | None = None
lock: Lock = field(default_factory=Lock)

8
src/dataflux/tags.py Normal file
View File

@@ -0,0 +1,8 @@
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
MENU_FILE_CONNECT: str = "menu_file_connect"
MENU_FILE_DISCONNECT: str = "menu_file_disconnect"
WINDOW_CONNECTION_MENU: str = "window_connection_menu"
WINDOW_CONNECTION_MENU_COMBO: str = "window_connection_menu_combo"

View File

View File

View File

View File

@@ -0,0 +1,16 @@
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
import dearpygui.dearpygui as dpg
from dataflux.state import AppState
from dataflux.tags import MENU_FILE_CONNECT, MENU_FILE_DISCONNECT
def update_menu_file_connection_status(state: AppState) -> None:
if state.serial_port is None:
dpg.enable_item(MENU_FILE_CONNECT)
dpg.disable_item(MENU_FILE_DISCONNECT)
else:
dpg.disable_item(MENU_FILE_CONNECT)
dpg.enable_item(MENU_FILE_DISCONNECT)

View File

@@ -0,0 +1,11 @@
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
import dearpygui.dearpygui as dpg
from dataflux.services.serial import list_serial_ports
from dataflux.tags import WINDOW_CONNECTION_MENU_COMBO
def update_window_connection_menu_combo() -> None:
ports: list[str] = list_serial_ports()
dpg.configure_item(WINDOW_CONNECTION_MENU_COMBO, items=ports)

View File

@@ -0,0 +1,45 @@
# Copyright (C) 2026 Hector van der Aa <hector@h3cx.dev>
# Copyright (C) 2026 Association Exergie <association.exergie@gmail.com>
# SPDX-License-Identifier: GPL-3.0-or-later
import dearpygui.dearpygui as dpg
import dataflux.callbacks.menu
from dataflux.tags import MENU_FILE_CONNECT, MENU_FILE_DISCONNECT, WINDOW_CONNECTION_MENU, WINDOW_CONNECTION_MENU_COMBO
def build_windows() -> None:
with dpg.window(label='DataFlux',tag="main_window", no_collapse=True):
with dpg.menu_bar():
with dpg.menu(label='File'):
dpg.add_menu_item(label="Connect", enabled=True, tag=MENU_FILE_CONNECT, callback=dataflux.callbacks.menu.open_connection_window)
dpg.add_menu_item(label="Disonnect", enabled=False, tag=MENU_FILE_DISCONNECT)
dpg.add_menu_item(label="Quit")
with dpg.menu(label='Window'):
dpg.add_menu_item(label="Live Data", user_data="page_live_data")
dpg.add_menu_item(label="Lap Recap", user_data="page_lap_recap")
with dpg.child_window(tag="content_area", autosize_x=True, autosize_y=True, border=False):
with dpg.group(tag="page_live_data", show=True):
dpg.add_text("Live Data")
dpg.add_separator()
with dpg.group(horizontal=True):
with dpg.child_window(tag="realtime_stats", width=250, autosize_y=True, border=True):
dpg.add_text("Speed: 25kmh")
with dpg.child_window(tag="data_graphs", autosize_x=True, autosize_y=True, border=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="x_axis_speed")
y_axis = dpg.add_plot_axis(dpg.mvYAxis, label="Speed", tag="y_axis_speed")
dpg.set_axis_limits("y_axis_speed", 0, 50)
dpg.add_line_series([], [], parent=y_axis, tag="speed_series")
with dpg.group(tag="page_lap_recap", show=False):
dpg.add_text("Lap Recap")
dpg.add_separator()
with dpg.window(label="Connection Menu", tag=WINDOW_CONNECTION_MENU, show=False, modal=True, no_collapse=True, width=300):
dpg.add_combo([], tag=WINDOW_CONNECTION_MENU_COMBO)
dpg.add_button(label="Connect")