From 1fffdafcda0026c07b39bdb484ec8c1cff153668 Mon Sep 17 00:00:00 2001 From: Manuel Date: Sun, 25 Jun 2023 12:20:08 +0200 Subject: [PATCH] added debug and error information for CVL --- etc/dbus-serialbattery/battery.py | 79 +++++++++++++------ etc/dbus-serialbattery/config.default.ini | 12 ++- etc/dbus-serialbattery/dbushelper.py | 2 + .../qml/PageBatteryParameters.qml | 9 +++ etc/dbus-serialbattery/utils.py | 16 ++-- 5 files changed, 84 insertions(+), 34 deletions(-) diff --git a/etc/dbus-serialbattery/battery.py b/etc/dbus-serialbattery/battery.py index d92500fd..4a6c7495 100644 --- a/etc/dbus-serialbattery/battery.py +++ b/etc/dbus-serialbattery/battery.py @@ -111,6 +111,7 @@ def init_values(self): self.transition_start_time = None self.control_voltage_at_transition_start = None self.charge_mode = None + self.charge_mode_debug = "" self.charge_limitation = None self.discharge_limitation = None self.linear_cvl_last_set = 0 @@ -250,6 +251,7 @@ def manage_charge_voltage_linear(self) -> None: voltageSum = 0 penaltySum = 0 tDiff = 0 + current_time = int(time()) try: # calculate battery sum @@ -273,7 +275,7 @@ def manage_charge_voltage_linear(self) -> None: and voltageDiff <= utils.CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL and self.allow_max_voltage ): - self.max_voltage_start_time = int(time()) + self.max_voltage_start_time = current_time # allow max voltage again, if cells are unbalanced or SoC threshold is reached elif ( @@ -281,13 +283,24 @@ def manage_charge_voltage_linear(self) -> None: or voltageDiff >= utils.CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT ) and not self.allow_max_voltage: self.allow_max_voltage = True + else: + pass + 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: + tDiff = current_time - self.max_voltage_start_time + # keep max voltage for MAX_VOLTAGE_TIME_SEC more seconds + if utils.MAX_VOLTAGE_TIME_SEC < tDiff: self.allow_max_voltage = False self.max_voltage_start_time = None + if self.soc <= utils.SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT: + # write to log, that reset to float was not possible + logger.error( + f"Could not change to float voltage. Battery SoC ({self.soc}%) is lower" + + f" than SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT ({utils.SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT}%)." + + " Please reset SoC manually or lower the SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT in the" + + ' "config.ini".' + ) + # 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: @@ -311,20 +324,8 @@ def manage_charge_voltage_linear(self) -> None: self.charge_mode = ( "Bulk dynamic" - # + " (vS: " - # + str(round(voltageSum, 2)) - # + " - pS: " - # + str(round(penaltySum, 2)) - # + ")" if self.max_voltage_start_time is None else "Absorption dynamic" - # + "(vS: " - # + str(round(voltageSum, 2)) - # + " tDiff: " - # + str(tDiff) - # + " pS: " - # + str(round(penaltySum, 2)) - # + ")" ) elif self.allow_max_voltage: @@ -341,19 +342,20 @@ def manage_charge_voltage_linear(self) -> None: chargeMode = "Float" if self.control_voltage: if not self.charge_mode.startswith("Float"): - self.transition_start_time = int(time()) + self.transition_start_time = current_time self.initial_control_voltage = self.control_voltage chargeMode = "Float Transition" elif self.charge_mode.startswith("Float Transition"): - current_time = int(time()) elapsed_time = current_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, + # Voltage reduction per second + VOLTAGE_REDUCTION_PER_SECOND = 0.01 / 10 + voltage_reduction = min( + VOLTAGE_REDUCTION_PER_SECOND * elapsed_time, self.initial_control_voltage - floatVoltage, ) - self.set_cvl_linear(self.initial_control_voltage - voltage_drop) + self.set_cvl_linear( + self.initial_control_voltage - voltage_reduction + ) if self.control_voltage <= floatVoltage: self.control_voltage = floatVoltage chargeMode = "Float" @@ -372,6 +374,35 @@ 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" + ) + self.charge_mode_debug += ( + f" - VOLTAGE_DROP: {round(utils.VOLTAGE_DROP, 2)}V" + ) + self.charge_mode_debug += f"\nvoltageSum: {round(voltageSum, 2)}V" + self.charge_mode_debug += f" • voltageDiff: {round(voltageDiff, 3)}V" + self.charge_mode_debug += ( + f"\ncontrol_voltage: {round(self.control_voltage, 2)}V" + ) + self.charge_mode_debug += f" • penaltySum: {round(penaltySum, 3)}V" + self.charge_mode_debug += f"\ntDiff: {tDiff}/{utils.MAX_VOLTAGE_TIME_SEC}" + self.charge_mode_debug += f" • SoC: {self.soc}%" + self.charge_mode_debug += ( + f" • Reset SoC: {utils.SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT}%" + ) + self.charge_mode_debug += f"\nallow_max_voltage: {self.allow_max_voltage}" + self.charge_mode_debug += ( + f"\nmax_voltage_start_time: {self.max_voltage_start_time}" + ) + self.charge_mode_debug += f"\ncurrent_time: {current_time}" + self.charge_mode_debug += ( + f"\nlinear_cvl_last_set: {self.linear_cvl_last_set}" + ) + """ + except TypeError: self.control_voltage = None self.charge_mode = "--" diff --git a/etc/dbus-serialbattery/config.default.ini b/etc/dbus-serialbattery/config.default.ini index 59dc3be0..5466b1d3 100644 --- a/etc/dbus-serialbattery/config.default.ini +++ b/etc/dbus-serialbattery/config.default.ini @@ -76,11 +76,15 @@ CELL_VOLTAGE_DIFF_KEEP_MAX_VOLTAGE_UNTIL = 0.010 ; e.g. 3.2 V * 5 / 100 = 0.160 V CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT = 0.080 -; -- CVL reset based on SoC option (step mode) -; Specify how long the max voltage should be kept, if reached then switch to float voltage +; -- CVL reset based on SoC option (step mode & linear mode) +; Specify how long the max voltage should be kept +; Step mode: If reached then switch to float voltage +; Linear mode: If cells are balanced keep max voltage for further MAX_VOLTAGE_TIME_SEC seconds MAX_VOLTAGE_TIME_SEC = 900 -; Specify SoC where CVL limit is reset to max voltage, if value gets below -SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT = 90 +; Specify SoC where CVL limit is reset to max voltage +; Step mode: If SoC gets below +; Linear mode: If cells are unbalanced or if SoC gets below +SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT = 80 ; --------- Cell Voltage Current limitation (affecting CCL/DCL) --------- diff --git a/etc/dbus-serialbattery/dbushelper.py b/etc/dbus-serialbattery/dbushelper.py index cec1148d..12102411 100644 --- a/etc/dbus-serialbattery/dbushelper.py +++ b/etc/dbus-serialbattery/dbushelper.py @@ -133,6 +133,7 @@ def setup_vedbus(self): ) self._dbusservice.add_path("/Info/ChargeMode", None, writeable=True) + self._dbusservice.add_path("/Info/ChargeModeDebug", None, writeable=True) self._dbusservice.add_path("/Info/ChargeLimitation", None, writeable=True) self._dbusservice.add_path("/Info/DischargeLimitation", None, writeable=True) @@ -477,6 +478,7 @@ def publish_dbus(self): # Voltage and charge control info self._dbusservice["/Info/ChargeMode"] = self.battery.charge_mode + self._dbusservice["/Info/ChargeModeDebug"] = self.battery.charge_mode_debug self._dbusservice["/Info/ChargeLimitation"] = self.battery.charge_limitation self._dbusservice[ "/Info/DischargeLimitation" diff --git a/etc/dbus-serialbattery/qml/PageBatteryParameters.qml b/etc/dbus-serialbattery/qml/PageBatteryParameters.qml index b95161a3..c402e446 100644 --- a/etc/dbus-serialbattery/qml/PageBatteryParameters.qml +++ b/etc/dbus-serialbattery/qml/PageBatteryParameters.qml @@ -6,6 +6,8 @@ MbPage { property variant service + property VBusItem chargeModeDebug: VBusItem { bind: service.path("/Info/ChargeModeDebug") } + model: VisibleItemModel { MbItemValue { @@ -14,6 +16,13 @@ MbPage { show: item.valid } + // show debug informations + MbItemText { + text: chargeModeDebug.value + wrapMode: Text.WordWrap + show: chargeModeDebug.value != "" + } + MbItemValue { description: qsTr("Charge Voltage Limit (CVL)") item.bind: service.path("/Info/MaxChargeVoltage") diff --git a/etc/dbus-serialbattery/utils.py b/etc/dbus-serialbattery/utils.py index fb7a93fd..46771a25 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.20230620dev" +DRIVER_VERSION = "1.0.20230625dev" zero_char = chr(48) degree_sign = "\N{DEGREE SIGN}" @@ -127,11 +127,15 @@ def _get_list_from_config( config["DEFAULT"]["CELL_VOLTAGE_DIFF_TO_RESET_VOLTAGE_LIMIT"] ) -# -- CVL Reset based on SoC option -# Specify how long the max voltage should be kept, if reached then switch to float voltage -MAX_VOLTAGE_TIME_SEC = float(config["DEFAULT"]["MAX_VOLTAGE_TIME_SEC"]) -# Specify SoC where CVL limit is reset to max voltage, if value gets below -SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT = float( +# -- CVL reset based on SoC option (step mode & linear mode) +# Specify how long the max voltage should be kept +# Step mode: If reached then switch to float voltage +# Linear mode: If cells are balanced keep max voltage for further MAX_VOLTAGE_TIME_SEC seconds +MAX_VOLTAGE_TIME_SEC = int(config["DEFAULT"]["MAX_VOLTAGE_TIME_SEC"]) +# Specify SoC where CVL limit is reset to max voltage +# Step mode: If SoC gets below +# Linear mode: If cells are unbalanced or if SoC gets below +SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT = int( config["DEFAULT"]["SOC_LEVEL_TO_RESET_VOLTAGE_LIMIT"] )