diff --git a/packages/modules/devices/siemens/siemens_sentron/bat.py b/packages/modules/devices/siemens/siemens_sentron/bat.py new file mode 100644 index 0000000000..b1a5d39a0c --- /dev/null +++ b/packages/modules/devices/siemens/siemens_sentron/bat.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 +from typing import TypedDict, Any + +from modules.common import modbus +from modules.common.abstract_device import AbstractBat +from modules.common.component_state import BatState +from modules.common.component_type import ComponentDescriptor +from modules.common.fault_state import ComponentInfo, FaultState +from modules.common.modbus import ModbusDataType +from modules.common.store import get_bat_value_store +from modules.devices.siemens.siemens_sentron.config import SiemensSentronBatSetup + + +class KwargsDict(TypedDict): + client: modbus.ModbusTcpClient_ + modbus_id: int + + +class SiemensSentronBat(AbstractBat): + def __init__(self, component_config: SiemensSentronBatSetup, **kwargs: Any) -> None: + self.component_config = component_config + self.kwargs: KwargsDict = kwargs + + def initialize(self) -> None: + self.__tcp_client: modbus.ModbusTcpClient_ = self.kwargs['client'] + self.__modbus_id: int = self.kwargs['modbus_id'] + self.store = get_bat_value_store(self.component_config.id) + self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config)) + + def update(self) -> None: + with self.__tcp_client: + power = self.__tcp_client.read_holding_registers(65, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * -1 + imported = self.__tcp_client.read_holding_registers(801, ModbusDataType.FLOAT_64, unit=self.__modbus_id) + exported = self.__tcp_client.read_holding_registers(809, ModbusDataType.FLOAT_64, unit=self.__modbus_id) + + bat_state = BatState( + imported=imported, + exported=exported, + power=power + ) + self.store.set(bat_state) + + +component_descriptor = ComponentDescriptor(configuration_factory=SiemensSentronBatSetup) diff --git a/packages/modules/devices/siemens/siemens_sentron/config.py b/packages/modules/devices/siemens/siemens_sentron/config.py index 11f23c0b8e..b610cf47df 100644 --- a/packages/modules/devices/siemens/siemens_sentron/config.py +++ b/packages/modules/devices/siemens/siemens_sentron/config.py @@ -36,3 +36,31 @@ def __init__(self, id: int = 0, configuration: SiemensSentronCounterConfiguration = None) -> None: super().__init__(name, type, id, configuration or SiemensSentronCounterConfiguration()) + + +class SiemensSentronInverterConfiguration: + def __init__(self): + pass + + +class SiemensSentronInverterSetup(ComponentSetup[SiemensSentronInverterConfiguration]): + def __init__(self, + name: str = "Siemens Sentron PV-Zähler", + type: str = "inverter", + id: int = 0, + configuration: SiemensSentronInverterConfiguration = None) -> None: + super().__init__(name, type, id, configuration or SiemensSentronInverterConfiguration()) + + +class SiemensSentronBatConfiguration: + def __init__(self): + pass + + +class SiemensSentronBatSetup(ComponentSetup[SiemensSentronBatConfiguration]): + def __init__(self, + name: str = "Siemens Sentron Speicher-Zähler", + type: str = "bat", + id: int = 0, + configuration: SiemensSentronBatConfiguration = None) -> None: + super().__init__(name, type, id, configuration or SiemensSentronBatConfiguration()) diff --git a/packages/modules/devices/siemens/siemens_sentron/device.py b/packages/modules/devices/siemens/siemens_sentron/device.py index 5b57b33916..dfad7169fc 100644 --- a/packages/modules/devices/siemens/siemens_sentron/device.py +++ b/packages/modules/devices/siemens/siemens_sentron/device.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 import logging -from typing import Iterable +from typing import Iterable, Union from modules.common.abstract_device import DeviceDescriptor from modules.common.configurable_device import ComponentFactoryByType, ConfigurableDevice, MultiComponentUpdater from modules.common.modbus import ModbusTcpClient_ -from modules.devices.siemens.siemens_sentron.config import SiemensSentron, SiemensSentronCounterSetup -from modules.devices.siemens.siemens_sentron.counter import SiemensSentronCounter +from modules.devices.siemens.siemens_sentron.config import (SiemensSentron, SiemensSentronCounterSetup, + SiemensSentronInverterSetup, SiemensSentronBatSetup) +from modules.devices.siemens.siemens_sentron import counter, inverter, bat log = logging.getLogger(__name__) @@ -16,9 +17,21 @@ def create_device(device_config: SiemensSentron): def create_counter_component(component_config: SiemensSentronCounterSetup): nonlocal client - return SiemensSentronCounter(component_config, client=client, modbus_id=device_config.configuration.modbus_id) + return counter.SiemensSentronCounter(component_config, client=client, + modbus_id=device_config.configuration.modbus_id) - def update_components(components: Iterable[SiemensSentronCounter]): + def create_inverter_component(component_config: SiemensSentronInverterSetup): + nonlocal client + return inverter.SiemensSentronInverter(component_config, client=client, + modbus_id=device_config.configuration.modbus_id) + + def create_bat_component(component_config: SiemensSentronBatSetup): + nonlocal client + return bat.SiemensSentronBat(component_config, client=client, + modbus_id=device_config.configuration.modbus_id) + + def update_components(components: Iterable[Union[counter.SiemensSentronCounter, inverter.SiemensSentronInverter, + bat.SiemensSentronBat]]): nonlocal client with client: for component in components: @@ -33,6 +46,8 @@ def initializer(): initializer=initializer, component_factory=ComponentFactoryByType( counter=create_counter_component, + inverter=create_inverter_component, + bat=create_bat_component ), component_updater=MultiComponentUpdater(update_components) ) diff --git a/packages/modules/devices/siemens/siemens_sentron/inverter.py b/packages/modules/devices/siemens/siemens_sentron/inverter.py new file mode 100644 index 0000000000..2cd4d3c038 --- /dev/null +++ b/packages/modules/devices/siemens/siemens_sentron/inverter.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +from typing import TypedDict, Any + +from modules.common import modbus +from modules.common.abstract_device import AbstractInverter +from modules.common.component_state import InverterState +from modules.common.component_type import ComponentDescriptor +from modules.common.fault_state import ComponentInfo, FaultState +from modules.common.modbus import ModbusDataType +from modules.common.store import get_inverter_value_store +from modules.devices.siemens.siemens_sentron.config import SiemensSentronInverterSetup + + +class KwargsDict(TypedDict): + client: modbus.ModbusTcpClient_ + modbus_id: int + + +class SiemensSentronInverter(AbstractInverter): + def __init__(self, component_config: SiemensSentronInverterSetup, **kwargs: Any) -> None: + self.component_config = component_config + self.kwargs: KwargsDict = kwargs + + def initialize(self) -> None: + self.__tcp_client: modbus.ModbusTcpClient_ = self.kwargs['client'] + self.__modbus_id: int = self.kwargs['modbus_id'] + self.store = get_inverter_value_store(self.component_config.id) + self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config)) + + def update(self) -> None: + with self.__tcp_client: + power = self.__tcp_client.read_holding_registers(65, ModbusDataType.FLOAT_32, unit=self.__modbus_id) * -1 + exported = self.__tcp_client.read_holding_registers(809, ModbusDataType.FLOAT_64, unit=self.__modbus_id) + + inverter_state = InverterState( + power=power, + exported=exported + ) + self.store.set(inverter_state) + + +component_descriptor = ComponentDescriptor(configuration_factory=SiemensSentronInverterSetup)