From 977cd1629849b4d0df122c17df42c5993b465d50 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 15 Sep 2025 13:47:49 +0200 Subject: [PATCH 01/11] Create vendor.py --- packages/modules/devices/idm/vendor.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 packages/modules/devices/idm/vendor.py diff --git a/packages/modules/devices/idm/vendor.py b/packages/modules/devices/idm/vendor.py new file mode 100644 index 0000000000..e2d6437048 --- /dev/null +++ b/packages/modules/devices/idm/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 = "IDM" + self.group = VendorGroup.VENDORS.value + + +vendor_descriptor = DeviceDescriptor(configuration_factory=Vendor) From 2afad2d29796fb941bd72cd6410a75ea21d30a20 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 15 Sep 2025 13:48:54 +0200 Subject: [PATCH 02/11] Add files via upload --- packages/modules/devices/idm/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/modules/devices/idm/__init__.py diff --git a/packages/modules/devices/idm/__init__.py b/packages/modules/devices/idm/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From c04e0d334ebacc6eb9dd7c964c4c32c6ab05f149 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 15 Sep 2025 13:52:55 +0200 Subject: [PATCH 03/11] Create config.py --- packages/modules/devices/idm/idm/config.py | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 packages/modules/devices/idm/idm/config.py diff --git a/packages/modules/devices/idm/idm/config.py b/packages/modules/devices/idm/idm/config.py new file mode 100644 index 0000000000..70ec7edbe6 --- /dev/null +++ b/packages/modules/devices/idm/idm/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 NibeConfiguration: + def __init__(self, ip_address: Optional[str] = None, port: int = 502): + self.ip_address = ip_address + self.port = port + + +@auto_str +class IDM: + def __init__(self, + name: str = "IDM Wärmepumpe", + type: str = "IDM", + id: int = 0, + configuration: IDMConfiguration = None) -> None: + self.name = name + self.type = type + self.vendor = vendor_descriptor.configuration_factory().type + self.id = id + self.configuration = configuration or IDMConfiguration() + + +@auto_str +class IDMCounterConfiguration: + def __init__(self, modbus_id: int = 1): + self.modbus_id = modbus_id + + +@auto_str +class IDMCounterSetup(ComponentSetup[IDMCounterConfiguration]): + def __init__(self, + name: str = "IDM Zähler", + type: str = "counter", + id: int = 0, + configuration: IDMCounterConfiguration = None) -> None: + super().__init__(name, type, id, configuration or IDMCounterConfiguration()) From 557cdfe011f173ceb0dcc72382d201671262bf2e Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 15 Sep 2025 13:53:07 +0200 Subject: [PATCH 04/11] Add files via upload --- packages/modules/devices/idm/idm/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 packages/modules/devices/idm/idm/__init__.py diff --git a/packages/modules/devices/idm/idm/__init__.py b/packages/modules/devices/idm/idm/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 696da4b65e6b886366965d1879533aeb6c28fcda Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Mon, 15 Sep 2025 13:56:49 +0200 Subject: [PATCH 05/11] Create device.py --- packages/modules/devices/idm/idm/device.py | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 packages/modules/devices/idm/idm/device.py diff --git a/packages/modules/devices/idm/idm/device.py b/packages/modules/devices/idm/idm/device.py new file mode 100644 index 0000000000..f6fb4e2c19 --- /dev/null +++ b/packages/modules/devices/idm/idm/device.py @@ -0,0 +1,42 @@ +#!/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.idm.idm.config import IDM, IDMCounterSetup +from modules.devices.idm.idm.counter import IDMCounter + +log = logging.getLogger(__name__) + + +def create_device(device_config: IDM): + client = None + + def create_counter_component(component_config: IDMCounterSetup): + nonlocal client + return IDMCounter(component_config, device_id=device_config.id, client=client) + + def update_components(components: Iterable[IDMCounter]): + 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=IDM) From 07d32263e14b4828a607a16db6f474f853d61182 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Tue, 16 Sep 2025 16:40:08 +0200 Subject: [PATCH 06/11] Create counter.py --- packages/modules/devices/idm/idm/counter.py | 45 +++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 packages/modules/devices/idm/idm/counter.py diff --git a/packages/modules/devices/idm/idm/counter.py b/packages/modules/devices/idm/idm/counter.py new file mode 100644 index 0000000000..005cbdf7d6 --- /dev/null +++ b/packages/modules/devices/idm/idm/counter.py @@ -0,0 +1,45 @@ +#!/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.idm.idm.config import IDMCounterSetup + + +class KwargsDict(TypedDict): + device_id: int + client: ModbusTcpClient_ + + +class IDMCounter(AbstractCounter): + def __init__(self, component_config: IDMCounterSetup, **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.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.component_config.configuration.modbus_id + power = self.client.read_input_registers(4123, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=unit) + 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=IDMCounterSetup) From 80732895bc083c12a344463a372b5e157a647681 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Wed, 17 Sep 2025 07:24:26 +0200 Subject: [PATCH 07/11] Update config.py --- packages/modules/devices/idm/idm/config.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/modules/devices/idm/idm/config.py b/packages/modules/devices/idm/idm/config.py index 70ec7edbe6..99edcdddc8 100644 --- a/packages/modules/devices/idm/idm/config.py +++ b/packages/modules/devices/idm/idm/config.py @@ -1,22 +1,22 @@ 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 NibeConfiguration: - def __init__(self, ip_address: Optional[str] = None, port: int = 502): +class IDMConfiguration: + 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 IDM: def __init__(self, - name: str = "IDM Wärmepumpe", - type: str = "IDM", + name: str = "IDM", + type: str = "idm", id: int = 0, configuration: IDMConfiguration = None) -> None: self.name = name @@ -28,8 +28,8 @@ def __init__(self, @auto_str class IDMCounterConfiguration: - def __init__(self, modbus_id: int = 1): - self.modbus_id = modbus_id + def __init__(self): + pass @auto_str From 6e6ac8683e1c727d17327df8a3e6f9d25cb96b3c Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Wed, 17 Sep 2025 07:28:36 +0200 Subject: [PATCH 08/11] Fix Register --- packages/modules/devices/idm/idm/counter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/modules/devices/idm/idm/counter.py b/packages/modules/devices/idm/idm/counter.py index 005cbdf7d6..c6907e3406 100644 --- a/packages/modules/devices/idm/idm/counter.py +++ b/packages/modules/devices/idm/idm/counter.py @@ -31,7 +31,8 @@ def initialize(self) -> None: def update(self): unit = self.component_config.configuration.modbus_id - power = self.client.read_input_registers(4123, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=unit) + power = self.client.read_input_registers(4122, ModbusDataType.FLOAT_32, + wordorder=Endian.Little, unit=unit) *1000 imported, exported = self.sim_counter.sim_count(power) counter_state = CounterState( From b76a167be08dea6800762eadcec29eae7384589e Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Wed, 17 Sep 2025 08:56:58 +0200 Subject: [PATCH 09/11] flake8 --- packages/modules/devices/idm/idm/counter.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/modules/devices/idm/idm/counter.py b/packages/modules/devices/idm/idm/counter.py index c6907e3406..6f14fd7716 100644 --- a/packages/modules/devices/idm/idm/counter.py +++ b/packages/modules/devices/idm/idm/counter.py @@ -31,8 +31,8 @@ def initialize(self) -> None: def update(self): unit = self.component_config.configuration.modbus_id - power = self.client.read_input_registers(4122, ModbusDataType.FLOAT_32, - wordorder=Endian.Little, unit=unit) *1000 + power = self.client.read_input_registers(4122, ModbusDataType.FLOAT_32, + wordorder=Endian.Little, unit=unit) * 1000 imported, exported = self.sim_counter.sim_count(power) counter_state = CounterState( From 4afc6ec481b00d32d4cd157ae2078ffebe9518f2 Mon Sep 17 00:00:00 2001 From: SeaSpotter Date: Fri, 24 Oct 2025 09:18:43 +0200 Subject: [PATCH 10/11] Add modbus_id to IDMCounter and update initialization --- packages/modules/devices/idm/idm/counter.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/modules/devices/idm/idm/counter.py b/packages/modules/devices/idm/idm/counter.py index 6f14fd7716..44ff2ab5b9 100644 --- a/packages/modules/devices/idm/idm/counter.py +++ b/packages/modules/devices/idm/idm/counter.py @@ -15,6 +15,7 @@ class KwargsDict(TypedDict): device_id: int client: ModbusTcpClient_ + modbus_id: int class IDMCounter(AbstractCounter): @@ -25,12 +26,13 @@ def __init__(self, component_config: IDMCounterSetup, **kwargs: Any) -> None: 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.component_config.configuration.modbus_id + unit = self.modbus_id power = self.client.read_input_registers(4122, ModbusDataType.FLOAT_32, wordorder=Endian.Little, unit=unit) * 1000 imported, exported = self.sim_counter.sim_count(power) From bdfe62a1af3273c721eda8fc260dd9e068ee6821 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 27 Oct 2025 11:59:01 +0100 Subject: [PATCH 11/11] fix parameter --- packages/modules/devices/idm/idm/device.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/modules/devices/idm/idm/device.py b/packages/modules/devices/idm/idm/device.py index f6fb4e2c19..c7c2983201 100644 --- a/packages/modules/devices/idm/idm/device.py +++ b/packages/modules/devices/idm/idm/device.py @@ -17,7 +17,10 @@ def create_device(device_config: IDM): def create_counter_component(component_config: IDMCounterSetup): nonlocal client - return IDMCounter(component_config, device_id=device_config.id, client=client) + return IDMCounter(component_config, + device_id=device_config.id, + client=client, + modbus_id=device_config.configuration.modbus_id) def update_components(components: Iterable[IDMCounter]): with client: