From e5d3954012737e9f0374d6b1593fc4f4bc8bd110 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 19 Jan 2026 07:56:07 +0100 Subject: [PATCH 1/8] Add Vendor --- packages/modules/devices/solvis/vendor.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 packages/modules/devices/solvis/vendor.py diff --git a/packages/modules/devices/solvis/vendor.py b/packages/modules/devices/solvis/vendor.py new file mode 100644 index 0000000000..2adee7c9c1 --- /dev/null +++ b/packages/modules/devices/solvis/vendor.py @@ -0,0 +1,14 @@ +from pathlib import Path + +from modules.common.abstract_device import DeviceDescriptor +from modules.devices.vendors import VendorGroup + + +class Vendor: + def __init__(self): + self.type = Path(__file__).parent.name + self.vendor = "Solvis" + self.group = VendorGroup.VENDORS.value + + +vendor_descriptor = DeviceDescriptor(configuration_factory=Vendor) From 25b65a7eeaefcfab6dd10a25009b76692152c7e3 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 19 Jan 2026 07:56:40 +0100 Subject: [PATCH 2/8] Add files via upload --- packages/modules/devices/solvis/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/modules/devices/solvis/__init__.py diff --git a/packages/modules/devices/solvis/__init__.py b/packages/modules/devices/solvis/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 3980f870ed5ed76c4b2df7e695f8d75097790f44 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 19 Jan 2026 07:59:32 +0100 Subject: [PATCH 3/8] Add Solvis Counter.py --- .../modules/devices/solvis/solvis/config.py | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 packages/modules/devices/solvis/solvis/config.py diff --git a/packages/modules/devices/solvis/solvis/config.py b/packages/modules/devices/solvis/solvis/config.py new file mode 100644 index 0000000000..4ebfc8f463 --- /dev/null +++ b/packages/modules/devices/solvis/solvis/config.py @@ -0,0 +1,42 @@ +from typing import Optional +from helpermodules.auto_str import auto_str +from modules.common.component_setup import ComponentSetup +from ..vendor import vendor_descriptor + + +@auto_str +class SolvisConfiguration: + def __init__(self, ip_address: Optional[str] = None, port: int = 502, modbus_id: int = 1): + self.ip_address = ip_address + self.port = port + self.modbus_id = modbus_id + + +@auto_str +class Solvis: + def __init__(self, + name: str = "Solvis", + type: str = "solvis", + id: int = 0, + configuration: SolvisConfiguration = None) -> None: + self.name = name + self.type = type + self.vendor = vendor_descriptor.configuration_factory().type + self.id = id + self.configuration = configuration or SolvisConfiguration() + + +@auto_str +class SolvisCounterConfiguration: + def __init__(self): + pass + + +@auto_str +class SolvisCounterSetup(ComponentSetup[SolvisCounterConfiguration]): + def __init__(self, + name: str = "Solvis Zähler", + type: str = "counter", + id: int = 0, + configuration: SolvisCounterConfiguration = None) -> None: + super().__init__(name, type, id, configuration or SolvisCounterConfiguration()) From 46141ef78d466d0d36f24174f1b5def4d7cd1afb Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 19 Jan 2026 08:01:06 +0100 Subject: [PATCH 4/8] Add Solvis device.py --- .../modules/devices/solvis/solvis/device.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 packages/modules/devices/solvis/solvis/device.py diff --git a/packages/modules/devices/solvis/solvis/device.py b/packages/modules/devices/solvis/solvis/device.py new file mode 100644 index 0000000000..65568bac91 --- /dev/null +++ b/packages/modules/devices/solvis/solvis/device.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +import logging +from typing import Iterable + +from modules.common.abstract_device import DeviceDescriptor +from modules.common.component_context import SingleComponentUpdateContext +from modules.common.configurable_device import ConfigurableDevice, ComponentFactoryByType, MultiComponentUpdater +from modules.common.modbus import ModbusTcpClient_ +from modules.devices.solvis.solvis.config import Solvis, SolvisCounterSetup +from modules.devices.solvis.solvis.counter import SolvisCounter + +log = logging.getLogger(__name__) + + +def create_device(device_config: Solvis): + client = None + + def create_counter_component(component_config: SolvisCounterSetup): + nonlocal client + return SolvisCounter(component_config, + device_id=device_config.id, + client=client, + modbus_id=device_config.configuration.modbus_id) + + def update_components(components: Iterable[SolvisCounter]): + with client: + for component in components: + with SingleComponentUpdateContext(component.fault_state): + component.update() + + def initializer(): + nonlocal client + client = ModbusTcpClient_(device_config.configuration.ip_address, device_config.configuration.port) + + return ConfigurableDevice( + device_config=device_config, + initializer=initializer, + component_factory=ComponentFactoryByType( + counter=create_counter_component, + ), + component_updater=MultiComponentUpdater(update_components) + ) + + +device_descriptor = DeviceDescriptor(configuration_factory=Solvis) From 5d6c6d0911b2c843c6cfc247f10f28368bb8c7d7 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 19 Jan 2026 08:01:19 +0100 Subject: [PATCH 5/8] Add files via upload --- packages/modules/devices/solvis/solvis/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/modules/devices/solvis/solvis/__init__.py diff --git a/packages/modules/devices/solvis/solvis/__init__.py b/packages/modules/devices/solvis/solvis/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 277a6799893895fece4b760f9ec1a394e2b34f47 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 19 Jan 2026 08:16:44 +0100 Subject: [PATCH 6/8] Add Solvis Counter.py --- .../modules/devices/solvis/solvis/counter.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 packages/modules/devices/solvis/solvis/counter.py diff --git a/packages/modules/devices/solvis/solvis/counter.py b/packages/modules/devices/solvis/solvis/counter.py new file mode 100644 index 0000000000..6bc864a3cb --- /dev/null +++ b/packages/modules/devices/solvis/solvis/counter.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +from typing import TypedDict, Any +from pymodbus.constants import Endian + +from modules.common.abstract_device import AbstractCounter +from modules.common.component_state import CounterState +from modules.common.component_type import ComponentDescriptor +from modules.common.fault_state import ComponentInfo, FaultState +from modules.common.modbus import ModbusDataType, ModbusTcpClient_ +from modules.common.simcount import SimCounter +from modules.common.store import get_counter_value_store +from modules.devices.solvis.solvis.config import SolvisCounterSetup + + +class KwargsDict(TypedDict): + device_id: int + client: ModbusTcpClient_ + modbus_id: int + + +class SolvisCounter(AbstractCounter): + def __init__(self, component_config: SolvisCounterSetup, **kwargs: Any) -> None: + self.component_config = component_config + self.kwargs: KwargsDict = kwargs + + def initialize(self) -> None: + self.__device_id: int = self.kwargs['device_id'] + self.client: ModbusTcpClient_ = self.kwargs['client'] + self.modbus_id: int = self.kwargs['modbus_id'] + self.sim_counter = SimCounter(self.__device_id, self.component_config.id, prefix="bezug") + self.store = get_counter_value_store(self.component_config.id) + self.fault_state = FaultState(ComponentInfo.from_component_config(self.component_config)) + + def update(self): + unit = self.modbus_id + power = self.client.read_input_registers(33545, ModbusDataType.INT_16, unit=unit) * 100 + imported, exported = self.sim_counter.sim_count(power) + + counter_state = CounterState( + imported=imported, + exported=exported, + power=power, + ) + self.store.set(counter_state) + + +component_descriptor = ComponentDescriptor(configuration_factory=SolvisCounterSetup) From b77bf73d6d0f51845017525d61fb7ea5a86a506f Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 19 Jan 2026 08:37:58 +0100 Subject: [PATCH 7/8] Flake8 Removed unused import of Endian from pymodbus.constants. --- packages/modules/devices/solvis/solvis/counter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/modules/devices/solvis/solvis/counter.py b/packages/modules/devices/solvis/solvis/counter.py index 6bc864a3cb..cc965f944c 100644 --- a/packages/modules/devices/solvis/solvis/counter.py +++ b/packages/modules/devices/solvis/solvis/counter.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 from typing import TypedDict, Any -from pymodbus.constants import Endian from modules.common.abstract_device import AbstractCounter from modules.common.component_state import CounterState From a89f4c19167b87321856c471bc3cd4529fd37685 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 19 Jan 2026 08:39:43 +0100 Subject: [PATCH 8/8] Flake8 Reformatted return statement for better readability. --- packages/modules/devices/solvis/solvis/device.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/modules/devices/solvis/solvis/device.py b/packages/modules/devices/solvis/solvis/device.py index 65568bac91..8f24a03646 100644 --- a/packages/modules/devices/solvis/solvis/device.py +++ b/packages/modules/devices/solvis/solvis/device.py @@ -17,10 +17,12 @@ def create_device(device_config: Solvis): def create_counter_component(component_config: SolvisCounterSetup): nonlocal client - return SolvisCounter(component_config, - device_id=device_config.id, - client=client, - modbus_id=device_config.configuration.modbus_id) + return SolvisCounter( + component_config, + device_id=device_config.id, + client=client, + modbus_id=device_config.configuration.modbus_id, + ) def update_components(components: Iterable[SolvisCounter]): with client: