Segmentation stage 1
This commit is contained in:
118
main.py
118
main.py
@@ -1,119 +1,7 @@
|
||||
# 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 time
|
||||
import threading
|
||||
from serial import Serial
|
||||
import serial.tools.list_ports
|
||||
from dataflux.app import run
|
||||
|
||||
running = True
|
||||
|
||||
def quit_app(sender, app_data, user_data):
|
||||
running = False
|
||||
dpg.destroy_context()
|
||||
|
||||
|
||||
def serial_worker():
|
||||
while running:
|
||||
|
||||
print(serial_port.read())
|
||||
serial_port.close()
|
||||
|
||||
serial_port = Serial()
|
||||
serial_thread = threading.Thread(target=serial_worker, daemon=True)
|
||||
|
||||
def telemetry_worker():
|
||||
speed_data_x = [-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0]
|
||||
speed_data_y = [5,6,7,8,9,10,9,8,7,6,5]
|
||||
while running:
|
||||
time.sleep(0.1)
|
||||
y_val = speed_data_y.pop(0)
|
||||
|
||||
speed_data_y.append(y_val)
|
||||
dpg.set_value("speed_series", [speed_data_x, speed_data_y])
|
||||
dpg.set_axis_limits("x_axis_speed", speed_data_x[0], speed_data_x[-1])
|
||||
|
||||
def show_page(sender, app_data, user_data):
|
||||
pages = ["page_live_data", "page_lap_recap"]
|
||||
|
||||
for page in pages:
|
||||
dpg.hide_item(page)
|
||||
|
||||
dpg.show_item(user_data)
|
||||
|
||||
def show_connection_menu(sender, app_data, user_data):
|
||||
ports = serial.tools.list_ports.comports()
|
||||
port_names = []
|
||||
for port in ports:
|
||||
if port.vid is not None and port.pid is not None:
|
||||
port_names.append(port.device)
|
||||
|
||||
dpg.configure_item("serial_combo", items=port_names)
|
||||
dpg.show_item("connection_menu")
|
||||
|
||||
def connect_to_serial(sender, app_data, user_data):
|
||||
global serial_port
|
||||
port = dpg.get_value("serial_combo")
|
||||
print("Connecting to " + port)
|
||||
serial_port = Serial(port=port, baudrate=115200)
|
||||
serial_thread.start()
|
||||
|
||||
|
||||
dpg.create_context()
|
||||
dpg.create_viewport(title='DataFlux', width=600, height=600)
|
||||
|
||||
with dpg.font_registry():
|
||||
app_font = dpg.add_font("./Inter-Regular.ttf", 18)
|
||||
|
||||
dpg.bind_font(app_font)
|
||||
|
||||
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", callback=show_connection_menu)
|
||||
dpg.add_menu_item(label="Quit", callback=quit_app)
|
||||
with dpg.menu(label='Window'):
|
||||
dpg.add_menu_item(label="Live Data", callback=show_page, user_data="page_live_data")
|
||||
dpg.add_menu_item(label="Lap Recap", callback=show_page, 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="connection_menu", show=False, modal=True, no_collapse=True, width=300):
|
||||
dpg.add_combo([], tag="serial_combo")
|
||||
dpg.add_button(label="Connect", callback=connect_to_serial)
|
||||
|
||||
worker = threading.Thread(target=telemetry_worker, daemon=True)
|
||||
worker.start()
|
||||
|
||||
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()
|
||||
|
||||
running = False
|
||||
dpg.destroy_context()
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
|
||||
139
main2.py
Normal file
139
main2.py
Normal file
@@ -0,0 +1,139 @@
|
||||
# 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 time
|
||||
import threading
|
||||
from serial import Serial
|
||||
import serial.tools.list_ports
|
||||
|
||||
running = True
|
||||
serial_connected = False
|
||||
|
||||
def quit_app(sender, app_data, user_data):
|
||||
global running
|
||||
running = False
|
||||
dpg.destroy_context()
|
||||
|
||||
|
||||
def serial_worker():
|
||||
global serial_connected
|
||||
global serial_port
|
||||
global running
|
||||
while running and serial_connected:
|
||||
if not serial_port.is_open:
|
||||
serial_connected = False
|
||||
print(serial_port.read())
|
||||
serial_connected = False
|
||||
serial_port.close()
|
||||
dpg.enable_item("menu_file_connect")
|
||||
dpg.disable_item("menu_file_disconnect")
|
||||
|
||||
serial_port: Serial | None = None
|
||||
serial_thread: threading.Thread | None = None
|
||||
|
||||
def telemetry_worker():
|
||||
speed_data_x = [-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0]
|
||||
speed_data_y = [5,6,7,8,9,10,9,8,7,6,5]
|
||||
while running:
|
||||
time.sleep(0.1)
|
||||
y_val = speed_data_y.pop(0)
|
||||
|
||||
speed_data_y.append(y_val)
|
||||
dpg.set_value("speed_series", [speed_data_x, speed_data_y])
|
||||
dpg.set_axis_limits("x_axis_speed", speed_data_x[0], speed_data_x[-1])
|
||||
|
||||
def show_page(sender, app_data, user_data):
|
||||
pages = ["page_live_data", "page_lap_recap"]
|
||||
|
||||
for page in pages:
|
||||
dpg.hide_item(page)
|
||||
|
||||
dpg.show_item(user_data)
|
||||
|
||||
def show_connection_menu(sender, app_data, user_data):
|
||||
ports = serial.tools.list_ports.comports()
|
||||
port_names = []
|
||||
for port in ports:
|
||||
if port.vid is not None and port.pid is not None:
|
||||
port_names.append(port.device)
|
||||
|
||||
dpg.configure_item("serial_combo", items=port_names)
|
||||
dpg.show_item("connection_menu")
|
||||
|
||||
def disconnect_serial(sender, app_data, user_data):
|
||||
global serial_connected
|
||||
serial_connected = False
|
||||
|
||||
def connect_to_serial(sender, app_data, user_data):
|
||||
global serial_port
|
||||
global serial_connected
|
||||
global serial_thread
|
||||
port = dpg.get_value("serial_combo")
|
||||
print("Connecting to " + port)
|
||||
serial_port = Serial(port=port, baudrate=115200)
|
||||
serial_connected = True
|
||||
dpg.enable_item("menu_file_disconnect")
|
||||
dpg.disable_item("menu_file_connect")
|
||||
serial_thread = threading.Thread(target=serial_worker, daemon=True)
|
||||
serial_thread.start()
|
||||
|
||||
|
||||
# dpg.create_context()
|
||||
# dpg.create_viewport(title='DataFlux', width=600, height=600)
|
||||
#
|
||||
# with dpg.font_registry():
|
||||
# app_font = dpg.add_font("./Inter-Regular.ttf", 18)
|
||||
#
|
||||
# dpg.bind_font(app_font)
|
||||
|
||||
# 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", callback=show_connection_menu, enabled=True, tag="menu_file_connect")
|
||||
# dpg.add_menu_item(label="Disonnect", callback=disconnect_serial, enabled=False, tag="menu_file_disconnect")
|
||||
# dpg.add_menu_item(label="Quit", callback=quit_app)
|
||||
# with dpg.menu(label='Window'):
|
||||
# dpg.add_menu_item(label="Live Data", callback=show_page, user_data="page_live_data")
|
||||
# dpg.add_menu_item(label="Lap Recap", callback=show_page, 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="connection_menu", show=False, modal=True, no_collapse=True, width=300):
|
||||
# dpg.add_combo([], tag="serial_combo")
|
||||
# dpg.add_button(label="Connect", callback=connect_to_serial)
|
||||
|
||||
worker = threading.Thread(target=telemetry_worker, daemon=True)
|
||||
worker.start()
|
||||
|
||||
# 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()
|
||||
#
|
||||
# running = False
|
||||
# dpg.destroy_context()
|
||||
140
main3.py
Normal file
140
main3.py
Normal file
@@ -0,0 +1,140 @@
|
||||
|
||||
# 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 time
|
||||
import threading
|
||||
from serial import Serial
|
||||
import serial.tools.list_ports
|
||||
|
||||
running = True
|
||||
serial_connected = False
|
||||
|
||||
def quit_app(sender, app_data, user_data):
|
||||
global running
|
||||
running = False
|
||||
dpg.destroy_context()
|
||||
|
||||
|
||||
def serial_worker():
|
||||
global serial_connected
|
||||
global serial_port
|
||||
global running
|
||||
while running and serial_connected:
|
||||
if not serial_port.is_open:
|
||||
serial_connected = False
|
||||
print(serial_port.read())
|
||||
serial_connected = False
|
||||
serial_port.close()
|
||||
dpg.enable_item("menu_file_connect")
|
||||
dpg.disable_item("menu_file_disconnect")
|
||||
|
||||
serial_port: Serial | None = None
|
||||
serial_thread: threading.Thread | None = None
|
||||
|
||||
def telemetry_worker():
|
||||
speed_data_x = [-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0]
|
||||
speed_data_y = [5,6,7,8,9,10,9,8,7,6,5]
|
||||
while running:
|
||||
time.sleep(0.1)
|
||||
y_val = speed_data_y.pop(0)
|
||||
|
||||
speed_data_y.append(y_val)
|
||||
dpg.set_value("speed_series", [speed_data_x, speed_data_y])
|
||||
dpg.set_axis_limits("x_axis_speed", speed_data_x[0], speed_data_x[-1])
|
||||
|
||||
def show_page(sender, app_data, user_data):
|
||||
pages = ["page_live_data", "page_lap_recap"]
|
||||
|
||||
for page in pages:
|
||||
dpg.hide_item(page)
|
||||
|
||||
dpg.show_item(user_data)
|
||||
|
||||
def show_connection_menu(sender, app_data, user_data):
|
||||
ports = serial.tools.list_ports.comports()
|
||||
port_names = []
|
||||
for port in ports:
|
||||
if port.vid is not None and port.pid is not None:
|
||||
port_names.append(port.device)
|
||||
|
||||
dpg.configure_item("serial_combo", items=port_names)
|
||||
dpg.show_item("connection_menu")
|
||||
|
||||
def disconnect_serial(sender, app_data, user_data):
|
||||
global serial_connected
|
||||
serial_connected = False
|
||||
|
||||
def connect_to_serial(sender, app_data, user_data):
|
||||
global serial_port
|
||||
global serial_connected
|
||||
global serial_thread
|
||||
port = dpg.get_value("serial_combo")
|
||||
print("Connecting to " + port)
|
||||
serial_port = Serial(port=port, baudrate=115200)
|
||||
serial_connected = True
|
||||
dpg.enable_item("menu_file_disconnect")
|
||||
dpg.disable_item("menu_file_connect")
|
||||
serial_thread = threading.Thread(target=serial_worker, daemon=True)
|
||||
serial_thread.start()
|
||||
|
||||
|
||||
dpg.create_context()
|
||||
dpg.create_viewport(title='DataFlux', width=600, height=600)
|
||||
|
||||
with dpg.font_registry():
|
||||
app_font = dpg.add_font("./Inter-Regular.ttf", 18)
|
||||
|
||||
dpg.bind_font(app_font)
|
||||
|
||||
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", callback=show_connection_menu, enabled=True, tag="menu_file_connect")
|
||||
dpg.add_menu_item(label="Disonnect", callback=disconnect_serial, enabled=False, tag="menu_file_disconnect")
|
||||
dpg.add_menu_item(label="Quit", callback=quit_app)
|
||||
with dpg.menu(label='Window'):
|
||||
dpg.add_menu_item(label="Live Data", callback=show_page, user_data="page_live_data")
|
||||
dpg.add_menu_item(label="Lap Recap", callback=show_page, 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="connection_menu", show=False, modal=True, no_collapse=True, width=300):
|
||||
dpg.add_combo([], tag="serial_combo")
|
||||
dpg.add_button(label="Connect", callback=connect_to_serial)
|
||||
|
||||
worker = threading.Thread(target=telemetry_worker, daemon=True)
|
||||
worker.start()
|
||||
|
||||
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()
|
||||
|
||||
running = False
|
||||
dpg.destroy_context()
|
||||
@@ -1,10 +1,26 @@
|
||||
[project]
|
||||
name = "dataflux"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
description = "Telemetry dashboard for Exergie vehicle data"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.14"
|
||||
dependencies = [
|
||||
"dearpygui>=2.2",
|
||||
"pyserial>=3.5",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
dataflux = "dataflux.app:run"
|
||||
|
||||
[tool.uv]
|
||||
package = true
|
||||
|
||||
[build-system]
|
||||
requires = ["setuptools>=68"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools]
|
||||
package-dir = {"" = "src"}
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["src"]
|
||||
|
||||
0
src/dataflux/__init__.py
Normal file
0
src/dataflux/__init__.py
Normal file
40
src/dataflux/app.py
Normal file
40
src/dataflux/app.py
Normal 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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
0
src/dataflux/callbacks/__init__.py
Normal file
0
src/dataflux/callbacks/__init__.py
Normal file
11
src/dataflux/callbacks/menu.py
Normal file
11
src/dataflux/callbacks/menu.py
Normal 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
0
src/dataflux/config.py
Normal file
0
src/dataflux/services/__init__.py
Normal file
0
src/dataflux/services/__init__.py
Normal file
18
src/dataflux/services/serial/__init__.py
Normal file
18
src/dataflux/services/serial/__init__.py
Normal 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
18
src/dataflux/state.py
Normal 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
8
src/dataflux/tags.py
Normal 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"
|
||||
0
src/dataflux/ui/__init__.py
Normal file
0
src/dataflux/ui/__init__.py
Normal file
0
src/dataflux/ui/pages/__init__.py
Normal file
0
src/dataflux/ui/pages/__init__.py
Normal file
0
src/dataflux/ui/routines/__init__.py
Normal file
0
src/dataflux/ui/routines/__init__.py
Normal file
16
src/dataflux/ui/routines/menu.py
Normal file
16
src/dataflux/ui/routines/menu.py
Normal 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)
|
||||
11
src/dataflux/ui/routines/windows.py
Normal file
11
src/dataflux/ui/routines/windows.py
Normal 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)
|
||||
45
src/dataflux/ui/windows.py
Normal file
45
src/dataflux/ui/windows.py
Normal 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")
|
||||
Reference in New Issue
Block a user