Check temperature & voltage
This commit is contained in:
parent
7bcafa2c4d
commit
a91f9d70db
@ -1,7 +1,9 @@
|
||||
from abc import abstractmethod
|
||||
import time
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum
|
||||
|
||||
from .load import Load
|
||||
from .temperatures import N_SENSORS
|
||||
|
||||
from PySide6.QtCore import QObject, Signal, Slot, Qt
|
||||
@ -15,16 +17,79 @@ SLAVE_UNIT_ID = 0x02
|
||||
NUM_CELLS = 3
|
||||
VOLTAGE_QUANT = 1 / 10000.0
|
||||
|
||||
THRESH_UV = 2.5
|
||||
THRESH_OV = 4.2
|
||||
THRESH_UT = 1
|
||||
THRESH_OT = 60
|
||||
|
||||
|
||||
class BMSError(Enum):
|
||||
NONE = 0
|
||||
UV = 1
|
||||
OV = 2
|
||||
UT = 3
|
||||
OT = 4
|
||||
|
||||
def __str__(self):
|
||||
if self == self.NONE:
|
||||
return ""
|
||||
elif self == self.UV:
|
||||
return "Undervoltage"
|
||||
elif self == self.OV:
|
||||
return "Overvoltage"
|
||||
elif self == self.UT:
|
||||
return "Undertemperature"
|
||||
elif self == self.OT:
|
||||
return "Overtemperature"
|
||||
else:
|
||||
return "Unknown error"
|
||||
|
||||
|
||||
@dataclass
|
||||
class BMSData:
|
||||
voltages: list[float]
|
||||
temperatures: list[float]
|
||||
error: BMSError
|
||||
|
||||
|
||||
class BMS(QObject):
|
||||
dataUpdated = Signal(BMSData)
|
||||
|
||||
_data: BMSData
|
||||
_load: Load
|
||||
_num_cells: int
|
||||
_num_sensors: int
|
||||
|
||||
def __init__(self, load: Load, num_cells: int, num_sensors: int):
|
||||
super().__init__(None)
|
||||
self._load = load
|
||||
self._num_cells = num_cells
|
||||
self._num_sensors = num_sensors
|
||||
self._data = BMSData([0.0] * num_cells, [0.0] * num_sensors, BMSError.NONE)
|
||||
|
||||
def _check_for_errors(self):
|
||||
error = BMSError.NONE
|
||||
for v in self._data.voltages:
|
||||
if v > THRESH_OV:
|
||||
error = BMSError.OV
|
||||
break
|
||||
elif v < THRESH_UV:
|
||||
error = BMSError.UV
|
||||
break
|
||||
for t in self._data.temperatures:
|
||||
if t > THRESH_OT:
|
||||
error = BMSError.OT
|
||||
break
|
||||
if t < THRESH_UT:
|
||||
error = BMSError.UT
|
||||
break
|
||||
|
||||
if error != self._data.error:
|
||||
print(f"Error changed: {error}")
|
||||
self._data.error = error
|
||||
self._load.set_error(error != BMSError.NONE)
|
||||
self.dataUpdated.emit(self._data)
|
||||
|
||||
@abstractmethod
|
||||
def do_work(self):
|
||||
pass
|
||||
@ -32,14 +97,12 @@ class BMS(QObject):
|
||||
|
||||
class BMSEvalBoard(BMS):
|
||||
_dev: ModbusSerialClient
|
||||
_data: BMSData
|
||||
|
||||
def __init__(self, uart_path: str, temperaturesUpdated: Signal):
|
||||
super().__init__(None)
|
||||
def __init__(self, uart_path: str, temperaturesUpdated: Signal, load: Load):
|
||||
super().__init__(load, NUM_CELLS, N_SENSORS)
|
||||
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
|
||||
)
|
||||
@ -53,10 +116,12 @@ class BMSEvalBoard(BMS):
|
||||
self._data.voltages = list(
|
||||
map(lambda v: v * VOLTAGE_QUANT, result.registers)
|
||||
)
|
||||
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._check_for_errors()
|
||||
self.dataUpdated.emit(self._data)
|
||||
|
@ -88,3 +88,4 @@ class GUI(QObject):
|
||||
self._win.setProperty("voltage_max", max(data.voltages))
|
||||
self._win.setProperty("temp_min", min(data.temperatures))
|
||||
self._win.setProperty("temp_max", max(data.temperatures))
|
||||
self._win.setProperty("bmsError", str(data.error))
|
||||
|
@ -9,6 +9,7 @@ from .profile_handler import ProfileHandler
|
||||
class Load(QObject):
|
||||
dev: serial.Serial
|
||||
|
||||
_error: bool
|
||||
_current: float
|
||||
|
||||
_timer: QTimer
|
||||
@ -17,6 +18,7 @@ class Load(QObject):
|
||||
def __init__(self, uart_path: str, profile_handler: ProfileHandler):
|
||||
super().__init__(None)
|
||||
self.dev = serial.Serial(uart_path, 115200)
|
||||
self._error = False
|
||||
self._current = 0
|
||||
|
||||
self._profile_handler = profile_handler
|
||||
@ -25,12 +27,16 @@ class Load(QObject):
|
||||
self._timer.timeout.connect(self._update_load)
|
||||
self._timer.start(100)
|
||||
|
||||
def set_error(self, error):
|
||||
self._error = error
|
||||
|
||||
@Slot()
|
||||
def _update_current(self, current):
|
||||
self._current = current
|
||||
|
||||
def _update_load(self):
|
||||
curr_quants = round(self._current / 0.1)
|
||||
current = 0 if self._error else self._current
|
||||
curr_quants = round(current / 0.1)
|
||||
assert curr_quants <= 0xFFFF
|
||||
|
||||
msb = curr_quants >> 8
|
||||
|
2
main.py
2
main.py
@ -23,7 +23,7 @@ def main(argv: list[str]) -> int:
|
||||
temps.moveToThread(temp_thread)
|
||||
temp_thread.started.connect(temps.run)
|
||||
temp_thread.start()
|
||||
bms = BMSEvalBoard(argv[3], temps.temperaturesUpdated)
|
||||
bms = BMSEvalBoard(argv[3], temps.temperaturesUpdated, load)
|
||||
bms_thread = QThread()
|
||||
bms.moveToThread(bms_thread)
|
||||
bms_thread.started.connect(bms.do_work)
|
||||
|
@ -18,12 +18,13 @@ ApplicationWindow {
|
||||
property real voltage_max: 0
|
||||
property real temp_min: 0
|
||||
property real temp_max: 0
|
||||
property string bmsError: ""
|
||||
property bool bmsErrorVisible: false
|
||||
|
||||
Connections {
|
||||
target: profile_handler
|
||||
|
||||
function onCurrentChanged(new_current) {
|
||||
console.log("currentChanged");
|
||||
current = new_current;
|
||||
}
|
||||
|
||||
@ -45,6 +46,11 @@ ApplicationWindow {
|
||||
currentTimeSeries.append(profileTime, 100)
|
||||
}
|
||||
|
||||
onBmsErrorChanged: {
|
||||
console.log(bmsError);
|
||||
bmsErrorVisible = bmsError != "";
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: layout
|
||||
anchors.fill: parent
|
||||
@ -151,6 +157,22 @@ ApplicationWindow {
|
||||
Layout.row: 3
|
||||
Layout.column: 1
|
||||
}
|
||||
Text {
|
||||
text: "BMS Error:"
|
||||
Layout.row: 4
|
||||
Layout.column: 0
|
||||
visible: bmsErrorVisible
|
||||
color: "red"
|
||||
font.bold: true
|
||||
}
|
||||
Text {
|
||||
text: bmsError
|
||||
Layout.row: 4
|
||||
Layout.column: 1
|
||||
visible: bmsErrorVisible
|
||||
color: "red"
|
||||
font.bold: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user