Errorcodes, SoC, 9 slaves
This commit is contained in:
		@ -8,6 +8,8 @@ import random
 | 
				
			|||||||
import serial
 | 
					import serial
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import numpy as np
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PyQt5.QtCore import Qt, QTimer, QThread, QObject, pyqtSignal
 | 
					from PyQt5.QtCore import Qt, QTimer, QThread, QObject, pyqtSignal
 | 
				
			||||||
from PyQt5.QtWidgets import (
 | 
					from PyQt5.QtWidgets import (
 | 
				
			||||||
    QApplication,
 | 
					    QApplication,
 | 
				
			||||||
@ -25,14 +27,32 @@ from PyQt5.QtWidgets import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
BITRATE = 115200  # baud/s
 | 
					BITRATE = 115200  # baud/s
 | 
				
			||||||
TIMEOUT = 1  # seconds
 | 
					TIMEOUT = 1  # seconds
 | 
				
			||||||
N_SLAVES = 7
 | 
					N_SLAVES = 9
 | 
				
			||||||
LOG_FRAME_LENGTH = 8  # bytes
 | 
					LOG_FRAME_LENGTH = 8  # bytes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PARALLEL_CELLS = 9
 | 
				
			||||||
CELLS_PER_SLAVE = 10
 | 
					CELLS_PER_SLAVE = 10
 | 
				
			||||||
TEMP_SENSORS_PER_SLAVE = 32
 | 
					TEMP_SENSORS_PER_SLAVE = 32
 | 
				
			||||||
VOLTAGE_CONV = 5.0 / 255  # volts/quantum
 | 
					VOLTAGE_CONV = 5.0 / 255  # volts/quantum
 | 
				
			||||||
TEMP_CONV = 0.0625 * 16  # °C/quantum
 | 
					TEMP_CONV = 0.0625 * 16  # °C/quantum
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ERRORCODE_TIMEOUT_SLAVE = 1
 | 
				
			||||||
 | 
					ERRORCODE_SLAVE_PANIC = 2
 | 
				
			||||||
 | 
					ERRORCODE_TIMEOUT_SLAVE_FRAMES = 3
 | 
				
			||||||
 | 
					ERRORCODE_TOO_FEW_TEMPS = 4
 | 
				
			||||||
 | 
					ERRORCODE_TIMEOUT_SHUNT = 6
 | 
				
			||||||
 | 
					ERRORCODE_MASTER_THRESH = 7
 | 
				
			||||||
 | 
					SLAVE_ERROR_UV = 0
 | 
				
			||||||
 | 
					SLAVE_ERROR_OV = 1
 | 
				
			||||||
 | 
					SLAVE_ERROR_UT = 2
 | 
				
			||||||
 | 
					SLAVE_ERROR_OT = 3
 | 
				
			||||||
 | 
					SLAVE_ERROR_BQ = 4
 | 
				
			||||||
 | 
					SLAVE_ERROR_TMP144 = 5
 | 
				
			||||||
 | 
					MASTER_THRESH_UT = 0
 | 
				
			||||||
 | 
					MASTER_THRESH_OT = 1
 | 
				
			||||||
 | 
					MASTER_THRESH_UV = 2
 | 
				
			||||||
 | 
					MASTER_THRESH_OV = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SlaveData:
 | 
					class SlaveData:
 | 
				
			||||||
    cell_voltages: list[float]
 | 
					    cell_voltages: list[float]
 | 
				
			||||||
@ -47,6 +67,8 @@ class AccumulatorData:
 | 
				
			|||||||
    slaves: list[SlaveData]
 | 
					    slaves: list[SlaveData]
 | 
				
			||||||
    min_voltage: float
 | 
					    min_voltage: float
 | 
				
			||||||
    max_voltage: float
 | 
					    max_voltage: float
 | 
				
			||||||
 | 
					    min_soc: float
 | 
				
			||||||
 | 
					    max_soc: float
 | 
				
			||||||
    min_temp: float
 | 
					    min_temp: float
 | 
				
			||||||
    max_temp: float
 | 
					    max_temp: float
 | 
				
			||||||
    last_frame: float
 | 
					    last_frame: float
 | 
				
			||||||
@ -60,6 +82,10 @@ class AccumulatorData:
 | 
				
			|||||||
        self.slaves = [SlaveData() for _ in range(N_SLAVES)]
 | 
					        self.slaves = [SlaveData() for _ in range(N_SLAVES)]
 | 
				
			||||||
        self.min_voltage = (
 | 
					        self.min_voltage = (
 | 
				
			||||||
            self.max_voltage
 | 
					            self.max_voltage
 | 
				
			||||||
 | 
					        ) = (
 | 
				
			||||||
 | 
					            self.min_soc
 | 
				
			||||||
 | 
					        ) = (
 | 
				
			||||||
 | 
					            self.max_soc
 | 
				
			||||||
        ) = self.min_temp = self.max_temp = self.last_frame = self.current = 0
 | 
					        ) = self.min_temp = self.max_temp = self.last_frame = self.current = 0
 | 
				
			||||||
        self.panic = False
 | 
					        self.panic = False
 | 
				
			||||||
        self.panic_errorcode = self.panic_errorarg = 0
 | 
					        self.panic_errorcode = self.panic_errorarg = 0
 | 
				
			||||||
@ -257,25 +283,37 @@ class Window(QWidget):
 | 
				
			|||||||
        self.l_max_voltage.setNum(data.max_voltage)
 | 
					        self.l_max_voltage.setNum(data.max_voltage)
 | 
				
			||||||
        self.l_max_voltage.setAlignment(Qt.AlignLeft)
 | 
					        self.l_max_voltage.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.l3 = QLabel("Min Temperature [°C]")
 | 
					        self.l3 = QLabel("Min SoC [%]")
 | 
				
			||||||
        self.l3.setAlignment(Qt.AlignLeft)
 | 
					        self.l3.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					        self.l_min_soc = QLabel()
 | 
				
			||||||
 | 
					        self.l_min_soc.setNum(data.min_soc)
 | 
				
			||||||
 | 
					        self.l_min_soc.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.l4 = QLabel("Max SoC [%]")
 | 
				
			||||||
 | 
					        self.l4.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					        self.l_max_soc = QLabel()
 | 
				
			||||||
 | 
					        self.l_max_soc.setNum(data.max_soc)
 | 
				
			||||||
 | 
					        self.l_max_soc.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.l5 = QLabel("Min Temperature [°C]")
 | 
				
			||||||
 | 
					        self.l5.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
        self.l_min_temp = QLabel()
 | 
					        self.l_min_temp = QLabel()
 | 
				
			||||||
        self.l_min_temp.setNum(data.min_temp)
 | 
					        self.l_min_temp.setNum(data.min_temp)
 | 
				
			||||||
        self.l_min_temp.setAlignment(Qt.AlignLeft)
 | 
					        self.l_min_temp.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.l4 = QLabel("Max Temperature [°C]")
 | 
					        self.l6 = QLabel("Max Temperature [°C]")
 | 
				
			||||||
        self.l4.setAlignment(Qt.AlignLeft)
 | 
					        self.l6.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
        self.l_max_temp = QLabel()
 | 
					        self.l_max_temp = QLabel()
 | 
				
			||||||
        self.l_max_temp.setNum(data.max_temp)
 | 
					        self.l_max_temp.setNum(data.max_temp)
 | 
				
			||||||
        self.l_max_temp.setAlignment(Qt.AlignLeft)
 | 
					        self.l_max_temp.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.l5 = QLabel("Current [A]")
 | 
					        self.l7 = QLabel("Current [A]")
 | 
				
			||||||
        self.l5.setAlignment(Qt.AlignLeft)
 | 
					        self.l7.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
        self.l_current = QLabel()
 | 
					        self.l_current = QLabel()
 | 
				
			||||||
        self.l_current.setNum(data.current)
 | 
					        self.l_current.setNum(data.current)
 | 
				
			||||||
        self.l_current.setAlignment(Qt.AlignLeft)
 | 
					        self.l_current.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.l6 = QLabel("Error")
 | 
					        self.l8 = QLabel("Error")
 | 
				
			||||||
        self.l_error = QLabel()
 | 
					        self.l_error = QLabel()
 | 
				
			||||||
        self.l_error.setText(str(data.panic))
 | 
					        self.l_error.setText(str(data.panic))
 | 
				
			||||||
        self.l_error.setAlignment(Qt.AlignLeft)
 | 
					        self.l_error.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
@ -286,7 +324,7 @@ class Window(QWidget):
 | 
				
			|||||||
        self.l_errorarg.setText(str(data.panic_errorarg))
 | 
					        self.l_errorarg.setText(str(data.panic_errorarg))
 | 
				
			||||||
        self.l_errorcode.setAlignment(Qt.AlignLeft)
 | 
					        self.l_errorcode.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.l7 = QLabel("Time Since Last Dataframe")
 | 
					        self.l9 = QLabel("Time Since Last Dataframe")
 | 
				
			||||||
        self.l_time_since_last_frame = QLabel()
 | 
					        self.l_time_since_last_frame = QLabel()
 | 
				
			||||||
        self.l_time_since_last_frame.setText(str(data.time_since_last_frame))
 | 
					        self.l_time_since_last_frame.setText(str(data.time_since_last_frame))
 | 
				
			||||||
        self.l_time_since_last_frame.setAlignment(Qt.AlignLeft)
 | 
					        self.l_time_since_last_frame.setAlignment(Qt.AlignLeft)
 | 
				
			||||||
@ -295,21 +333,25 @@ class Window(QWidget):
 | 
				
			|||||||
        grid_accumulator = QGridLayout()
 | 
					        grid_accumulator = QGridLayout()
 | 
				
			||||||
        grid_accumulator.addWidget(self.l1, 0, 0)
 | 
					        grid_accumulator.addWidget(self.l1, 0, 0)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l2, 1, 0)
 | 
					        grid_accumulator.addWidget(self.l2, 1, 0)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l3, 0, 2)
 | 
					        grid_accumulator.addWidget(self.l3, 2, 0)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l4, 1, 2)
 | 
					        grid_accumulator.addWidget(self.l4, 3, 0)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l5, 2, 0)
 | 
					        grid_accumulator.addWidget(self.l5, 0, 2)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l6, 3, 0)
 | 
					        grid_accumulator.addWidget(self.l6, 1, 2)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l7, 4, 0)
 | 
					        grid_accumulator.addWidget(self.l7, 2, 2)
 | 
				
			||||||
 | 
					        grid_accumulator.addWidget(self.l8, 5, 0)
 | 
				
			||||||
 | 
					        grid_accumulator.addWidget(self.l9, 3, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_min_voltage, 0, 1)
 | 
					        grid_accumulator.addWidget(self.l_min_voltage, 0, 1)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_max_voltage, 1, 1)
 | 
					        grid_accumulator.addWidget(self.l_max_voltage, 1, 1)
 | 
				
			||||||
 | 
					        grid_accumulator.addWidget(self.l_min_soc, 2, 1)
 | 
				
			||||||
 | 
					        grid_accumulator.addWidget(self.l_max_soc, 3, 1)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_min_temp, 0, 3)
 | 
					        grid_accumulator.addWidget(self.l_min_temp, 0, 3)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_max_temp, 1, 3)
 | 
					        grid_accumulator.addWidget(self.l_max_temp, 1, 3)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_current, 2, 1)
 | 
					        grid_accumulator.addWidget(self.l_current, 2, 3)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_error, 3, 1)
 | 
					        grid_accumulator.addWidget(self.l_error, 5, 1)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_errorcode, 3, 2)
 | 
					        grid_accumulator.addWidget(self.l_errorcode, 5, 2)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_errorarg, 3, 3)
 | 
					        grid_accumulator.addWidget(self.l_errorarg, 5, 3)
 | 
				
			||||||
        grid_accumulator.addWidget(self.l_time_since_last_frame, 4, 1)
 | 
					        grid_accumulator.addWidget(self.l_time_since_last_frame, 3, 3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        groupBox_accumulator = QGroupBox("Accumulator General")
 | 
					        groupBox_accumulator = QGroupBox("Accumulator General")
 | 
				
			||||||
        groupBox_accumulator.setLayout(grid_accumulator)
 | 
					        groupBox_accumulator.setLayout(grid_accumulator)
 | 
				
			||||||
@ -400,15 +442,17 @@ class Window(QWidget):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def update(self):
 | 
					    def update(self):
 | 
				
			||||||
        # Accumulator
 | 
					        # Accumulator
 | 
				
			||||||
        self.l_min_voltage.setNum(data.min_voltage)
 | 
					        self.l_min_voltage.setText(f"{data.min_voltage:.02f}")
 | 
				
			||||||
        self.l_max_voltage.setNum(data.max_voltage)
 | 
					        self.l_max_voltage.setText(f"{data.max_voltage:.02f}")
 | 
				
			||||||
        self.l_min_temp.setNum(data.min_temp)
 | 
					        self.l_min_soc.setText(f"{data.min_soc:.01f}")
 | 
				
			||||||
        self.l_max_temp.setNum(data.max_temp)
 | 
					        self.l_max_soc.setText(f"{data.max_soc:.01f}")
 | 
				
			||||||
        self.l_current.setNum(data.current)
 | 
					        self.l_min_temp.setText(f"{data.min_temp:.00f}")
 | 
				
			||||||
 | 
					        self.l_max_temp.setText(f"{data.max_temp:.00f}")
 | 
				
			||||||
 | 
					        self.l_current.setText(f"{data.current:.03f}")
 | 
				
			||||||
        self.l_error.setText(str(data.panic))
 | 
					        self.l_error.setText(str(data.panic))
 | 
				
			||||||
        self.l_errorcode.setText(str(data.panic_errorcode))
 | 
					        self.l_errorcode.setText(str(data.panic_errorcode))
 | 
				
			||||||
        self.l_errorarg.setText(str(data.panic_errorarg))
 | 
					        self.l_errorarg.setText(str(data.panic_errorarg))
 | 
				
			||||||
        self.l_time_since_last_frame.setText(str(data.time_since_last_frame))
 | 
					        self.l_time_since_last_frame.setText(str(time.time() - data.last_frame))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Stacks
 | 
					        # Stacks
 | 
				
			||||||
        for i, sge in enumerate(self.stack_gui_elements):
 | 
					        for i, sge in enumerate(self.stack_gui_elements):
 | 
				
			||||||
@ -434,6 +478,7 @@ class Worker(QObject):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def charger_communication(self):
 | 
					    def charger_communication(self):
 | 
				
			||||||
        rx_data = ser.read(256)
 | 
					        rx_data = ser.read(256)
 | 
				
			||||||
 | 
					        # print(len(rx_data), rx_data)
 | 
				
			||||||
        while len(rx_data) > 0:
 | 
					        while len(rx_data) > 0:
 | 
				
			||||||
            if (frame_start := self.check_log_start(rx_data)) != -1:
 | 
					            if (frame_start := self.check_log_start(rx_data)) != -1:
 | 
				
			||||||
                self.decode_log_frame(rx_data[frame_start + 3 : frame_start + 11])
 | 
					                self.decode_log_frame(rx_data[frame_start + 3 : frame_start + 11])
 | 
				
			||||||
@ -503,6 +548,8 @@ class Worker(QObject):
 | 
				
			|||||||
        ]
 | 
					        ]
 | 
				
			||||||
        data.min_voltage = min(voltages)
 | 
					        data.min_voltage = min(voltages)
 | 
				
			||||||
        data.max_voltage = max(voltages)
 | 
					        data.max_voltage = max(voltages)
 | 
				
			||||||
 | 
					        data.min_soc = self.calculate_soc(data.min_voltage)
 | 
				
			||||||
 | 
					        data.max_soc = self.calculate_soc(data.max_voltage)
 | 
				
			||||||
        data.min_temp = min(temps)
 | 
					        data.min_temp = min(temps)
 | 
				
			||||||
        data.max_temp = max(temps)
 | 
					        data.max_temp = max(temps)
 | 
				
			||||||
        data.time_since_last_frame = time.time() - data.last_frame
 | 
					        data.time_since_last_frame = time.time() - data.last_frame
 | 
				
			||||||
