diff --git a/test.py b/test.py new file mode 100644 index 0000000..09f4a53 --- /dev/null +++ b/test.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python3 + +import os +import struct +import time + +# import serial +import sys + +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import ( + QApplication, + QWidget, + QPushButton, + QVBoxLayout, + QHBoxLayout, + QGridLayout, + QSlider, + QLabel, + QRadioButton, + QGroupBox, +) + + +BITRATE = 115200 # baud/s +TIMEOUT = 1 # seconds +N_SLAVES = 6 +LOG_FRAME_LENGTH = 8 # bytes + +CELLS_PER_SLAVE = 10 +TEMP_SENSORS_PER_SLAVE = 32 +VOLTAGE_CONV = 5.0 / 255 # volts/quantum +TEMP_CONV = 0.0625 * 16 # °C/quantum + + +class SlaveData: + cell_voltages: list[float] + cell_temps: list[float] + + def __init__(self) -> None: + self.cell_voltages = [-1] * CELLS_PER_SLAVE + self.cell_temps = [-1] * TEMP_SENSORS_PER_SLAVE + + +class AccumulatorData: + slaves: list[SlaveData] + min_voltage: float + max_voltage: float + min_temp: float + max_temp: float + last_frame: float + current: float + panic: bool + panic_errorcode: int + panic_errorarg: int + + def __init__(self) -> None: + self.slaves = [SlaveData() for _ in range(N_SLAVES)] + self.min_voltage = ( + self.max_voltage + ) = self.min_temp = self.max_temp = self.last_frame = self.current = 0 + self.panic = False + self.panic_errorcode = self.panic_errorarg = 0 + + +def update_display(): + voltages = [ + slave.cell_voltages[i] for i in range(CELLS_PER_SLAVE) for slave in data.slaves + ] + temps = [ + slave.cell_temps[i] + for i in range(TEMP_SENSORS_PER_SLAVE) + for slave in data.slaves + ] + data.min_voltage = min(voltages) + data.max_voltage = max(voltages) + data.min_temp = min(temps) + data.max_temp = max(temps) + time_since_last_frame = time.time() - data.last_frame + + print("\033[2J\033[H", end="") + print("-" * 20) + if data.panic: + print("!!!!! PANIC !!!!!") + print(f"Error code: {data.panic_errorcode}") + print(f"Error arg: {data.panic_errorarg}") + time.sleep(0.5) + return + + print(f"Time since last frame: {time_since_last_frame} s") + print(f"Current: {data.current:.2f} A") + print(f"Min voltage: {data.min_voltage:.2f} V") + print(f"Max voltage: {data.max_voltage:.2f} V") + print(f"Min temp: {data.min_temp:.1f} °C") + print(f"Max temp: {data.max_temp:.1f} °C") + for i in range(N_SLAVES): + min_v = min(data.slaves[i].cell_voltages) + max_v = max(data.slaves[i].cell_voltages) + min_t = min(data.slaves[i].cell_temps) + max_t = max(data.slaves[i].cell_temps) + print( + f"Stack {i}: V ∈ [{min_v:.2f}, {max_v:.2f}]\tT ∈ [{min_t:.1f}, {max_t:.1f}]" + ) + + +def gui(): + pass + + +class Window(QWidget): + def __init__(self, parent=None): + super(Window, self).__init__(parent) + + win = QVBoxLayout() + + ### ACCUMULATOR GENERAL ### + self.l1 = QLabel("Min Voltage [V]") + self.l1.setAlignment(Qt.AlignLeft) + self.l_min_voltage = QLabel() + self.l_min_voltage.setNum(data.min_voltage) + self.l_min_voltage.setAlignment(Qt.AlignLeft) + + self.l2 = QLabel("Max Voltage [V]") + self.l2.setAlignment(Qt.AlignLeft) + self.l_max_voltage = QLabel() + self.l_max_voltage.setNum(data.max_voltage) + self.l_max_voltage.setAlignment(Qt.AlignLeft) + + self.l3 = QLabel("Min Temperature [°C]") + self.l3.setAlignment(Qt.AlignLeft) + self.l_min_temp = QLabel() + self.l_min_temp.setNum(data.min_temp) + self.l_min_temp.setAlignment(Qt.AlignLeft) + + self.l4 = QLabel("Max Temperature [°C]") + self.l4.setAlignment(Qt.AlignLeft) + self.l_max_temp = QLabel() + self.l_max_temp.setNum(data.max_temp) + self.l_max_temp.setAlignment(Qt.AlignLeft) + + self.l5 = QLabel("Current [A]") + self.l5.setAlignment(Qt.AlignLeft) + self.l_current = QLabel() + self.l_current.setNum(data.current) + self.l_current.setAlignment(Qt.AlignLeft) + + grid_accumulator = QGridLayout() + grid_accumulator.addWidget(self.l1, 0, 0) + grid_accumulator.addWidget(self.l2, 1, 0) + grid_accumulator.addWidget(self.l3, 0, 2) + grid_accumulator.addWidget(self.l4, 1, 2) + grid_accumulator.addWidget(self.l5, 2, 0) + + grid_accumulator.addWidget(self.l_min_voltage, 0, 1) + grid_accumulator.addWidget(self.l_max_voltage, 1, 1) + grid_accumulator.addWidget(self.l_min_temp, 0, 3) + grid_accumulator.addWidget(self.l_max_temp, 1, 3) + grid_accumulator.addWidget(self.l_current, 2, 1) + + groupBox_accumulator = QGroupBox("Accumulator General") + groupBox_accumulator.setLayout(grid_accumulator) + + win.addWidget(groupBox_accumulator) + + ### STACKS ### + + ### STACK 0 ### + + self.l1_s0 = QLabel("Min Voltage [V]") + self.l1_s0.setAlignment(Qt.AlignLeft) + self.l_min_voltage_s0 = QLabel() + self.l_min_voltage_s0.setNum(min(data.slaves[0].cell_voltages)) + self.l_min_voltage_s0.setAlignment(Qt.AlignLeft) + + self.l2_s0 = QLabel("Max Voltage [V]") + self.l2_s0.setAlignment(Qt.AlignLeft) + self.l_max_voltage_s0 = QLabel() + self.l_max_voltage_s0.setNum(max(data.slaves[0].cell_voltages)) + self.l_max_voltage_s0.setAlignment(Qt.AlignLeft) + + self.l3_s0 = QLabel("Min Temperature [°C]") + self.l3_s0.setAlignment(Qt.AlignLeft) + self.l_min_temp_s0 = QLabel() + self.l_min_temp_s0.setNum(min(data.slaves[0].cell_temps)) + self.l_min_temp_s0.setAlignment(Qt.AlignLeft) + + self.l4_s0 = QLabel("Max Temperature [°C]") + self.l4_s0.setAlignment(Qt.AlignLeft) + self.l_max_temp_s0 = QLabel() + self.l_max_temp_s0.setNum(max(data.slaves[0].cell_temps)) + self.l_max_temp_s0.setAlignment(Qt.AlignLeft) + + grid_stack_s0 = QGridLayout() + grid_stack_s0.addWidget(self.l1_s0, 0, 0) + grid_stack_s0.addWidget(self.l2_s0, 1, 0) + grid_stack_s0.addWidget(self.l3_s0, 0, 2) + grid_stack_s0.addWidget(self.l4_s0, 1, 2) + + grid_stack_s0.addWidget(self.l_min_voltage_s0, 0, 1) + grid_stack_s0.addWidget(self.l_max_voltage_s0, 1, 1) + grid_stack_s0.addWidget(self.l_min_temp_s0, 0, 3) + grid_stack_s0.addWidget(self.l_max_temp_s0, 1, 3) + + groupBox_stack_s0 = QGroupBox("Stack 0") + groupBox_stack_s0.setLayout(grid_stack_s0) + + grid_stacks = QGridLayout() + grid_stacks.addWidget(groupBox_stack_s0, 0, 0) + + groupBox_stacks = QGroupBox("Individual Stacks") + groupBox_stacks.setLayout(grid_stacks) + + win.addWidget(groupBox_stacks) + + self.setLayout(win) + self.setWindowTitle("FT22 Charger Display") + + +data = AccumulatorData() +update_display() +app = QApplication(sys.argv) +clock = Window() +clock.show() +sys.exit(app.exec_())