diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dd60e19..1db8a136 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,17 +7,19 @@ * Added: Implement callback function for update by @seidler2547 * Added: JKBMS BLE - Show last five characters from the MAC address in the custom name (which is displayed in the device list) by @mr-manuel * Added: Save custom name and make it restart persistant by @mr-manuel +* Added: Validate current, voltage, capacity and SoC for all BMS. This prevents that a device, which is no BMS, is detected as BMS. Fixes also https://github.com/Louisvdw/dbus-serialbattery/issues/479 by @mr-manuel * Changed: Enable BMS that are disabled by default by specifying it in the config file. No more need to edit scripts by @mr-manuel +* Changed: Fix daly readsentence by @transistorgit * Changed: Fix Sinowealth not loading https://github.com/Louisvdw/dbus-serialbattery/issues/702 by @mr-manuel * Changed: Fixed error in `reinstall-local.sh` script for Bluetooth installation by @mr-manuel -* Changed: Fixed that other devices are recognized as ANT BMS by @mr-manuel -* Changed: Fixed that other devices are recognized as Sinowealth BMS by @mr-manuel * Changed: Fixed typo in `config.ini` sample by @hoschult * Changed: For BMS_TYPE now multiple BMS can be specified by @mr-manuel -* Changed: Improved driver reinstall when multiple Bluetooth BMS are enabled by @mr-manuel -* Changed: Improved Jkbms_Ble driver by @seidler2547 & @mr-manuel * Changed: Improved battery error handling on connection loss by @mr-manuel * Changed: Improved battery voltage handling in linear absorption mode by @ogurevich +* Changed: Improved driver reinstall when multiple Bluetooth BMS are enabled by @mr-manuel +* Changed: Improved Jkbms_Ble driver by @seidler2547 & @mr-manuel +* Changed: Reduce the big inrush current if the CVL jumps from Bulk/Absorbtion to Float https://github.com/Louisvdw/dbus-serialbattery/issues/659 by @Rikkert-RS +* Removed: Cronjob to restart Bluetooth service every 12 hours by @mr-manuel ## v1.0.20230531 diff --git a/etc/dbus-serialbattery/battery.py b/etc/dbus-serialbattery/battery.py index 0c7bef68..a8068cca 100644 --- a/etc/dbus-serialbattery/battery.py +++ b/etc/dbus-serialbattery/battery.py @@ -108,6 +108,8 @@ def init_values(self): self.min_battery_voltage = None self.allow_max_voltage = True self.max_voltage_start_time = None + self.transition_start_time = None + self.control_voltage_at_transition_start = None self.charge_mode = None self.charge_limitation = None self.discharge_limitation = None @@ -141,7 +143,7 @@ def unique_identifier(self) -> str: On +/- 5 Ah you can identify 11 batteries """ string = ( - "".join(filter(str.isalnum, self.hardware_version)) + "_" + "".join(filter(str.isalnum, str(self.hardware_version))) + "_" if self.hardware_version is not None and self.hardware_version != "" else "" ) @@ -250,48 +252,46 @@ def manage_charge_voltage_linear(self) -> None: tDiff = 0 try: - if utils.CVCM_ENABLE: - # calculate battery sum - for i in range(self.cell_count): - voltage = self.get_cell_voltage(i) - if voltage: - voltageSum += voltage - - # calculate penalty sum to prevent single cell overcharge by using current cell voltage - if voltage > utils.MAX_CELL_VOLTAGE: - # foundHighCellVoltage: reset to False is not needed, since it is recalculated every second - foundHighCellVoltage = True - penaltySum += voltage - utils.MAX_CELL_VOLTAGE - - voltageDiff = self.get_max_cell_voltage() - self.get_min_cell_voltage() - - if self.max_voltage_start_time is None: - # start timer, if max voltage is reached and cells are balanced - if ( - self.max_battery_voltage - utils.VOLTAGE_DROP <= voltageSum - and voltageDiff - <= utils.CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL - and self.allow_max_voltage - ): - self.max_voltage_start_time = int(time()) - - # allow max voltage again, if cells are unbalanced or SoC threshold is reached - elif ( - utils.SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT > self.soc - or voltageDiff >= utils.CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT - ) and not self.allow_max_voltage: - self.allow_max_voltage = True - else: - tDiff = int(time()) - self.max_voltage_start_time - # if utils.MAX_VOLTAGE_TIME_SEC < tDiff: - # keep max voltage for 300 more seconds - if 300 < tDiff: - self.allow_max_voltage = False - self.max_voltage_start_time = None - # we don't forget to reset max_voltage_start_time wenn we going to bulk(dynamic) mode - # regardless of whether we were in absorption mode or not - if voltageSum < self.max_battery_voltage - utils.VOLTAGE_DROP: - self.max_voltage_start_time = None + # calculate battery sum + for i in range(self.cell_count): + voltage = self.get_cell_voltage(i) + if voltage: + voltageSum += voltage + + # calculate penalty sum to prevent single cell overcharge by using current cell voltage + if voltage > utils.MAX_CELL_VOLTAGE: + # foundHighCellVoltage: reset to False is not needed, since it is recalculated every second + foundHighCellVoltage = True + penaltySum += voltage - utils.MAX_CELL_VOLTAGE + + voltageDiff = self.get_max_cell_voltage() - self.get_min_cell_voltage() + + if self.max_voltage_start_time is None: + # start timer, if max voltage is reached and cells are balanced + if ( + self.max_battery_voltage - utils.VOLTAGE_DROP <= voltageSum + and voltageDiff <= utils.CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL + and self.allow_max_voltage + ): + self.max_voltage_start_time = int(time()) + + # allow max voltage again, if cells are unbalanced or SoC threshold is reached + elif ( + utils.SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT > self.soc + or voltageDiff >= utils.CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT + ) and not self.allow_max_voltage: + self.allow_max_voltage = True + else: + tDiff = int(time()) - self.max_voltage_start_time + # if utils.MAX_VOLTAGE_TIME_SEC < tDiff: + # keep max voltage for 300 more seconds + if 300 < tDiff: + self.allow_max_voltage = False + self.max_voltage_start_time = None + # we don't forget to reset max_voltage_start_time wenn we going to bulk(dynamic) mode + # regardless of whether we were in absorption mode or not + if voltageSum < self.max_battery_voltage - utils.VOLTAGE_DROP: + self.max_voltage_start_time = None # INFO: battery will only switch to Absorption, if all cells are balanced. # Reach MAX_CELL_VOLTAGE * cell count if they are all balanced. @@ -343,10 +343,32 @@ def manage_charge_voltage_linear(self) -> None: ) else: - self.control_voltage = round( - (utils.FLOAT_CELL_VOLTAGE * self.cell_count), 3 - ) - self.charge_mode = "Float" + floatVoltage = round((utils.FLOAT_CELL_VOLTAGE * self.cell_count), 3) + chargeMode = "Float" + if self.control_voltage: + if not self.charge_mode.startswith("Float"): + self.transition_start_time = int(time()) + self.initial_control_voltage = self.control_voltage + chargeMode = "Float Transition" + elif self.charge_mode.startswith("Float Transition"): + elapsed_time = int(time()) - self.transition_start_time + # Voltage drop per second + VOLTAGE_DROP_PER_SECOND = 0.01 / 10 + voltage_drop = min( + VOLTAGE_DROP_PER_SECOND * elapsed_time, + self.initial_control_voltage - floatVoltage, + ) + self.control_voltage = ( + self.initial_control_voltage - voltage_drop + ) + if self.control_voltage <= floatVoltage: + self.control_voltage = floatVoltage + chargeMode = "Float" + else: + chargeMode = "Float Transition" + else: + self.control_voltage = floatVoltage + self.charge_mode = chargeMode if ( self.allow_max_voltage @@ -370,43 +392,42 @@ def manage_charge_voltage_step(self) -> None: tDiff = 0 try: - if utils.CVCM_ENABLE: - # calculate battery sum - for i in range(self.cell_count): - voltage = self.get_cell_voltage(i) - if voltage: - voltageSum += voltage - - if self.max_voltage_start_time is None: - # check if max voltage is reached and start timer to keep max voltage - if ( - self.max_battery_voltage - utils.VOLTAGE_DROP <= voltageSum - and self.allow_max_voltage - ): - # example 2 - self.max_voltage_start_time = time() - - # check if reset soc is greater than battery soc - # this prevents flapping between max and float voltage - elif ( - utils.SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT > self.soc - and not self.allow_max_voltage - ): - self.allow_max_voltage = True - - # do nothing - else: - pass + # calculate battery sum + for i in range(self.cell_count): + voltage = self.get_cell_voltage(i) + if voltage: + voltageSum += voltage + + if self.max_voltage_start_time is None: + # check if max voltage is reached and start timer to keep max voltage + if ( + self.max_battery_voltage - utils.VOLTAGE_DROP <= voltageSum + and self.allow_max_voltage + ): + # example 2 + self.max_voltage_start_time = time() + + # check if reset soc is greater than battery soc + # this prevents flapping between max and float voltage + elif ( + utils.SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT > self.soc + and not self.allow_max_voltage + ): + self.allow_max_voltage = True - # timer started + # do nothing else: - tDiff = time() - self.max_voltage_start_time - if utils.MAX_VOLTAGE_TIME_SEC < tDiff: - self.allow_max_voltage = False - self.max_voltage_start_time = None + pass - else: - pass + # timer started + else: + tDiff = time() - self.max_voltage_start_time + if utils.MAX_VOLTAGE_TIME_SEC < tDiff: + self.allow_max_voltage = False + self.max_voltage_start_time = None + + else: + pass if self.allow_max_voltage: self.control_voltage = self.max_battery_voltage @@ -981,6 +1002,34 @@ def get_mos_temp(self) -> Union[float, None]: else: return None + def validate_data(self) -> bool: + """ + Used to validate the data received from the BMS. + If the data is in the thresholds return True, + else return False since it's very probably not a BMS + """ + if self.capacity is not None and (self.capacity < 0 or self.capacity > 1000): + logger.debug( + "Capacity outside of thresholds (from 0 to 1000): " + str(self.capacity) + ) + return False + if self.current is not None and abs(self.current) > 1000: + logger.debug( + "Current outside of thresholds (from -1000 to 1000): " + + str(self.current) + ) + return False + if self.voltage is not None and (self.voltage < 0 or self.voltage > 100): + logger.debug( + "Voltage outside of thresholds (form 0 to 100): " + str(self.voltage) + ) + return False + if self.soc is not None and (self.soc < 0 or self.soc > 100): + logger.debug("SoC outside of thresholds (from 0 to 100): " + str(self.soc)) + return False + + return True + def log_cell_data(self) -> bool: if logger.getEffectiveLevel() > logging.INFO and len(self.cells) == 0: return False diff --git a/etc/dbus-serialbattery/bms/ant.py b/etc/dbus-serialbattery/bms/ant.py index b6e2d904..ceb6be68 100644 --- a/etc/dbus-serialbattery/bms/ant.py +++ b/etc/dbus-serialbattery/bms/ant.py @@ -63,15 +63,9 @@ def read_status_data(self): voltage = unpack_from(">H", status_data, 4) self.voltage = voltage[0] * 0.1 - # check if data is in the thresholds, if not it's very likely that it's not an ANT BMS - if self.voltage < 0 and self.voltage > 100: - return False current, self.soc = unpack_from(">lB", status_data, 70) self.current = 0.0 if current == 0 else current / -10 - # check if data is in the thresholds, if not it's very likely that it's not an ANT BMS - if self.soc < 0 or self.soc > 100 or abs(self.current) > 1000: - return False self.cell_count = unpack_from(">b", status_data, 123)[0] self.max_battery_voltage = utils.MAX_CELL_VOLTAGE * self.cell_count @@ -87,9 +81,6 @@ def read_status_data(self): capacity = unpack_from(">L", status_data, 75) self.capacity = capacity[0] / 1000000 - # check if data is in the thresholds, if not it's very likely that it's not an ANT BMS - if self.capacity < 0 or self.capacity > 1000: - return False capacity_remain = unpack_from(">L", status_data, 79) self.capacity_remain = capacity_remain[0] / 1000000 diff --git a/etc/dbus-serialbattery/bms/battery_template.py b/etc/dbus-serialbattery/bms/battery_template.py index 92c7fa49..e859c675 100644 --- a/etc/dbus-serialbattery/bms/battery_template.py +++ b/etc/dbus-serialbattery/bms/battery_template.py @@ -28,8 +28,7 @@ def test_connection(self): try: result = self.read_status_data() # get first data to show in startup log, only if result is true - if result: - self.refresh_data() + result = result and self.refresh_data() except Exception as err: logger.error(f"Unexpected {err=}, {type(err)=}") result = False @@ -87,6 +86,8 @@ def read_status_data(self): self.cycles, ) = unpack_from(">bb??bhx", status_data) + # Integrate a check to be sure, that the received data is from the BMS type you are making this driver for + self.hardware_version = "TemplateBMS " + str(self.cell_count) + " cells" logger.info(self.hardware_version) return True diff --git a/etc/dbus-serialbattery/bms/daly.py b/etc/dbus-serialbattery/bms/daly.py index 732af406..3d571696 100644 --- a/etc/dbus-serialbattery/bms/daly.py +++ b/etc/dbus-serialbattery/bms/daly.py @@ -548,6 +548,10 @@ def write_soc_and_datetime(self, ser): if self.soc_to_set is None: return False + # wait shortly, else the Daly is not ready and throws a lot of no reply errors + # if you see a lot of errors, try to increase in steps of 0.005 + sleep(0.020) + cmd = bytearray(13) now = datetime.now() @@ -577,7 +581,7 @@ def write_soc_and_datetime(self, ser): ser.write(cmd) reply = self.read_sentence(ser, self.command_set_soc) - if reply[0] != 1: + if reply is False or reply[0] != 1: logger.error("write soc failed") return True @@ -616,6 +620,10 @@ def write_charge_discharge_mos(self, ser): ): return False + # wait shortly, else the Daly is not ready and throws a lot of no reply errors + # if you see a lot of errors, try to increase in steps of 0.005 + sleep(0.020) + cmd = bytearray(self.command_base) if self.trigger_force_disable_charge is not None: diff --git a/etc/dbus-serialbattery/bms/hlpdatabms4s.py b/etc/dbus-serialbattery/bms/hlpdatabms4s.py index 7faf8b2c..9f33dc25 100644 --- a/etc/dbus-serialbattery/bms/hlpdatabms4s.py +++ b/etc/dbus-serialbattery/bms/hlpdatabms4s.py @@ -54,21 +54,8 @@ def refresh_data(self): pass return result - # def log_settings(self): - # logger.info(f'Battery {self.type} connected to dbus from {self.port}') - # logger.info(f'=== Settings ===') - # cell_counter = len(self.cells) - # logger.info(f'> Connection voltage {self.voltage}V | current {self.current}A | SOC {self.soc}%') - # logger.info(f'> Cell count {self.cell_count} | cells populated {cell_counter}') - # logger.info(f'> CCCM SOC {CCCM_SOC_ENABLE} | DCCM SOC {DCCM_SOC_ENABLE}') - # logger.info(f'> CCCM CV {CCCM_CV_ENABLE} | DCCM CV {DCCM_CV_ENABLE}') - # logger.info(f'> CCCM T {CCCM_T_ENABLE} | DCCM T {DCCM_T_ENABLE}') - # logger.info(f'> MIN_CELL_VOLTAGE {MIN_CELL_VOLTAGE}V | MAX_CELL_VOLTAGE {MAX_CELL_VOLTAGE}V') - - return - def read_test_data(self): - test_data = self.read_serial_data_HLPdataBMS4S(b"pv\n", 1, 15) + test_data = self.read_serial_data_HLPdataBMS4S(b"pv\n", 0.2, 12) if test_data is False: return False s1 = str(test_data) @@ -196,19 +183,15 @@ def manage_charge_current(self): self.control_discharge_current = 1000 def read_serial_data_HLPdataBMS4S(self, command, time, min_len): - data = read_serial_data2(command, self.port, self.baud_rate, time, min_len) - if data is False: - return False + data = read_serial_data(command, self.port, self.baud_rate, time, min_len) return data -def read_serial_data2(command, port, baud, time, min_len): +def read_serial_data(command, port, baud, time, min_len): try: with serial.Serial(port, baudrate=baud, timeout=0.5) as ser: - ret = read_serialport_data2(ser, command, time, min_len) - if ret is True: - return ret - return False + ret = read_serialport_data(ser, command, time, min_len) + return ret except serial.SerialException as e: logger.error(e) @@ -218,8 +201,11 @@ def read_serial_data2(command, port, baud, time, min_len): return False -def read_serialport_data2(ser, command, time, min_len): +def read_serialport_data(ser, command, time, min_len): try: + if min_len == 12: + ser.write(b"\n") + sleep(0.2) cnt = 0 while cnt < 3: cnt += 1 @@ -227,7 +213,8 @@ def read_serialport_data2(ser, command, time, min_len): ser.flushInput() ser.write(command) sleep(time) - res = ser.read(1000) + toread = ser.inWaiting() + res = ser.read(toread) if len(res) >= min_len: return res return False diff --git a/etc/dbus-serialbattery/bms/renogy.py b/etc/dbus-serialbattery/bms/renogy.py index acfe2335..e920a771 100644 --- a/etc/dbus-serialbattery/bms/renogy.py +++ b/etc/dbus-serialbattery/bms/renogy.py @@ -48,8 +48,7 @@ def test_connection(self): try: result = self.read_gen_data() # get first data to show in startup log - if result: - self.refresh_data() + result = result and self.refresh_data() except Exception as err: logger.error(f"Unexpected {err=}, {type(err)=}") result = False @@ -145,6 +144,8 @@ def read_cell_data(self): self.cells[c].voltage = 0 return True + """ + # Did not found who changed this. "command_env_temp_count" is missing def read_temp_data(self): # Check to see how many Enviromental Temp Sensors this battery has, it may have none. num_env_temps = self.read_serial_data_renogy(self.command_env_temp_count) @@ -172,6 +173,17 @@ def read_temp_data(self): logger.info("temp2 = %s °C", temp2) return True + """ + + def read_temp_data(self): + temp1 = self.read_serial_data_renogy(self.command_bms_temp1) + temp2 = self.read_serial_data_renogy(self.command_bms_temp2) + if temp1 is False: + return False + self.temp1 = unpack(">H", temp1)[0] / 10 + self.temp2 = unpack(">H", temp2)[0] / 10 + + return True def read_bms_config(self): return True diff --git a/etc/dbus-serialbattery/bms/seplos.py b/etc/dbus-serialbattery/bms/seplos.py index b7c9a2e1..0a0c3fe2 100644 --- a/etc/dbus-serialbattery/bms/seplos.py +++ b/etc/dbus-serialbattery/bms/seplos.py @@ -115,7 +115,6 @@ def refresh_data(self): # This will be called for every iteration (self.poll_interval) # Return True if success, False for failure result_status = self.read_status_data() - # sleep(0.5) result_alarm = self.read_alarm_data() return result_status and result_alarm @@ -129,15 +128,20 @@ def decode_alarm_byte(data_byte: int, alarm_bit: int, warn_bit: int): return Protection.OK def read_alarm_data(self): + logger.debug("read alarm data") data = self.read_serial_data_seplos( self.encode_cmd(address=0x00, cid2=self.COMMAND_ALARM, info=b"01") ) - # check if connection success - if data is False: + # check if we could successfully read data and we have the expected length of 98 bytes + if data is False or len(data) != 98: return False - logger.debug("alarm info raw {}".format(data)) - return self.decode_alarm_data(bytes.fromhex(data.decode("ascii"))) + try: + logger.debug("alarm info raw {}".format(data)) + return self.decode_alarm_data(bytes.fromhex(data.decode("ascii"))) + except (ValueError, UnicodeDecodeError) as e: + logger.warning("could not hex-decode raw alarm data", exc_info=e) + return False def decode_alarm_data(self, data: bytes): logger.debug("alarm info decoded {}".format(data)) @@ -191,14 +195,21 @@ def decode_alarm_data(self, data: bytes): def read_status_data(self): logger.debug("read status data") + data = self.read_serial_data_seplos( self.encode_cmd(address=0x00, cid2=0x42, info=b"01") ) - # check if connection success - if data is False: + # check if reading data was successful and has the expected data length of 150 byte + if data is False or len(data) != 150: + return False + + if not self.decode_status_data(data): return False + return True + + def decode_status_data(self, data): cell_count_offset = 4 voltage_offset = 6 temps_offset = 72 @@ -218,7 +229,6 @@ def read_status_data(self): ) / 10 self.cells[i].temp = temp logger.debug("Temp cell[{}]={}°C".format(i, temp)) - self.temp1 = ( Seplos.int_from_2byte_hex_ascii(data, temps_offset + 4 * 4) - 2731 ) / 10 @@ -234,7 +244,6 @@ def read_status_data(self): self.soc = Seplos.int_from_2byte_hex_ascii(data, offset=114) / 10 self.cycles = Seplos.int_from_2byte_hex_ascii(data, offset=122) self.hardware_version = "Seplos BMS {} cells".format(self.cell_count) - logger.debug("Current = {}A , Voltage = {}V".format(self.current, self.voltage)) logger.debug( "Capacity = {}/{}Ah , SOC = {}%".format( @@ -297,7 +306,9 @@ def read_serial_data_seplos(self, command): return_data = data[length_pos + 3 : -5] info_length = Seplos.int_from_2byte_hex_ascii(b"0" + data[length_pos:], 0) logger.debug( - "return info data of length {} : {}".format(info_length, return_data) + "returning info data of length {}, info_length is {} : {}".format( + len(return_data), info_length, return_data + ) ) return return_data diff --git a/etc/dbus-serialbattery/bms/sinowealth.py b/etc/dbus-serialbattery/bms/sinowealth.py index 6806217c..8e4e900e 100755 --- a/etc/dbus-serialbattery/bms/sinowealth.py +++ b/etc/dbus-serialbattery/bms/sinowealth.py @@ -149,10 +149,6 @@ def read_soc(self): return False logger.debug(">>> INFO: current SOC: %u", soc_data[1]) soc = soc_data[1] - # check if data is in the thresholds, if not it's very likely that it's not a Sinowealth BMS - if soc < 0 or soc > 100: - return False - self.soc = soc return True @@ -172,12 +168,8 @@ def read_pack_voltage(self): return False pack_voltage = unpack_from(">H", pack_voltage_data[:-1]) pack_voltage = pack_voltage[0] / 1000 - logger.debug(">>> INFO: current pack voltage: %f", pack_voltage) - # check if data is in the thresholds, if not it's very likely that it's not a Sinowealth BMS - if pack_voltage < 0 or pack_voltage > 100: - return False - self.voltage = pack_voltage + logger.debug(">>> INFO: current pack voltage: %f", self.voltage) return True def read_pack_current(self): @@ -187,9 +179,6 @@ def read_pack_current(self): current = unpack_from(">i", current_data[:-1]) current = current[0] / 1000 logger.debug(">>> INFO: current pack current: %f", current) - # check if data is in the thresholds, if not it's very likely that it's not a Sinowealth BMS - if abs(current) > 1000: - return False self.current = current return True @@ -214,9 +203,6 @@ def read_capacity(self): capacity = unpack_from(">i", capacity_data[:-1]) capacity = capacity[0] / 1000 logger.debug(">>> INFO: Battery capacity: %f Ah", capacity) - # check if data is in the thresholds, if not it's very likely that it's not a Sinowealth BMS - if capacity < 0 or capacity > 1000: - return False self.capacity = capacity return True diff --git a/etc/dbus-serialbattery/dbus-serialbattery.py b/etc/dbus-serialbattery/dbus-serialbattery.py index 5703e79b..72c3234c 100644 --- a/etc/dbus-serialbattery/dbus-serialbattery.py +++ b/etc/dbus-serialbattery/dbus-serialbattery.py @@ -103,7 +103,7 @@ def get_battery(_port) -> Union[Battery, None]: battery: Battery = batteryClass( port=_port, baud=baud, address=test.get("address") ) - if battery.test_connection(): + if battery.test_connection() and battery.validate_data(): logger.info( "Connection established to " + battery.__class__.__name__ ) @@ -135,12 +135,12 @@ def get_port() -> str: if port not in utils.EXCLUDED_DEVICES: return port else: - logger.info( + logger.debug( "Stopping dbus-serialbattery: " + str(port) + " is excluded trough the config file" ) - sleep(86400) + sleep(60) sys.exit(0) else: # just for MNB-SPI @@ -166,7 +166,7 @@ def get_port() -> str: class_ = eval(port) testbms = class_("", 9600, sys.argv[2]) - if testbms.test_connection() is True: + if testbms.test_connection(): logger.info("Connection established to " + testbms.__class__.__name__) battery = testbms else: diff --git a/etc/dbus-serialbattery/reinstall-local.sh b/etc/dbus-serialbattery/reinstall-local.sh index d0982864..48585e3e 100755 --- a/etc/dbus-serialbattery/reinstall-local.sh +++ b/etc/dbus-serialbattery/reinstall-local.sh @@ -156,6 +156,9 @@ if [ -d "/service/dbus-blebattery.0" ]; then pkill -f "supervise dbus-blebattery.*" pkill -f "multilog .* /var/log/dbus-blebattery.*" pkill -f "python .*/dbus-serialbattery.py .*_Ble" + + # kill opened bluetoothctl processes + pkill -f "^bluetoothctl " fi @@ -241,8 +244,11 @@ if [ "$length" -gt 0 ]; then echo # setup cronjob to restart Bluetooth - # remove if not needed anymore, has to be checked first - grep -qxF "5 0,12 * * * /etc/init.d/bluetooth restart" /var/spool/cron/root || echo "5 0,12 * * * /etc/init.d/bluetooth restart" >> /var/spool/cron/root + # remove if not needed anymore, has to be checked first --> seems that it's not needed anymore + # grep -qxF "5 0,12 * * * /etc/init.d/bluetooth restart" /var/spool/cron/root || echo "5 0,12 * * * /etc/init.d/bluetooth restart" >> /var/spool/cron/root + + # remove cronjob + sed -i "/5 0,12 \* \* \* \/etc\/init.d\/bluetooth restart/d" /var/spool/cron/root else diff --git a/etc/dbus-serialbattery/utils.py b/etc/dbus-serialbattery/utils.py index 36d8523a..b1c5f42b 100644 --- a/etc/dbus-serialbattery/utils.py +++ b/etc/dbus-serialbattery/utils.py @@ -38,7 +38,7 @@ def _get_list_from_config( # Constants - Need to dynamically get them in future -DRIVER_VERSION = "1.0.20230611dev" +DRIVER_VERSION = "1.0.20230613dev" zero_char = chr(48) degree_sign = "\N{DEGREE SIGN}" @@ -55,6 +55,16 @@ def _get_list_from_config( MAX_CELL_VOLTAGE = float(config["DEFAULT"]["MAX_CELL_VOLTAGE"]) # Max voltage can seen as absorption voltage FLOAT_CELL_VOLTAGE = float(config["DEFAULT"]["FLOAT_CELL_VOLTAGE"]) +if FLOAT_CELL_VOLTAGE > MAX_CELL_VOLTAGE: + FLOAT_CELL_VOLTAGE = MAX_CELL_VOLTAGE + logger.error( + ">>> ERROR: FLOAT_CELL_VOLTAGE is set to a value greater than MAX_CELL_VOLTAGE. Please check the configuration." + ) +if FLOAT_CELL_VOLTAGE < MIN_CELL_VOLTAGE: + FLOAT_CELL_VOLTAGE = MIN_CELL_VOLTAGE + logger.error( + ">>> ERROR: FLOAT_CELL_VOLTAGE is set to a value less than MAX_CELL_VOLTAGE. Please check the configuration." + ) # --------- BMS disconnect behaviour --------- # Description: Block charge and discharge when the communication to the BMS is lost. If you are removing the