import os.path import time from PySide6.QtCore import QTimer, QObject, Signal from PySide6.QtWidgets import QFileDialog from PySide6.QtQml import QQmlApplicationEngine from .bms import BMSData from .profile_handler import ProfileHandler, ProfileState class GUI(QObject): _profile_handler: ProfileHandler _engine: QQmlApplicationEngine _win: QObject _update_timer: QTimer _profile_chooser_btn: QObject _start_pause_btn: QObject _stop_btn: QObject def __init__(self, profile_handler: ProfileHandler, bmsUpdated: Signal): super().__init__(None) self._engine = QQmlApplicationEngine() qml_path = os.path.join( os.path.dirname(__file__), "..", "ui", "main_window.qml" ) self._engine.load(qml_path) self._win = self._engine.rootObjects()[0] self._win.setProperty("profile_handler", profile_handler) self._profile_chooser_btn = self._win.findChild(QObject, "profile_chooser") self._profile_chooser_btn.clicked.connect(self._choose_profile) self._start_pause_btn = self._win.findChild(QObject, "start_pause") self._start_pause_btn.clicked.connect(self._start_pause) self._stop_btn = self._win.findChild(QObject, "stop") self._stop_btn.clicked.connect(self._stop) self._profile_handler = profile_handler self._profile_handler.finished.connect(self._stop) self._update_timer = QTimer() self._update_timer.timeout.connect(self._update) self._update_timer.start(100) bmsUpdated.connect(self._updateBMS) def _choose_profile(self): dlg = QFileDialog() dlg.setFileMode(QFileDialog.FileMode.ExistingFile) dlg.setNameFilter("Profiles (*.csv)") if not dlg.exec(): return profile_path = dlg.selectedFiles()[0] print(f"Profile: {profile_path}") self._profile_handler.load_profile(profile_path) self._win.setProperty("profile", profile_path) self._win.findChild(QObject, "start_pause").setProperty("enabled", True) def _start_pause(self): if self._profile_handler.state == ProfileState.STOPPED: self._profile_handler.start() self._start_pause_btn.setProperty("text", "PAUSE") self._stop_btn.setProperty("enabled", True) self._profile_chooser_btn.setProperty("enabled", False) # TODO: Start logging elif self._profile_handler.state == ProfileState.RUNNING: self._profile_handler.pause() self._start_pause_btn.setProperty("text", "RESUME") else: self._profile_handler.resume() self._start_pause_btn.setProperty("text", "PAUSE") def _stop(self): self._start_pause_btn.setProperty("text", "START") self._stop_btn.setProperty("enabled", False) self._profile_chooser_btn.setProperty("enabled", True) def _update(self): if self._profile_handler.state == ProfileState.RUNNING: dt = time.time() - self._profile_handler.profile_start self._win.setProperty("profileTime", dt) def _updateBMS(self, data: BMSData): self._win.setProperty("voltage_min", min(data.voltages)) self._win.setProperty("voltage_max", max(data.voltages)) self._win.setProperty("temp_min", min(data.temperatures)) self._win.setProperty("temp_max", max(data.temperatures))