From f558f44907f65c2f0f418d3553ea929c86510eb9 Mon Sep 17 00:00:00 2001 From: "Jasper v. Blanckenburg" <j.blanckenburg@fasttube.de> Date: Thu, 26 Jan 2023 16:52:58 +0100 Subject: [PATCH] Check timeouts --- load_controller/bms.py | 30 ++++++++++++++++++++++++++---- load_controller/temperatures.py | 7 ++++++- ui/main_window.qml | 1 - 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/load_controller/bms.py b/load_controller/bms.py index 211105c..a5c5a60 100644 --- a/load_controller/bms.py +++ b/load_controller/bms.py @@ -21,6 +21,8 @@ THRESH_UV = 2.5 THRESH_OV = 4.2 THRESH_UT = 1 THRESH_OT = 60 +THRESH_VOLTAGE_TIMEOUT = 1 +THRESH_TEMP_TIMEOUT = 1 class BMSError(Enum): @@ -29,6 +31,8 @@ class BMSError(Enum): OV = 2 UT = 3 OT = 4 + TIMEOUT_V = 5 + TIMEOUT_T = 6 def __str__(self): if self == self.NONE: @@ -41,6 +45,10 @@ class BMSError(Enum): return "Undertemperature" elif self == self.OT: return "Overtemperature" + elif self == self.TIMEOUT_V: + return "Timeout (voltages)" + elif self == self.TIMEOUT_T: + return "Timeout (temps)" else: return "Unknown error" @@ -59,6 +67,8 @@ class BMS(QObject): _load: Load _num_cells: int _num_sensors: int + _last_voltage_time: float + _last_temp_time: float def __init__(self, load: Load, num_cells: int, num_sensors: int): super().__init__(None) @@ -83,6 +93,11 @@ class BMS(QObject): if t < THRESH_UT: error = BMSError.UT break + now = time.time() + if now - self._last_voltage_time > THRESH_VOLTAGE_TIMEOUT: + error = BMSError.TIMEOUT_V + if now - self._last_temp_time > THRESH_TEMP_TIMEOUT: + error = BMSError.TIMEOUT_T if error != self._data.error: print(f"Error changed: {error}") @@ -103,6 +118,8 @@ class BMSEvalBoard(BMS): self._dev = ModbusSerialClient( method="rtu", port=uart_path, baudrate=MODBUS_BAUDRATE ) + self._last_voltage_time = time.time() + self._last_temp_time = time.time() temperaturesUpdated.connect( self._updateTemperatures, Qt.ConnectionType.DirectConnection ) @@ -113,15 +130,20 @@ class BMSEvalBoard(BMS): 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) - ) + if result.isError(): + print(f"ERROR READING VOLTAGES: {result}") + else: + self._data.voltages = list( + map(lambda v: v * VOLTAGE_QUANT, result.registers) + ) + self._last_voltage_time = time.time() + self.dataUpdated.emit(self._data) self._check_for_errors() - self.dataUpdated.emit(self._data) @Slot(list) def _updateTemperatures(self, temps: list[float]): assert len(temps) == N_SENSORS self._data.temperatures = temps + self._last_temp_time = time.time() self._check_for_errors() self.dataUpdated.emit(self._data) diff --git a/load_controller/temperatures.py b/load_controller/temperatures.py index a693344..ea4dab2 100644 --- a/load_controller/temperatures.py +++ b/load_controller/temperatures.py @@ -26,12 +26,17 @@ class Temperatures(QObject): self.dev.read_until(START_OF_TEMPS) data = self.dev.read(N_SENSORS * 2) temps = struct.unpack(f">{N_SENSORS}h", data) + err = False for i, t in enumerate(temps): if (t & 0x0F) != 0: print( f"WARN: temperature had a non-zero least-significant nibble: {t:04x}", file=sys.stderr, ) + err = True else: self._temps[i] = (t >> 4) * TEMP_QUANT - self.temperaturesUpdated.emit(self._temps) + # Only emit the signal if there's no error, so we cause a timeout if + # there were errors. + if not err: + self.temperaturesUpdated.emit(self._temps) diff --git a/ui/main_window.qml b/ui/main_window.qml index 16bdc29..a10e1d1 100644 --- a/ui/main_window.qml +++ b/ui/main_window.qml @@ -47,7 +47,6 @@ ApplicationWindow { } onBmsErrorChanged: { - console.log(bmsError); bmsErrorVisible = bmsError != ""; }