From a74223cc2968a9c2fd4ade02761e6ef326400a9d Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 17 Jul 2023 16:13:35 +0200 Subject: [PATCH 1/4] Added temperature names to dbus/mqtt --- CHANGELOG.md | 1 + etc/dbus-serialbattery/dbushelper.py | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b40ecd4..8df28974 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * 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: Load to bulk voltage every x days to reset the SoC to 100% for some BMS by @mr-manuel * Added: Save custom name and make it restart persistant by @mr-manuel +* Added: Temperature names to dbus and mqtt 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 diff --git a/etc/dbus-serialbattery/dbushelper.py b/etc/dbus-serialbattery/dbushelper.py index a9878dec..bca3b746 100644 --- a/etc/dbus-serialbattery/dbushelper.py +++ b/etc/dbus-serialbattery/dbushelper.py @@ -210,9 +210,13 @@ def setup_vedbus(self): self._dbusservice.add_path("/System/MaxTemperatureCellId", None, writeable=True) self._dbusservice.add_path("/System/MOSTemperature", None, writeable=True) self._dbusservice.add_path("/System/Temperature1", None, writeable=True) + self._dbusservice.add_path("/System/Temperature1Name", None, writeable=True) self._dbusservice.add_path("/System/Temperature2", None, writeable=True) + self._dbusservice.add_path("/System/Temperature2Name", None, writeable=True) self._dbusservice.add_path("/System/Temperature3", None, writeable=True) + self._dbusservice.add_path("/System/Temperature3Name", None, writeable=True) self._dbusservice.add_path("/System/Temperature4", None, writeable=True) + self._dbusservice.add_path("/System/Temperature4Name", None, writeable=True) self._dbusservice.add_path( "/System/MaxCellVoltage", None, @@ -463,9 +467,13 @@ def publish_dbus(self): ] = self.battery.get_max_temp_id() self._dbusservice["/System/MOSTemperature"] = self.battery.get_mos_temp() self._dbusservice["/System/Temperature1"] = self.battery.temp1 + self._dbusservice["/System/Temperature1Name"] = utils.TEMP_1_NAME self._dbusservice["/System/Temperature2"] = self.battery.temp2 + self._dbusservice["/System/Temperature2Name"] = utils.TEMP_2_NAME self._dbusservice["/System/Temperature3"] = self.battery.temp3 + self._dbusservice["/System/Temperature3Name"] = utils.TEMP_3_NAME self._dbusservice["/System/Temperature4"] = self.battery.temp4 + self._dbusservice["/System/Temperature4Name"] = utils.TEMP_4_NAME # Voltage control self._dbusservice["/Info/MaxChargeVoltage"] = self.battery.control_voltage From 6ece4474387240692e1d37d6d5fee92b582c2051 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 17 Jul 2023 17:08:35 +0200 Subject: [PATCH 2/4] Use current avg of last 300 cycles for TTG & TTS --- CHANGELOG.md | 1 + etc/dbus-serialbattery/battery.py | 2 ++ etc/dbus-serialbattery/dbushelper.py | 31 ++++++++++++++++++++++++---- etc/dbus-serialbattery/utils.py | 2 +- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8df28974..0a15f695 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Added: Load to bulk voltage every x days to reset the SoC to 100% for some BMS by @mr-manuel * Added: Save custom name and make it restart persistant by @mr-manuel * Added: Temperature names to dbus and mqtt by @mr-manuel +* Added: Use current average of the last 300 cycles for time to go and time to SoC calculation 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 diff --git a/etc/dbus-serialbattery/battery.py b/etc/dbus-serialbattery/battery.py index af2f56ae..26140935 100644 --- a/etc/dbus-serialbattery/battery.py +++ b/etc/dbus-serialbattery/battery.py @@ -83,6 +83,8 @@ def init_values(self): """ self.voltage = None self.current = None + self.current_avg = None + self.current_avg_lst = [] self.capacity_remain = None self.capacity = None self.cycles = None diff --git a/etc/dbus-serialbattery/dbushelper.py b/etc/dbus-serialbattery/dbushelper.py index bca3b746..a564141e 100644 --- a/etc/dbus-serialbattery/dbushelper.py +++ b/etc/dbus-serialbattery/dbushelper.py @@ -582,6 +582,16 @@ def publish_dbus(self): # Update TimeToGo and/or TimeToSoC try: + # calculate current average for the last 300 cycles + # if Time-To-Go or Time-To-SoC is enabled + if utils.TIME_TO_GO_ENABLE or len(utils.TIME_TO_SOC_POINTS) > 0: + if self.battery.current is not None: + self.battery.current_avg_lst.append(self.battery.current) + + # delete oldest value + if len(self.battery.current_avg_lst) > 300: + del self.battery.current_avg_lst[0] + if ( self.battery.capacity is not None and (utils.TIME_TO_GO_ENABLE or len(utils.TIME_TO_SOC_POINTS) > 0) @@ -591,8 +601,15 @@ def publish_dbus(self): ) ): self.battery.time_to_soc_update = int(time()) + + self.battery.current_avg = round( + sum(self.battery.current_avg_lst) + / len(self.battery.current_avg_lst), + 2, + ) + crntPrctPerSec = ( - abs(self.battery.current / (self.battery.capacity / 100)) / 3600 + abs(self.battery.current_avg / (self.battery.capacity / 100)) / 3600 ) # Update TimeToGo item @@ -602,11 +619,17 @@ def publish_dbus(self): abs( int( self.battery.get_timeToSoc( - utils.SOC_LOW_WARNING, crntPrctPerSec, True + # switch value depending on charging/discharging + utils.SOC_LOW_WARNING + if self.battery.current_avg < 0 + else 100, + crntPrctPerSec, + True, ) ) ) - if self.battery.current and abs(self.battery.current) > 0.1 + if self.battery.current_avg + and abs(self.battery.current_avg) > 0.1 else None ) @@ -615,7 +638,7 @@ def publish_dbus(self): for num in utils.TIME_TO_SOC_POINTS: self._dbusservice["/TimeToSoC/" + str(num)] = ( self.battery.get_timeToSoc(num, crntPrctPerSec) - if self.battery.current + if self.battery.current_avg else None ) diff --git a/etc/dbus-serialbattery/utils.py b/etc/dbus-serialbattery/utils.py index 696d0028..73bab00a 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.20230711dev" +DRIVER_VERSION = "1.0.20230717dev" zero_char = chr(48) degree_sign = "\N{DEGREE SIGN}" From b914e8c8bd02984788c10acd69e2e85534236094 Mon Sep 17 00:00:00 2001 From: Manuel Date: Mon, 17 Jul 2023 17:09:30 +0200 Subject: [PATCH 3/4] Calculate only positive Time-to-SoC points --- CHANGELOG.md | 1 + etc/dbus-serialbattery/battery.py | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a15f695..f4e73afc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Added: Temperature names to dbus and mqtt by @mr-manuel * Added: Use current average of the last 300 cycles for time to go and time to SoC calculation 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: Calculate only positive Time-to-SoC points 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 diff --git a/etc/dbus-serialbattery/battery.py b/etc/dbus-serialbattery/battery.py index 26140935..a89a4744 100644 --- a/etc/dbus-serialbattery/battery.py +++ b/etc/dbus-serialbattery/battery.py @@ -881,6 +881,14 @@ def get_timeToSoc(self, socnum, crntPrctPerSec, onlyNumber=False) -> str: else: diffSoc = self.soc - socnum + """ + calculate only positive SoC points, since negative points have no sense + when charging only points above current SoC are shown + when discharging only points below current SoC are shown + """ + if diffSoc < 0: + return None + ttgStr = None if self.soc != socnum and (diffSoc > 0 or utils.TIME_TO_SOC_INC_FROM is True): secondstogo = int(diffSoc / crntPrctPerSec) From af4ec01dc718bb072894465472df0fb4d1eb6b5f Mon Sep 17 00:00:00 2001 From: Manuel Date: Sun, 23 Jul 2023 21:45:48 +0200 Subject: [PATCH 4/4] added current average of last 5 minutes --- CHANGELOG.md | 4 +- etc/dbus-serialbattery/battery.py | 8 +-- etc/dbus-serialbattery/dbushelper.py | 61 ++++++++++++++++------ etc/dbus-serialbattery/qml/PageBattery.qml | 6 +++ etc/dbus-serialbattery/utils.py | 2 +- 5 files changed, 61 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4e73afc..1762738d 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: Current average of the last 5 minutes 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 @@ -12,7 +13,6 @@ * Added: Temperature names to dbus and mqtt by @mr-manuel * Added: Use current average of the last 300 cycles for time to go and time to SoC calculation 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: Calculate only positive Time-to-SoC points 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 @@ -25,6 +25,8 @@ * 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 & @ogurevich +* Changed: Time-to-Go and Time-to-SoC use the current average of the last 5 minutes for calculation by @mr-manuel +* Changed: Time-to-SoC calculate only positive points by @mr-manuel * 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 a89a4744..b6111786 100644 --- a/etc/dbus-serialbattery/battery.py +++ b/etc/dbus-serialbattery/battery.py @@ -260,10 +260,12 @@ def prepare_voltage_management(self) -> None: or utils.BULK_AFTER_DAYS < bulk_last_reached_days_ago ) ): + """ logger.info( f"set bulk_requested to True: first time (0) or {utils.BULK_AFTER_DAYS}" + f" < {round(bulk_last_reached_days_ago, 2)}" ) + """ self.bulk_requested = True self.bulk_battery_voltage = round(utils.BULK_CELL_VOLTAGE * self.cell_count, 2) @@ -396,7 +398,7 @@ def manage_charge_voltage_linear(self) -> None: chargeMode = "Float" # reset bulk when going into float if self.bulk_requested: - logger.info("set bulk_requested to False") + # logger.info("set bulk_requested to False") self.bulk_requested = False # IDEA: Save "bulk_last_reached" in the dbus path com.victronenergy.settings # to make it restart persistent @@ -436,7 +438,7 @@ def manage_charge_voltage_linear(self) -> None: self.charge_mode += " (Linear Mode)" # uncomment for enabling debugging infos in GUI - # """ + """ self.charge_mode_debug = ( f"max_battery_voltage: {round(self.max_battery_voltage, 2)}V" ) @@ -550,7 +552,7 @@ def manage_charge_voltage_step(self) -> None: self.charge_mode = "Float" # reset bulk when going into float if self.bulk_requested: - logger.info("set bulk_requested to False") + # logger.info("set bulk_requested to False") self.bulk_requested = False self.bulk_last_reached = current_time diff --git a/etc/dbus-serialbattery/dbushelper.py b/etc/dbus-serialbattery/dbushelper.py index a564141e..3266665f 100644 --- a/etc/dbus-serialbattery/dbushelper.py +++ b/etc/dbus-serialbattery/dbushelper.py @@ -315,6 +315,12 @@ def setup_vedbus(self): # Create TimeToGo item if utils.TIME_TO_GO_ENABLE: self._dbusservice.add_path("/TimeToGo", None, writeable=True) + self._dbusservice.add_path( + "/CurrentAvg", + None, + writeable=True, + gettextcallback=lambda p, v: "{:0.2f}A".format(v), + ) # Create TimeToSoc items if len(utils.TIME_TO_SOC_POINTS) > 0: @@ -592,6 +598,20 @@ def publish_dbus(self): if len(self.battery.current_avg_lst) > 300: del self.battery.current_avg_lst[0] + """ + logger.info( + str(self.battery.capacity) + + " - " + + str(utils.TIME_TO_GO_ENABLE) + + " - " + + str(len(utils.TIME_TO_SOC_POINTS)) + + " - " + + str(int(time()) - self.battery.time_to_soc_update) + + " - " + + str(utils.TIME_TO_SOC_RECALCULATE_EVERY) + ) + """ + if ( self.battery.capacity is not None and (utils.TIME_TO_GO_ENABLE or len(utils.TIME_TO_SOC_POINTS) > 0) @@ -608,30 +628,35 @@ def publish_dbus(self): 2, ) + self._dbusservice["/CurrentAvg"] = self.battery.current_avg + crntPrctPerSec = ( abs(self.battery.current_avg / (self.battery.capacity / 100)) / 3600 ) # Update TimeToGo item if utils.TIME_TO_GO_ENABLE: - # Update TimeToGo item, has to be a positive int since it's used from dbus-systemcalc-py - self._dbusservice["/TimeToGo"] = ( - abs( - int( - self.battery.get_timeToSoc( - # switch value depending on charging/discharging - utils.SOC_LOW_WARNING - if self.battery.current_avg < 0 - else 100, - crntPrctPerSec, - True, + if self.battery.current_avg is not None: + # Update TimeToGo item, has to be a positive int since it's used from dbus-systemcalc-py + self._dbusservice["/TimeToGo"] = ( + abs( + int( + self.battery.get_timeToSoc( + # switch value depending on charging/discharging + utils.SOC_LOW_WARNING + if self.battery.current_avg < 0 + else 100, + crntPrctPerSec, + True, + ) ) ) + if self.battery.current_avg + and abs(self.battery.current_avg) > 0.1 + else None ) - if self.battery.current_avg - and abs(self.battery.current_avg) > 0.1 - else None - ) + else: + self._dbusservice["/TimeToGo"] = None # Update TimeToSoc items if len(utils.TIME_TO_SOC_POINTS) > 0: @@ -643,6 +668,12 @@ def publish_dbus(self): ) except Exception: + exception_type, exception_object, exception_traceback = sys.exc_info() + file = exception_traceback.tb_frame.f_code.co_filename + line = exception_traceback.tb_lineno + logger.error( + f"Exception occurred: {repr(exception_object)} of type {exception_type} in {file} line #{line}" + ) pass if self.battery.soc is not None: diff --git a/etc/dbus-serialbattery/qml/PageBattery.qml b/etc/dbus-serialbattery/qml/PageBattery.qml index 286ce74c..ea7b44f5 100644 --- a/etc/dbus-serialbattery/qml/PageBattery.qml +++ b/etc/dbus-serialbattery/qml/PageBattery.qml @@ -94,6 +94,12 @@ MbPage { ] } + MbItemValue { + description: qsTr("Current (last 5 minutes avg.)") + item.bind: service.path("/CurrentAvg") + show: item.seen + } + MbItemValue { id: soc diff --git a/etc/dbus-serialbattery/utils.py b/etc/dbus-serialbattery/utils.py index 73bab00a..081ee930 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.20230717dev" +DRIVER_VERSION = "1.0.20230723dev" zero_char = chr(48) degree_sign = "\N{DEGREE SIGN}"