From aad5dfd6013dc70639e789c040decb081af88a64 Mon Sep 17 00:00:00 2001 From: seaspotter Date: Sun, 20 Sep 2026 13:05:15 +0200 Subject: [PATCH 1/2] bat_all: restore Speicher-Vorrang beim Erholen von Mindest-SoC bis Maximal-SoC --- packages/control/bat_all.py | 51 ++++++++++++++++++++------------ packages/control/bat_all_test.py | 9 ++++-- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/packages/control/bat_all.py b/packages/control/bat_all.py index c1939c2187..6f6c5faf26 100644 --- a/packages/control/bat_all.py +++ b/packages/control/bat_all.py @@ -318,6 +318,31 @@ def setup_bat(self): except Exception: log.exception("Fehler im Bat-Modul") + def _charging_power_left_while_recovering(self, config) -> float: + """ Speicher-Vorrang, waehrend sich der Speicher auf dem Weg zum naechsten SoC-Ziel befindet + (unterhalb Mindest-SoC, oder oberhalb Mindest-SoC aber noch nicht wieder beim Maximal-SoC + angekommen, hysteresis_discharge=False): ermittelt, wie viel Leistung den Fahrzeugen dabei + verbleibt, unter Beruecksichtigung einer optional reservierten Ladeleistung. + """ + if self.data.get.power < 0: + # Wenn der Speicher entladen wird, darf diese Leistung nicht zum Laden der Fahrzeuge + # genutzt werden. Wenn der Speicher schneller regelt als die LP, würde sonst der Speicher + # reduziert werden. + charging_power_left = self.data.get.power + self.data.set.regulate_up = True + else: + if config.power_reserve_active: + # Die Differenz zwischen aktueller Batterie-Leistung und Reserveleistung bestimmt, + # was fuer EV-Ladung verbleibt (positiv) oder zusaetzlich benoetigt wird (negativ). + charging_power_left = self.data.get.power - config.power_reserve + if charging_power_left < 0: + self.data.set.regulate_up = True + else: + # Speicher wird geladen + charging_power_left = 0 + self.data.set.regulate_up = True + return charging_power_left + def get_charging_power_left_diff(self): """Ermittelt die Differenz zur aktuellen Batterie-Leistung, die zum Laden der EV verwendet werden darf. @@ -349,30 +374,18 @@ def get_charging_power_left_diff(self): # Speicher soll geladen werden um min SoC zu erreichen if self.data.get.soc < config.min_soc: self.data.set.hysteresis_discharge = False - if self.data.get.power < 0: - # Wenn der Speicher entladen wird, darf diese Leistung nicht zum Laden der Fahrzeuge - # genutzt werden. Wenn der Speicher schneller regelt als die LP, würde sonst der Speicher - # reduziert werden. - charging_power_left = self.data.get.power - self.data.set.regulate_up = True - else: - # Speicher-Vorrang bis zum Min-Soc - if config.power_reserve_active: - # Die Differenz zwischen aktueller Batterie-Leistung und Reserveleistung bestimmt, - # was fuer EV-Ladung verbleibt (positiv) oder zusaetzlich benoetigt wird (negativ). - charging_power_left = self.data.get.power - config.power_reserve - if charging_power_left < 0: - self.data.set.regulate_up = True - else: - # Speicher wird geladen - charging_power_left = 0 - self.data.set.regulate_up = True + charging_power_left = self._charging_power_left_while_recovering(config) # Speicher zwischen min und max SoC elif int(self.data.get.soc) >= config.min_soc and int(self.data.get.soc) < config.max_soc: # Speicher soll aktiv weder ge- noch entladen werden. # Mindest-SoC wird gehalten oder der Speicher mit weiterem vorhanden Überschuss geladen. if self.data.set.hysteresis_discharge is False: - charging_power_left = self.data.get.power + # Speicher befindet sich noch in der Erholung nach Unterschreiten des Mindest-SoC: + # Vorrang fuer den Speicher bis zum Erreichen des Maximal-SoC (hysteresis_discharge + # wird erst dort wieder True), analog zum Zweig unterhalb des Mindest-SoC - sonst + # bleibt der Speicher dauerhaft knapp oberhalb des Mindest-SoC haengen, weil die + # Hysterese nie zurueckgesetzt wird. + charging_power_left = self._charging_power_left_while_recovering(config) # Speicher darf wegen Hysterese bis min_soc entladen werden. else: if self.data.set.power_limit is None: diff --git a/packages/control/bat_all_test.py b/packages/control/bat_all_test.py index 4f0a6f7cbe..2b2ed13843 100644 --- a/packages/control/bat_all_test.py +++ b/packages/control/bat_all_test.py @@ -156,8 +156,13 @@ class Params: "Speicher-Sperre aktiv"), ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True), 400, 90, 0, False, 600), - Params(("Mindest-SoC, Hysterese, EV-Vorrang, keine Speichernutzung"), - ChargemodeConfigBat(mode="min_soc_bat_mode"), 400, 60, 400, False, hysteresis_discharge=False), + Params(("Mindest-SoC, Hysterese, Erholung nach Unterschreiten, Speicher-Vorrang bis Maximal-SoC"), + ChargemodeConfigBat(mode="min_soc_bat_mode"), 400, 60, -100, True, hysteresis_discharge=False), + Params(("Mindest-SoC, Hysterese, Erholung nach Unterschreiten, Speicher-Reserve aktiv"), + ChargemodeConfigBat(mode="min_soc_bat_mode", power_reserve=2000, power_reserve_active=True), + 2200, 60, 200, False, hysteresis_discharge=False), + Params(("Mindest-SoC, Hysterese, Erholung nach Unterschreiten, Speicher entlädt noch"), + ChargemodeConfigBat(mode="min_soc_bat_mode"), -300, 60, -400, True, hysteresis_discharge=False), Params(("Mindest-SoC, Hysterese, Speicherentladung, Speichernutzung erlaubt"), ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True), 400, 60, 900, False, hysteresis_discharge=True), From 763cc501563086d3d79d2a298964d67ccb4560dc Mon Sep 17 00:00:00 2001 From: seaspotter Date: Tue, 22 Sep 2026 20:16:55 +0200 Subject: [PATCH 2/2] bat_all: Speicherleistung nicht ans Fahrzeug weitergeben, wenn Entladung nicht erlaubt ist --- packages/control/bat_all.py | 12 ++++++++---- packages/control/bat_all_test.py | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/packages/control/bat_all.py b/packages/control/bat_all.py index 6f6c5faf26..af3cab264e 100644 --- a/packages/control/bat_all.py +++ b/packages/control/bat_all.py @@ -417,8 +417,10 @@ def get_charging_power_left_diff(self): absolute_bat_discharge_power) log.debug(f"Erlaubte Entlade-Leistung nutzen {charging_power_left}W") else: - # Speicher sollte weder ge- noch entladen werden. - charging_power_left = base_power + # Entladung nicht erlaubt: die eigene Speicherleistung darf nicht ans Fahrzeug + # weitergereicht werden, sonst wird der Speicher entladen, obwohl der Nutzer das + # nicht erlaubt hat. + charging_power_left = 0 else: log.debug("Keine erlaubte Entladeleistung freigeben, da der Speicher mit einer vorgegeben " "Leistung entladen wird.") @@ -454,8 +456,10 @@ def get_charging_power_left_diff(self): absolute_bat_discharge_power) log.debug(f"Erlaubte Entlade-Leistung nutzen {charging_power_left}W") else: - # Speicher sollte weder ge- noch entladen werden. - charging_power_left = base_power + # Entladung nicht erlaubt: die eigene Speicherleistung darf nicht ans Fahrzeug + # weitergereicht werden, sonst wird der Speicher entladen, obwohl der Nutzer das + # nicht erlaubt hat. + charging_power_left = 0 else: log.debug("Keine erlaubte Entladeleistung freigeben, da der Speicher mit einer vorgegeben " "Leistung entladen wird.") diff --git a/packages/control/bat_all_test.py b/packages/control/bat_all_test.py index 2b2ed13843..b877c058ac 100644 --- a/packages/control/bat_all_test.py +++ b/packages/control/bat_all_test.py @@ -128,10 +128,10 @@ class Params: Params("Mindest-SoC, SoC nicht erreicht, Speicher-Reserve ausgenutzt, Speicher lädt", ChargemodeConfigBat(mode="min_soc_bat_mode", power_reserve=2000, power_reserve_active=True), 2200, 40, 200, False), - Params("Mindest-SoC, SoC erreicht, Speicher entlädt", ChargemodeConfigBat(mode="min_soc_bat_mode"), -500, 90, -500, - False), - Params("Mindest-SoC, SoC erreicht, Speicher lädt", - ChargemodeConfigBat(mode="min_soc_bat_mode"), 500, 90, 500, False), + Params("Mindest-SoC, SoC erreicht, Entladung nicht erlaubt, Speicher entlädt trotzdem", + ChargemodeConfigBat(mode="min_soc_bat_mode"), -500, 90, 0, False), + Params("Mindest-SoC, SoC erreicht, Entladung nicht erlaubt, Speicher lädt", + ChargemodeConfigBat(mode="min_soc_bat_mode"), 500, 90, 0, False), Params("Mindest-SoC, SoC erreicht, Speicher ist voll", ChargemodeConfigBat(mode="min_soc_bat_mode"), 0, 100, 0, False), Params("Mindest-SoC, SoC erreicht, Entladung in Auto, Speicher entlädt, Entladeleistung nicht erreicht", @@ -169,6 +169,10 @@ class Params: Params(("Mindest-SoC, Hysterese, Speicherentladung, Speichernutzung erlaubt, Speicher-Sperre aktiv"), ChargemodeConfigBat(mode="min_soc_bat_mode", power_discharge=500, power_discharge_active=True), 400, 60, 0, False, 600, hysteresis_discharge=True), + Params(("Mindest-SoC, Hysterese, Entladung nicht erlaubt, Speicher entlädt trotzdem"), + ChargemodeConfigBat(mode="min_soc_bat_mode"), -500, 60, 0, False, hysteresis_discharge=True), + Params(("Mindest-SoC, Hysterese, Entladung nicht erlaubt, Speicher lädt"), + ChargemodeConfigBat(mode="min_soc_bat_mode"), 500, 60, 0, False, hysteresis_discharge=True), ]