From 1d2e47d1ab8fe28e4b62de957798df77adc128ff Mon Sep 17 00:00:00 2001 From: Bernd Stahlbock <6627385+transistorgit@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:28:23 +0000 Subject: [PATCH 01/11] set soc=100% when charge mode changes to float, apply exponential smoothing on current readout --- etc/dbus-serialbattery/bms/daly.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/etc/dbus-serialbattery/bms/daly.py b/etc/dbus-serialbattery/bms/daly.py index 87510c48..af72d10f 100644 --- a/etc/dbus-serialbattery/bms/daly.py +++ b/etc/dbus-serialbattery/bms/daly.py @@ -27,6 +27,7 @@ def __init__(self, port, baud, address): self.trigger_force_disable_discharge = None self.trigger_force_disable_charge = None self.cells_volts_data_lastreadbad = False + self.last_charge_mode = self.charge_mode # command bytes [StartFlag=A5][Address=40][Command=94][DataLength=8][8x zero bytes][checksum] command_base = b"\xA5\x40\x94\x08\x00\x00\x00\x00\x00\x00\x00\x00\x81" @@ -174,6 +175,8 @@ def refresh_data(self): self.write_charge_discharge_mos(ser) + self.update_soc(ser) + except OSError: logger.warning("Couldn't open serial port") @@ -181,6 +184,16 @@ def refresh_data(self): logger.info("refresh_data: result: " + str(result)) return result + def update_soc(self, ser): + if self.last_charge_mode is not None and self.charge_mode is not None: + if not self.last_charge_mode.startswith( + "Float" + ) and self.charge_mode.startswith("Float"): + # we just entered float mode, so the battery must be full + self.soc_to_set = 100 + self.write_soc_and_datetime(ser) + self.last_charge_mode = self.charge_mode + def read_status_data(self, ser): status_data = self.request_data(ser, self.command_status) # check if connection success @@ -229,7 +242,10 @@ def read_soc_data(self, ser): ) if crntMinValid < current < crntMaxValid: self.voltage = voltage / 10 - self.current = current + # apply exponential smoothing on the flickering current measurement + self.current = (0.1 * current) + ( + 0.9 * (0 if self.current is None else self.current) + ) self.soc = soc / 10 return True From b0ed2a44314cb08a2c2f1d4afcf224fa76516d6b Mon Sep 17 00:00:00 2001 From: Bernd Stahlbock <6627385+transistorgit@users.noreply.github.com> Date: Tue, 13 Jun 2023 20:44:37 +0000 Subject: [PATCH 02/11] fix rs485 write communication errors by inserting sleeps, add debug print for charge mode and fix crash on write soc failures --- etc/dbus-serialbattery/bms/daly.py | 13 ++++++++++++- etc/dbus-serialbattery/service/log/run | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/etc/dbus-serialbattery/bms/daly.py b/etc/dbus-serialbattery/bms/daly.py index af72d10f..c748fd86 100644 --- a/etc/dbus-serialbattery/bms/daly.py +++ b/etc/dbus-serialbattery/bms/daly.py @@ -186,6 +186,9 @@ def refresh_data(self): def update_soc(self, ser): if self.last_charge_mode is not None and self.charge_mode is not None: + #debug + if self.last_charge_mode != self.charge_mode: + logger.info(f"Switch charge mode from {self.last_charge_mode} to {self.charge_mode}") if not self.last_charge_mode.startswith( "Float" ) and self.charge_mode.startswith("Float"): @@ -560,6 +563,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() @@ -589,7 +596,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 @@ -622,6 +629,10 @@ def force_discharging_off_callback(self, path, value): return False def write_charge_discharge_mos(self, ser): + # 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) + if ( self.trigger_force_disable_charge is None and self.trigger_force_disable_discharge is None diff --git a/etc/dbus-serialbattery/service/log/run b/etc/dbus-serialbattery/service/log/run index ca6196de..d826d8ba 100755 --- a/etc/dbus-serialbattery/service/log/run +++ b/etc/dbus-serialbattery/service/log/run @@ -1,3 +1,3 @@ #!/bin/sh exec 2>&1 -exec multilog t s25000 n4 /var/log/dbus-serialbattery.TTY +exec multilog t s2500000 n4 /var/log/dbus-serialbattery.TTY From 75dd0091587d68736923fd582baaec8f4f5ede1c Mon Sep 17 00:00:00 2001 From: Bernd Stahlbock <6627385+transistorgit@users.noreply.github.com> Date: Thu, 15 Jun 2023 12:50:37 +0000 Subject: [PATCH 03/11] debug msg --- etc/dbus-serialbattery/battery.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/dbus-serialbattery/battery.py b/etc/dbus-serialbattery/battery.py index 1ce3c5be..61d468e0 100644 --- a/etc/dbus-serialbattery/battery.py +++ b/etc/dbus-serialbattery/battery.py @@ -257,6 +257,9 @@ def manage_charge_voltage_linear(self) -> None: self.allow_max_voltage = False self.max_voltage_start_time = None + logger.info(f"highCell {foundHighCellVoltage}, vDiff {voltageDiff}, vStartTime {self.max_voltage_start_time}, allowMaxV {self.allow_max_voltage}") + + # INFO: battery will only switch to Absorption, if all cells are balanced. # Reach MAX_CELL_VOLTAGE * cell count if they are all balanced. if foundHighCellVoltage and self.allow_max_voltage: From 51b71d600f455b6eb5974ff537155ad0766d3610 Mon Sep 17 00:00:00 2001 From: Bernd Stahlbock <6627385+transistorgit@users.noreply.github.com> Date: Thu, 15 Jun 2023 16:32:00 +0000 Subject: [PATCH 04/11] fix meaningless time to go values --- etc/dbus-serialbattery/dbushelper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/dbus-serialbattery/dbushelper.py b/etc/dbus-serialbattery/dbushelper.py index 849225c4..b0a217d7 100644 --- a/etc/dbus-serialbattery/dbushelper.py +++ b/etc/dbus-serialbattery/dbushelper.py @@ -612,7 +612,7 @@ def publish_dbus(self): ) ) ) - if self.battery.current + if self.battery.current and abs(self.battery.current) > 0.1 else None ) From b82c3ae64ce757ff294688acfabae5768062a8a6 Mon Sep 17 00:00:00 2001 From: Bernd Stahlbock <6627385+transistorgit@users.noreply.github.com> Date: Thu, 15 Jun 2023 16:32:00 +0000 Subject: [PATCH 05/11] fix meaningless time to go values --- etc/dbus-serialbattery/dbushelper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/dbus-serialbattery/dbushelper.py b/etc/dbus-serialbattery/dbushelper.py index 849225c4..b0a217d7 100644 --- a/etc/dbus-serialbattery/dbushelper.py +++ b/etc/dbus-serialbattery/dbushelper.py @@ -612,7 +612,7 @@ def publish_dbus(self): ) ) ) - if self.battery.current + if self.battery.current and abs(self.battery.current) > 0.1 else None ) From b4025b51552349273120e83dc27272f0e8b633df Mon Sep 17 00:00:00 2001 From: Manuel Date: Sat, 17 Jun 2023 12:30:33 +0200 Subject: [PATCH 06/11] cleanup --- CHANGELOG.md | 2 +- etc/dbus-serialbattery/battery.py | 3 ++- etc/dbus-serialbattery/dbushelper.py | 26 -------------------------- etc/dbus-serialbattery/utils.py | 2 +- 4 files changed, 4 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1db8a136..96874f0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ * 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 +* 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 & @ogurevich * Removed: Cronjob to restart Bluetooth service every 12 hours by @mr-manuel diff --git a/etc/dbus-serialbattery/battery.py b/etc/dbus-serialbattery/battery.py index 232fbfbb..ed0ee732 100644 --- a/etc/dbus-serialbattery/battery.py +++ b/etc/dbus-serialbattery/battery.py @@ -354,7 +354,8 @@ def manage_charge_voltage_linear(self) -> None: elapsed_time = int(time()) - self.transition_start_time # Duration in seconds for smooth voltage drop from absorption to float # depending on the number of cells - FLOAT_MODE_TRANSITION_DURATION = self.cell_count * 12 + # 900 seconds / number of cells (mostly 16) = 56 + FLOAT_MODE_TRANSITION_DURATION = self.cell_count * 56 t = min(1, elapsed_time / FLOAT_MODE_TRANSITION_DURATION) self.control_voltage = ( 1 - t diff --git a/etc/dbus-serialbattery/dbushelper.py b/etc/dbus-serialbattery/dbushelper.py index b0a217d7..cec1148d 100644 --- a/etc/dbus-serialbattery/dbushelper.py +++ b/etc/dbus-serialbattery/dbushelper.py @@ -54,32 +54,6 @@ def setup_instance(self): 0, 0, ], - # 'CellVoltageMin': [path + '/CellVoltageMin', 2.8, 0.0, 5.0], - # 'CellVoltageMax': [path + '/CellVoltageMax', 3.45, 0.0, 5.0], - # 'CellVoltageFloat': [path + '/CellVoltageFloat', 3.35, 0.0, 5.0], - # 'VoltageMaxTime': [path + '/VoltageMaxTime', 900, 0, 0], - # 'VoltageResetSocLimit': [path + '/VoltageResetSocLimit', 90, 0, 100], - # 'MaxChargeCurrent': [path + '/MaxCurrentCharge', 5, 0.0, 500], - # 'MaxDischargeCurrent': [path + '/MaxCurrentDischarge', 7, 0.0, 500], - # 'AllowDynamicChargeCurrent': [path + '/AllowDynamicChargeCurrent', 1, 0, 1], - # 'AllowDynamicDischargeCurrent': [path + '/AllowDynamicDischargeCurrent', 1, 0, 1], - # 'AllowDynamicChargeVoltage': [path + '/AllowDynamicChargeVoltage', 0, 0, 1], - # 'SocLowWarning': [path + '/SocLowWarning', 20, 0, 100], - # 'SocLowAlarm': [path + '/SocLowAlarm', 10, 0, 100], - # 'Capacity': [path + '/Capacity', '', 0, 500], - # 'EnableInvertedCurrent': [path + '/EnableInvertedCurrent', 0, 0, 1], - # 'CCMSocLimitCharge1': [path + '/CCMSocLimitCharge1', 98, 0, 100], - # 'CCMSocLimitCharge2': [path + '/CCMSocLimitCharge2', 95, 0, 100], - # 'CCMSocLimitCharge3': [path + '/CCMSocLimitCharge3', 91, 0, 100], - # 'CCMSocLimitDischarge1': [path + '/CCMSocLimitDischarge1', 10, 0, 100], - # 'CCMSocLimitDischarge2': [path + '/CCMSocLimitDischarge2', 20, 0, 100], - # 'CCMSocLimitDischarge3': [path + '/CCMSocLimitDischarge3', 30, 0, 100], - # 'CCMCurrentLimitCharge1': [path + '/CCMCurrentLimitCharge1', 5, 0, 100], - # 'CCMCurrentLimitCharge2': [path + '/CCMCurrentLimitCharge2', '', 0, 100], - # 'CCMCurrentLimitCharge3': [path + '/CCMCurrentLimitCharge3', '', 0, 100], - # 'CCMCurrentLimitDischarge1': [path + '/CCMCurrentLimitDischarge1', 5, 0, 100], - # 'CCMCurrentLimitDischarge2': [path + '/CCMCurrentLimitDischarge2', '', 0, 100], - # 'CCMCurrentLimitDischarge3': [path + '/CCMCurrentLimitDischarge3', '', 0, 100], } self.settings = SettingsDevice(get_bus(), settings, self.handle_changed_setting) diff --git a/etc/dbus-serialbattery/utils.py b/etc/dbus-serialbattery/utils.py index aec28640..a62e9f6e 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.20230613dev" +DRIVER_VERSION = "1.0.20230617dev" zero_char = chr(48) degree_sign = "\N{DEGREE SIGN}" From 3dfeff1244d4d0d74de1d414e87f1fd8ae147985 Mon Sep 17 00:00:00 2001 From: Manuel Date: Sat, 17 Jun 2023 17:16:56 +0200 Subject: [PATCH 07/11] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96874f0e..dc057c94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * 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 meaningless Time to Go values by @transistorgit * Changed: Fixed typo in `config.ini` sample by @hoschult * Changed: For BMS_TYPE now multiple BMS can be specified by @mr-manuel * Changed: Improved battery error handling on connection loss by @mr-manuel From 4b8be76ba09d9f014839de6916d116b209c3dc61 Mon Sep 17 00:00:00 2001 From: Bernd Stahlbock <6627385+transistorgit@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:43:39 +0000 Subject: [PATCH 08/11] remove debug msg --- etc/dbus-serialbattery/battery.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/etc/dbus-serialbattery/battery.py b/etc/dbus-serialbattery/battery.py index 24677317..de2d986e 100644 --- a/etc/dbus-serialbattery/battery.py +++ b/etc/dbus-serialbattery/battery.py @@ -291,9 +291,6 @@ def manage_charge_voltage_linear(self) -> None: if voltageSum < self.max_battery_voltage - utils.VOLTAGE_DROP: self.max_voltage_start_time = None - logger.info(f"highCell {foundHighCellVoltage}, vDiff {voltageDiff}, vStartTime {self.max_voltage_start_time}, allowMaxV {self.allow_max_voltage}") - - # INFO: battery will only switch to Absorption, if all cells are balanced. # Reach MAX_CELL_VOLTAGE * cell count if they are all balanced. if foundHighCellVoltage and self.allow_max_voltage: From cc4ed9c62a52cb2736bd3b4c99569d8239c5c619 Mon Sep 17 00:00:00 2001 From: Bernd Stahlbock <6627385+transistorgit@users.noreply.github.com> Date: Mon, 19 Jun 2023 17:45:51 +0000 Subject: [PATCH 09/11] remove debug msg --- etc/dbus-serialbattery/bms/daly.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/etc/dbus-serialbattery/bms/daly.py b/etc/dbus-serialbattery/bms/daly.py index 27de1ef5..1f67e7c8 100644 --- a/etc/dbus-serialbattery/bms/daly.py +++ b/etc/dbus-serialbattery/bms/daly.py @@ -186,9 +186,6 @@ def refresh_data(self): def update_soc(self, ser): if self.last_charge_mode is not None and self.charge_mode is not None: - #debug - if self.last_charge_mode != self.charge_mode: - logger.info(f"Switch charge mode from {self.last_charge_mode} to {self.charge_mode}") if not self.last_charge_mode.startswith( "Float" ) and self.charge_mode.startswith("Float"): From 12232d8fa0ac0d34cf96334ea2d55e8cc5cadf9f Mon Sep 17 00:00:00 2001 From: Bernd Stahlbock <6627385+transistorgit@users.noreply.github.com> Date: Mon, 19 Jun 2023 18:01:53 +0000 Subject: [PATCH 10/11] undo debug change --- etc/dbus-serialbattery/service/log/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/dbus-serialbattery/service/log/run b/etc/dbus-serialbattery/service/log/run index d826d8ba..ca6196de 100755 --- a/etc/dbus-serialbattery/service/log/run +++ b/etc/dbus-serialbattery/service/log/run @@ -1,3 +1,3 @@ #!/bin/sh exec 2>&1 -exec multilog t s2500000 n4 /var/log/dbus-serialbattery.TTY +exec multilog t s25000 n4 /var/log/dbus-serialbattery.TTY From b384400537fddf1dc5550b3fc3071f07b281869c Mon Sep 17 00:00:00 2001 From: Manuel Date: Tue, 20 Jun 2023 11:53:43 +0200 Subject: [PATCH 11/11] Daly BMS make auto reset soc configurable --- CHANGELOG.md | 1 + etc/dbus-serialbattery/bms/daly.py | 3 ++- etc/dbus-serialbattery/config.default.ini | 5 +++++ etc/dbus-serialbattery/utils.py | 7 ++++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc057c94..c6a50ae1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## v1.0.x * Added: Bluetooth: Show signal strength of BMS in log by @mr-manuel * Added: Create unique identifier, if not provided from BMS by @mr-manuel +* Added: Daly BMS: Auto reset SoC when changing to float (can be turned off in the config file) by @transistorgit * Added: Exclude a device from beeing used by the dbus-serialbattery driver by @mr-manuel * 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 diff --git a/etc/dbus-serialbattery/bms/daly.py b/etc/dbus-serialbattery/bms/daly.py index 1f67e7c8..d68eac78 100644 --- a/etc/dbus-serialbattery/bms/daly.py +++ b/etc/dbus-serialbattery/bms/daly.py @@ -175,7 +175,8 @@ def refresh_data(self): self.write_charge_discharge_mos(ser) - self.update_soc(ser) + if utils.AUTO_RESET_SOC: + self.update_soc(ser) except OSError: logger.warning("Couldn't open serial port") diff --git a/etc/dbus-serialbattery/config.default.ini b/etc/dbus-serialbattery/config.default.ini index 96cd90f4..59dc3be0 100644 --- a/etc/dbus-serialbattery/config.default.ini +++ b/etc/dbus-serialbattery/config.default.ini @@ -200,6 +200,11 @@ EXCLUDED_DEVICES = ; /dev/ttyUSB0:My first battery,/dev/ttyUSB1:My second battery CUSTOM_BATTERY_NAMES = +; Auto reset SoC +; If on, then SoC is reset to 100%, if the value switches from absorption to float voltage +; Currently only working for Daly BMS +AUTO_RESET_SOC = True + ; Publish the config settings to the dbus path "/Info/Config/" PUBLISH_CONFIG_VALUES = 1 diff --git a/etc/dbus-serialbattery/utils.py b/etc/dbus-serialbattery/utils.py index 2a7a57a9..fb7a93fd 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.20230617dev" +DRIVER_VERSION = "1.0.20230620dev" zero_char = chr(48) degree_sign = "\N{DEGREE SIGN}" @@ -298,6 +298,11 @@ def _get_list_from_config( "DEFAULT", "CUSTOM_BATTERY_NAMES", lambda v: str(v) ) +# Auto reset SoC +# If on, then SoC is reset to 100%, if the value switches from absorption to float voltage +# Currently only working for Daly BMS +AUTO_RESET_SOC = "True" == config["DEFAULT"]["AUTO_RESET_SOC"] + # Publish the config settings to the dbus path "/Info/Config/" PUBLISH_CONFIG_VALUES = int(config["DEFAULT"]["PUBLISH_CONFIG_VALUES"])