diff --git a/packages/control/bat_all.py b/packages/control/bat_all.py index d1085b0d2b..676ca7fd03 100644 --- a/packages/control/bat_all.py +++ b/packages/control/bat_all.py @@ -78,6 +78,7 @@ class Set: charging_power_left: float = field(default=0, metadata={"topic": "set/charging_power_left"}) power_limit: Optional[float] = field(default=None, metadata={"topic": "set/power_limit"}) regulate_up: bool = field(default=False, metadata={"topic": "set/regulate_up"}) + hysteresis_discharge: bool = field(default=False, metadata={"topic": "set/hysteresis_discharge"}) def set_factory() -> Set: @@ -214,7 +215,9 @@ def _get_charging_power_left(self): # Speicher sollte weder ge- noch entladen werden. charging_power_left = self.data.get.power else: + # Speicher soll geladen werden um min SoC zu erreichen if self.data.get.soc < config.min_bat_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 @@ -235,10 +238,30 @@ def _get_charging_power_left(self): # Speicher wird geladen charging_power_left = 0 self.data.set.regulate_up = True - elif int(self.data.get.soc) == config.min_bat_soc: - # Speicher sollte weder ge- noch entladen werden, um den Mindest-SoC zu halten. - charging_power_left = self.data.get.power + # Speicher zwischen min und max SoC + elif int(self.data.get.soc) >= config.min_bat_soc and int(self.data.get.soc) < config.max_bat_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 darf wegen Hysterese bis min_bat_soc entladen werden. + else: + if self.data.set.power_limit is None: + if config.bat_power_discharge_active: + # Wenn der Speicher mit mehr als der erlaubten Entladeleistung entladen wird, muss das + # vom Überschuss subtrahiert werden. + charging_power_left = config.bat_power_discharge + self.data.get.power + log.debug(f"Erlaubte Entlade-Leistung nutzen {charging_power_left}W") + else: + # Speicher sollte weder ge- noch entladen werden. + charging_power_left = self.data.get.power + else: + log.debug("Keine erlaubte Entladeleistung freigeben, da der Speicher mit einer vorgegeben " + "Leistung entladen wird.") + charging_power_left = 0 + # Speicher oberhalb max SoC. Darf bis min SoC entladen werden. else: + self.data.set.hysteresis_discharge = True if self.data.set.power_limit is None: if config.bat_power_discharge_active: # Wenn der Speicher mit mehr als der erlaubten Entladeleistung entladen wird, muss das diff --git a/packages/control/bat_all_test.py b/packages/control/bat_all_test.py index 2256629529..1429cdd1ad 100644 --- a/packages/control/bat_all_test.py +++ b/packages/control/bat_all_test.py @@ -80,6 +80,7 @@ class Params: expected_charging_power_left: float expected_regulate_up: bool power_limit: Optional[float] = None + hysteresis_discharge: Optional[bool] = False cases = [ @@ -128,6 +129,14 @@ class Params: "Speicher-Sperre aktiv"), PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True), 400, 90, 0, False, 600), + Params(("Mindest-SoC, Hysterese, EV-Vorrang, keine Speichernutzung"), + PvCharging(bat_mode="min_soc_bat_mode"), 400, 60, 400, False, hysteresis_discharge=False), + Params(("Mindest-SoC, Hysterese, Speicherentladung, Speichernutzung erlaubt"), + PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True), + 400, 60, 900, False, hysteresis_discharge=True), + Params(("Mindest-SoC, Hysterese, Speicherentladung, Speichernutzung erlaubt, Speicher-Sperre aktiv"), + PvCharging(bat_mode="min_soc_bat_mode", bat_power_discharge=500, bat_power_discharge_active=True), + 400, 60, 0, False, 600, hysteresis_discharge=True), ] @@ -138,6 +147,7 @@ def test_get_charging_power_left(params: Params, caplog, data_, monkeypatch): b_all.data.get.power = params.power b_all.data.get.soc = params.soc b_all.data.set.power_limit = params.power_limit + b_all.data.set.hysteresis_discharge = params.hysteresis_discharge b = Bat(0) b.data.get.power = params.power data.data.bat_data["bat0"] = b diff --git a/packages/control/general.py b/packages/control/general.py index 95253b3b2f..52d8bf7a7e 100644 --- a/packages/control/general.py +++ b/packages/control/general.py @@ -34,6 +34,8 @@ class PvCharging: "topic": "chargemode_config/pv_charging/bat_power_discharge_active"}) min_bat_soc: int = field(default=50, metadata={ "topic": "chargemode_config/pv_charging/min_bat_soc"}) + max_bat_soc: int = field(default=70, metadata={ + "topic": "chargemode_config/pv_charging/max_bat_soc"}) bat_mode: BatConsiderationMode = field(default=BatConsiderationMode.EV_MODE.value, metadata={ "topic": "chargemode_config/pv_charging/bat_mode"}) switch_off_delay: int = field(default=60, metadata={ diff --git a/packages/helpermodules/update_config.py b/packages/helpermodules/update_config.py index 74bd16464b..75d1fd5f3f 100644 --- a/packages/helpermodules/update_config.py +++ b/packages/helpermodules/update_config.py @@ -57,7 +57,7 @@ class UpdateConfig: - DATASTORE_VERSION = 99 + DATASTORE_VERSION = 100 valid_topic = [ "^openWB/bat/config/bat_control_permitted$", @@ -233,6 +233,7 @@ class UpdateConfig: "^openWB/general/chargemode_config/phase_switch_delay$", "^openWB/general/chargemode_config/pv_charging/control_range$", "^openWB/general/chargemode_config/pv_charging/min_bat_soc$", + "^openWB/general/chargemode_config/pv_charging/max_bat_soc$", "^openWB/general/chargemode_config/pv_charging/bat_power_discharge$", "^openWB/general/chargemode_config/pv_charging/bat_power_discharge_active$", "^openWB/general/chargemode_config/pv_charging/bat_power_reserve$", @@ -536,6 +537,7 @@ class UpdateConfig: ("openWB/general/chargemode_config/pv_charging/bat_power_discharge", 1000), ("openWB/general/chargemode_config/pv_charging/bat_power_discharge_active", True), ("openWB/general/chargemode_config/pv_charging/min_bat_soc", 50), + ("openWB/general/chargemode_config/pv_charging/max_bat_soc", 70), ("openWB/general/chargemode_config/pv_charging/bat_power_reserve", 200), ("openWB/general/chargemode_config/pv_charging/bat_power_reserve_active", True), ("openWB/general/chargemode_config/pv_charging/control_range", [0, 230]), @@ -2588,3 +2590,13 @@ def upgrade_datastore_98(self) -> None: MessageType.INFO, ) self.__update_topic("openWB/system/datastore_version", 99) + + def upgrade_datastore_99(self) -> None: + # bei Aktualisierung den max_bat_soc auf min_bat_soc setzen + # Regelung verhält sich dadurch wie bisher konfiguriert + # max_bat_soc kann nicht kleiner als min_bat_soc werden + min_bat_soc = decode_payload(self.all_received_topics[ + "openWB/general/chargemode_config/pv_charging/min_bat_soc"]) + + self.__update_topic("openWB/general/chargemode_config/pv_charging/max_bat_soc", min_bat_soc) + self.__update_topic("openWB/system/datastore_version", 100)