63 lines
1.5 KiB
Python
63 lines
1.5 KiB
Python
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)
|