diff --git a/docs/Neues Modul programmieren.md b/docs/Neues Modul programmieren.md index e76061d3a8..98e6159a20 100644 --- a/docs/Neues Modul programmieren.md +++ b/docs/Neues Modul programmieren.md @@ -35,7 +35,7 @@ Bei Hybrid-Systemen erfolgt die Verrechnung von Speicher-und PV-Leistung automat #### Schnittstelle für die Speicher-Steuerung -Bei Speichern, die eine aktive Steuerung unterstützen, kann mit der Methode `set_power_limit` die Speicherleistung gesetzt werden. Die Speicher erben von der Klasse `AbstractBat`, die die abstrakte Methode `set_power_limit` beinhaltet. Bei der Implementierung des Speichers kannst Du diese Methode überschreiben. Die Regelung prüft am Ende, ob die Methode für den jeweiligen Speicher implementiert ist und ruft diese auf. Als Variable wird die Speicherleistung in Watt oder `None` übergeben, dann wird der Speicher nicht mehr aktiv von der openWB gesteuert und soll selbst anhand des EVU-Punktes regeln. +Ob ein Speicher die aktive Speichersteuerung unterstützt, wird in der Methode `power_limit_controllable` implementiert. Ist diese Methode nicht im Speicher implementiert, wird die Methode aus der geerbten Klasse `AbstractBat` aufgerufen und die Steuerbarkeit auf `False` gesetzt. Bei Speichern, die eine aktive Steuerung unterstützen, kann mit der Methode `set_power_limit` die Speicherleistung gesetzt werden. Als Variable wird die Speicherleistung in Watt oder `None` übergeben, dann wird der Speicher nicht mehr aktiv von der openWB gesteuert und soll selbst anhand des EVU-Punktes regeln. ### Neues Fahrzeug programmieren diff --git a/docs/samples/sample_modbus/bat.py b/docs/samples/sample_modbus/bat.py index eaee6a3f48..3f8a9642a2 100644 --- a/docs/samples/sample_modbus/bat.py +++ b/docs/samples/sample_modbus/bat.py @@ -33,11 +33,16 @@ def update(self) -> None: self.store.set(bat_state) def set_power_limit(self, power_limit: Optional[int]) -> None: - # Methode entfernen, falls der Speicher keine Steuerung der Ladeleistung unterstützt # Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss bei Übergabe einer Zahl auf aktive # Speichersteurung umgeschaltet werden, sodass der Speicher mit der übergebenen Leistung lädt/entlädt. Wird # None übergeben, muss der Speicher die Null-Punkt-Ausregelung selbst übernehmen. self.client.write_registers(reg, power_limit) + # Wenn der Speicher keine Steuerung der Ladeleistung unterstützt + pass + + def power_limit_controllable(self) -> bool: + # Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss True zurückgegeben werden. + return True component_descriptor = ComponentDescriptor(configuration_factory=SampleBatSetup) diff --git a/docs/samples/sample_request_by_component/bat.py b/docs/samples/sample_request_by_component/bat.py index 0623ba06c7..a435f67fda 100644 --- a/docs/samples/sample_request_by_component/bat.py +++ b/docs/samples/sample_request_by_component/bat.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +from typing import Optional from dataclass_utils import dataclass_from_dict from modules.common import req from modules.common.abstract_device import AbstractBat @@ -31,5 +32,17 @@ def update(self) -> None: ) self.store.set(bat_state) + def set_power_limit(self, power_limit: Optional[int]) -> None: + # Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss bei Übergabe einer Zahl auf aktive + # Speichersteurung umgeschaltet werden, sodass der Speicher mit der übergebenen Leistung lädt/entlädt. Wird + # None übergeben, muss der Speicher die Null-Punkt-Ausregelung selbst übernehmen. + self.client.write_registers(reg, power_limit) + # Wenn der Speicher keine Steuerung der Ladeleistung unterstützt + pass + + def power_limit_controllable(self) -> bool: + # Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss True zurückgegeben werden. + return True + component_descriptor = ComponentDescriptor(configuration_factory=SampleBatSetup) diff --git a/docs/samples/sample_request_by_device/bat.py b/docs/samples/sample_request_by_device/bat.py index 8c84673029..469d1e5f46 100644 --- a/docs/samples/sample_request_by_device/bat.py +++ b/docs/samples/sample_request_by_device/bat.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +from typing import Optional from dataclass_utils import dataclass_from_dict from modules.common.abstract_device import AbstractBat from modules.common.component_state import BatState @@ -29,5 +30,17 @@ def update(self, response) -> None: ) self.store.set(bat_state) + def set_power_limit(self, power_limit: Optional[int]) -> None: + # Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss bei Übergabe einer Zahl auf aktive + # Speichersteurung umgeschaltet werden, sodass der Speicher mit der übergebenen Leistung lädt/entlädt. Wird + # None übergeben, muss der Speicher die Null-Punkt-Ausregelung selbst übernehmen. + self.client.write_registers(reg, power_limit) + # Wenn der Speicher keine Steuerung der Ladeleistung unterstützt + pass + + def power_limit_controllable(self) -> bool: + # Wenn der Speicher die Steuerung der Ladeleistung unterstützt, muss True zurückgegeben werden. + return True + component_descriptor = ComponentDescriptor(configuration_factory=SampleBatSetup) diff --git a/packages/control/bat_all.py b/packages/control/bat_all.py index c58c8a396c..c84cd5aed0 100644 --- a/packages/control/bat_all.py +++ b/packages/control/bat_all.py @@ -346,6 +346,6 @@ def get_controllable_bat_components() -> List: if isinstance(value, AbstractDevice): for comp_value in value.components.values(): if "bat" in comp_value.component_config.type: - if "set_power_limit" in type(comp_value).__dict__: + if comp_value.power_limit_controllable(): bat_components.append(comp_value) return bat_components diff --git a/packages/modules/common/abstract_device.py b/packages/modules/common/abstract_device.py index 88f33e90b7..7956a7d59f 100644 --- a/packages/modules/common/abstract_device.py +++ b/packages/modules/common/abstract_device.py @@ -30,6 +30,9 @@ def set_power_limit(self, power_limit: Optional[int]) -> None: # power limit None heißt, auf maximale Speicherleistung setzen = Speicher-Begrenzung aufheben pass + def power_limit_controllable(self) -> bool: + return False + class AbstractCounter: @abstractmethod diff --git a/packages/modules/devices/generic/mqtt/bat.py b/packages/modules/devices/generic/mqtt/bat.py index 5f518c26e7..252a1483f4 100644 --- a/packages/modules/devices/generic/mqtt/bat.py +++ b/packages/modules/devices/generic/mqtt/bat.py @@ -18,5 +18,8 @@ def set_power_limit(self, power_limit: Optional[int]) -> None: # ob der Speicher die Funktion bietet pass + def power_limit_controllable(self) -> bool: + return self.component_config.configuration.power_limit_controllable + component_descriptor = ComponentDescriptor(configuration_factory=MqttBatSetup) diff --git a/packages/modules/devices/generic/mqtt/config.py b/packages/modules/devices/generic/mqtt/config.py index cda7d72ca0..aa14d4ad4b 100644 --- a/packages/modules/devices/generic/mqtt/config.py +++ b/packages/modules/devices/generic/mqtt/config.py @@ -22,8 +22,8 @@ def __init__(self, class MqttBatConfiguration: - def __init__(self): - pass + def __init__(self, power_limit_controllable: bool = False): + self.power_limit_controllable = power_limit_controllable class MqttBatSetup(ComponentSetup[MqttBatConfiguration]):