@ -516,11 +563,72 @@ class Worker(QObject):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def decode_panic_frame(self, buf: bytes):
 | 
					    def decode_panic_frame(self, buf: bytes):
 | 
				
			||||||
        data.panic = True
 | 
					        data.panic = True
 | 
				
			||||||
        data.panic_errorcode = buf[0]
 | 
					        errorcode = int(buf[0])
 | 
				
			||||||
        data.panic_errorarg = buf[1]
 | 
					        errorargs = [int(buf[1]), int(buf[2])]
 | 
				
			||||||
 | 
					        if errorcode == ERRORCODE_TIMEOUT_SLAVE:
 | 
				
			||||||
 | 
					            data.panic_errorcode = "Slave timeout"
 | 
				
			||||||
 | 
					            data.panic_errorarg = f"Slave ID {errorargs[0]}"
 | 
				
			||||||
 | 
					        elif errorcode == ERRORCODE_SLAVE_PANIC:
 | 
				
			||||||
 | 
					            data.panic_errorcode = "Slave panic"
 | 
				
			||||||
 | 
					            if errorargs[1] == SLAVE_ERROR_UV:
 | 
				
			||||||
 | 
					                slave_error = "Undervoltage"
 | 
				
			||||||
 | 
					            elif errorargs[1] == SLAVE_ERROR_OV:
 | 
				
			||||||
 | 
					                slave_error = "Overvoltage"
 | 
				
			||||||
 | 
					            elif errorargs[1] == SLAVE_ERROR_UT:
 | 
				
			||||||
 | 
					                slave_error = "Undertemperature"
 | 
				
			||||||
 | 
					            elif errorargs[1] == SLAVE_ERROR_OT:
 | 
				
			||||||
 | 
					                slave_error = "Overtemperature"
 | 
				
			||||||
 | 
					            elif errorargs[1] == SLAVE_ERROR_BQ:
 | 
				
			||||||
 | 
					                slave_error = "BQ Communication error"
 | 
				
			||||||
 | 
					            elif errorargs[1] == SLAVE_ERROR_TMP144:
 | 
				
			||||||
 | 
					                slave_error = "TMP144 communication error"
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                slave_error = f"Unknown error ({errorargs[1]})"
 | 
				
			||||||
 | 
					            data.panic_errorarg = f"Slave ID {errorargs[0]}: {slave_error}"
 | 
				
			||||||
 | 
					        elif errorcode == ERRORCODE_TIMEOUT_SLAVE_FRAMES:
 | 
				
			||||||
 | 
					            data.panic_errorcode = "Slave frame timeout"
 | 
				
			||||||
 | 
					            data.panic_errorarg = f"Slave ID {errorargs[0]}, frame {errorargs[1]}"
 | 
				
			||||||
 | 
					        elif errorcode == ERRORCODE_TOO_FEW_TEMPS:
 | 
				
			||||||
 | 
					            data.panic_errorcode = "Too few temperature sensors"
 | 
				
			||||||
 | 
					            data.panic_errorarg = f"Slave ID {errorargs[0]}"
 | 
				
			||||||
 | 
					        elif errorcode == ERRORCODE_TIMEOUT_SHUNT:
 | 
				
			||||||
 | 
					            data.panic_errorcode = "Shunt timeout"
 | 
				
			||||||
 | 
					        elif errorcode == ERRORCODE_MASTER_THRESH:
 | 
				
			||||||
 | 
					            data.panic_errorcode = "Master detected threshold"
 | 
				
			||||||
 | 
					            if errorargs[0] == MASTER_THRESH_UT:
 | 
				
			||||||
 | 
					                data.panic_errorarg = "Undertemperature"
 | 
				
			||||||
 | 
					            elif errorargs[0] == MASTER_THRESH_OT:
 | 
				
			||||||
 | 
					                data.panic_errorarg = "Overtemperature"
 | 
				
			||||||
 | 
					            elif errorargs[0] == MASTER_THRESH_UV:
 | 
				
			||||||
 | 
					                data.panic_errorarg = "Undervoltage"
 | 
				
			||||||
 | 
					            elif errorargs[0] == MASTER_THRESH_OV:
 | 
				
			||||||
 | 
					                data.panic_errorarg = "Overvoltage"
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                data.panic_errorarg = f"Unknown threshold ({errorargs[0]})"
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            data.panic_errorcode = buf[0]
 | 
				
			||||||
 | 
					            data.panic_errorarg = buf[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    INTERNAL_RESISTANCE_CURVE_X = [2.0, 4.12]
 | 
				
			||||||
 | 
					    INTERNAL_RESISTANCE_CURVE_Y = [0.0528, 0.0294]
 | 
				
			||||||
 | 
					    SOC_OCV_X = [2.1, 2.9, 3.2, 3.3, 3.4, 3.5, 3.68, 4.0, 4.15, 4.2]
 | 
				
			||||||
 | 
					    SOC_OCV_Y = [0, 0.023, 0.06, 0.08, 0.119, 0.227, 0.541, 0.856, 0.985, 1.0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def calculate_soc(self, voltage: float):
 | 
				
			||||||
 | 
					        r_i = np.interp(
 | 
				
			||||||
 | 
					            [voltage],
 | 
				
			||||||
 | 
					            self.INTERNAL_RESISTANCE_CURVE_X,
 | 
				
			||||||
 | 
					            self.INTERNAL_RESISTANCE_CURVE_Y,
 | 
				
			||||||
 | 
					        )[0]
 | 
				
			||||||
 | 
					        # i = data.current / PARALLEL_CELLS
 | 
				
			||||||
 | 
					        i = 3 / PARALLEL_CELLS
 | 
				
			||||||
 | 
					        ocv = voltage - i * r_i
 | 
				
			||||||
 | 
					        return np.interp([ocv], self.SOC_OCV_X, self.SOC_OCV_Y)[0] * 100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def parse_cell_temps(self, slave: int):
 | 
					    def parse_cell_temps(self, slave: int):
 | 
				
			||||||
        temps = list(filter(lambda t: t > 0, data.slaves[slave].cell_temps[:16]))
 | 
					        temps = list(
 | 
				
			||||||
 | 
					            filter(lambda t: t > 0 and t < 60, data.slaves[slave].cell_temps[:16])
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        if len(temps) == 0:
 | 
					        if len(temps) == 0:
 | 
				
			||||||
            temps = [-1]
 | 
					            temps = [-1]
 | 
				
			||||||
        min_t = min(temps)
 | 
					        min_t = min(temps)
 | 
				
			||||||
@ -542,10 +650,7 @@ if __name__ == "__main__":
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    SERIAL_PORT = sys.argv[1]
 | 
					    SERIAL_PORT = sys.argv[1]
 | 
				
			||||||
    print(SERIAL_PORT)
 | 
					    print(SERIAL_PORT)
 | 
				
			||||||
    try:
 | 
					    ser = serial.Serial(SERIAL_PORT, BITRATE, timeout=TIMEOUT)
 | 
				
			||||||
        ser = serial.Serial(SERIAL_PORT, BITRATE, timeout=TIMEOUT)
 | 
					 | 
				
			||||||
    except serial.serialutil.SerialException:
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    app = QApplication(sys.argv)
 | 
					    app = QApplication(sys.argv)
 | 
				
			||||||
    gui = Window()
 | 
					    gui = Window()
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user