from abc import abstractmethod import time from dataclasses import dataclass from .temperatures import N_SENSORS from PySide6.QtCore import QObject, Signal, Slot, Qt from pymodbus.client import ModbusSerialClient MODBUS_BAUDRATE = 115200 VOLTAGE_ADDRESS = 0x00 SLAVE_UNIT_ID = 0x02 NUM_CELLS = 3 VOLTAGE_QUANT = 1 / 10000.0 @dataclass class BMSData: voltages: list[float] temperatures: list[float] class BMS(QObject): dataUpdated = Signal(BMSData) @abstractmethod def do_work(self): pass class BMSEvalBoard(BMS): _dev: ModbusSerialClient _data: BMSData def __init__(self, uart_path: str, temperaturesUpdated: Signal): super().__init__(None) self._dev = ModbusSerialClient( method="rtu", port=uart_path, baudrate=MODBUS_BAUDRATE ) self._data = BMSData([0.0] * NUM_CELLS, [0.0] * N_SENSORS) temperaturesUpdated.connect( self._updateTemperatures, Qt.ConnectionType.DirectConnection ) def do_work(self): while True: time.sleep(0.1) result = self._dev.read_holding_registers( VOLTAGE_ADDRESS, NUM_CELLS, SLAVE_UNIT_ID ) self._data.voltages = list( map(lambda v: v * VOLTAGE_QUANT, result.registers) ) self.dataUpdated.emit(self._data) @Slot(list) def _updateTemperatures(self, temps: list[float]): assert len(temps) == N_SENSORS self._data.temperatures = temps self.dataUpdated.emit(self._data)