from typing import Dict from typing_extensions import TypedDict from PySide6.QtCore import QObject, Qt, Slot from PySide6.QtGui import QFontDatabase from PySide6.QtWidgets import QButtonGroup, QDockWidget, QGridLayout, QGroupBox, QHBoxLayout, QLabel, QRadioButton, QVBoxLayout, QWidget ContactorStates = TypedDict("ContactorStates", {}) class BMSState(QObject): """Represents the BMS state, including history.""" main_voltage: float aux_voltage: float current: float def __init__(self, parent=None, upstream=None): super().__init__(parent) # uhh, take a connection to the upstream? class BMSModuleViewer(QWidget): """BMS module status viewer (temp and voltage)""" # use graphics view for rendering. temps: list[float] = [] volts: list[float] = [] def __init__(self, parent = None) -> None: super().__init__(parent) layout = QGridLayout() bg = QButtonGroup(self) self.volts_btn = QRadioButton("Voltage", self) self.temps_btn = QRadioButton("Temperatures", self) bg.addButton(self.volts_btn) bg.addButton(self.temps_btn) layout.addWidget(self.volts_btn, 0, 0) layout.addWidget(self.temps_btn, 0, 1) class BMSOverview(QWidget): current: QLabel main_voltage: QLabel aux_voltage: QLabel def __init__(self, parent=None) -> None: super().__init__(parent) self.setMaximumWidth layout = QGridLayout() layout.setRowStretch(0, 80) layout.setRowStretch(1, 20) number_font = QFontDatabase.systemFont(QFontDatabase.SystemFont.FixedFont) number_font.setPointSize(18) hcenter = Qt.AlignmentFlag.AlignHCenter self.main_voltage = QLabel("0.000", self) self.main_voltage.setAlignment(hcenter) self.main_voltage.setFont(number_font) layout.addWidget(self.main_voltage, 0, 0) main_v_label = QLabel("Main Voltage", self) main_v_label.setAlignment(hcenter) layout.addWidget(main_v_label, 1, 0) self.aux_voltage = QLabel("0.000", self) self.aux_voltage.setAlignment(hcenter) self.aux_voltage.setFont(number_font) layout.addWidget(self.aux_voltage, 0, 1) aux_v_label = QLabel("Aux Voltage", self) aux_v_label.setAlignment(hcenter) layout.addWidget(aux_v_label, 1, 1) self.current = QLabel("0.000", self) self.current.setAlignment(hcenter) self.current.setFont(number_font) layout.addWidget(self.current, 0, 2) current_label = QLabel("Battery Current", self) current_label.setAlignment(hcenter) layout.addWidget(current_label, 1, 2) # now add widgets that display the numeric values. # then make slots that take floats and display them. self.setLayout(layout) @Slot(float) def update_main_v(self, value: float): self.main_voltage.setText(f"{value:.2f}") @Slot(float) def set_aux_v(self, value:float): self.aux_voltage.setText(f"{value:.3f}") @Slot(float) def set_current(self, value: float): self.current.setText(f"{value:.3f}") class BMSStatus(QWidget): contactor_items: Dict[str, QLabel] = dict() "A mapping of string names to the label, used to set open/closed" def __init__(self, parent: QWidget | None = None, contactors: list[str] = []): super().__init__(parent) layout = QVBoxLayout(self) self.contactors_grp = QGroupBox("Contactor State", self) contactor_layout = QGridLayout() self.contactors_grp.setLayout(contactor_layout) layout.addWidget(self.contactors_grp) for c in contactors: label = QLabel(c, self) self.contactor_items[c] = label contactor_layout.addWidget(label) class BMSPlotsWidget(QWidget): pass