diff --git a/packages/modules/common/modbus.py b/packages/modules/common/modbus.py index 49fbaa4ac9..8da0ef2412 100644 --- a/packages/modules/common/modbus.py +++ b/packages/modules/common/modbus.py @@ -11,7 +11,7 @@ from typing import Any, Callable, Iterable, Optional, Union, overload, List import pymodbus -from pymodbus.client.sync import ModbusTcpClient, ModbusSerialClient +from pymodbus.client.sync import ModbusTcpClient, ModbusUdpClient, ModbusSerialClient from pymodbus.constants import Endian from pymodbus.payload import BinaryPayloadDecoder from pymodbus.transaction import ModbusSocketFramer @@ -49,7 +49,7 @@ def __init__(self, bits: int, decoding_method: str): class ModbusClient: def __init__(self, - delegate: Union[ModbusSerialClient, ModbusTcpClient], + delegate: Union[ModbusSerialClient, ModbusTcpClient, ModbusUdpClient], address: str, port: int = 502, sleep_after_connect: Optional[int] = 0): self._delegate = delegate @@ -207,6 +207,19 @@ def __init__(self, super().__init__(ModbusTcpClient(host, port, framer, **kwargs), address, port, sleep_after_connect) +class ModbusUdpClient_(ModbusClient): + def __init__(self, + address: str, + port: int = 502, + sleep_after_connect: Optional[int] = 0, + **kwargs): + parsed_url = parse_url(address) + host = parsed_url.host + if parsed_url.port is not None: + port = parsed_url.port + super().__init__(ModbusUdpClient(host, port, **kwargs), address, port, sleep_after_connect) + + class ModbusSerialClient_(ModbusClient): def __init__(self, port: int, diff --git a/packages/modules/devices/victron/victron/counter.py b/packages/modules/devices/victron/victron/counter.py index 138fa638a4..98b99e6403 100644 --- a/packages/modules/devices/victron/victron/counter.py +++ b/packages/modules/devices/victron/victron/counter.py @@ -14,7 +14,7 @@ class KwargsDict(TypedDict): device_id: int - client: modbus.ModbusTcpClient_ + client: modbus.ModbusUdpClient_ class VictronCounter(AbstractCounter): @@ -24,7 +24,7 @@ def __init__(self, component_config: VictronCounterSetup, **kwargs: Any) -> None def initialize(self) -> None: self.__device_id: int = self.kwargs['device_id'] - self.__tcp_client = self.kwargs['client'] + self.__udp_client = 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)) @@ -32,18 +32,20 @@ def initialize(self) -> None: def update(self): unit = self.component_config.configuration.modbus_id energy_meter = self.component_config.configuration.energy_meter - with self.__tcp_client: + with self.__udp_client: if energy_meter: - powers = self.__tcp_client.read_holding_registers(2600, [ModbusDataType.INT_16]*3, unit=unit) + powers = [ + self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_32, unit=unit) / -1 + for reg in [0x3082, 0x3086, 0x308A]] currents = [ - self.__tcp_client.read_holding_registers(reg, ModbusDataType.INT_16, unit=unit) / 10 - for reg in [2617, 2619, 2621]] + self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_16, unit=unit) / -100 + for reg in [0x3041, 0x3049, 0x3051]] voltages = [ - self.__tcp_client.read_holding_registers(reg, ModbusDataType.UINT_16, unit=unit) / 10 - for reg in [2616, 2618, 2620]] + self.__udp_client.read_holding_registers(reg, ModbusDataType.INT_16, unit=unit) / 100 + for reg in [0x3040, 0x3048, 0x3050]] power = sum(powers) else: - powers = self.__tcp_client.read_holding_registers(820, [ModbusDataType.INT_16]*3, unit=unit) + powers = self.__udp_client.read_holding_registers(820, [ModbusDataType.INT_16]*3, unit=unit) power = sum(powers) imported, exported = self.sim_counter.sim_count(power) diff --git a/packages/modules/devices/victron/victron/device.py b/packages/modules/devices/victron/victron/device.py index 5f346f400e..5b18f7fc46 100644 --- a/packages/modules/devices/victron/victron/device.py +++ b/packages/modules/devices/victron/victron/device.py @@ -5,7 +5,7 @@ from modules.common.abstract_device import DeviceDescriptor from modules.common.component_context import SingleComponentUpdateContext from modules.common.configurable_device import ComponentFactoryByType, ConfigurableDevice, MultiComponentUpdater -from modules.common.modbus import ModbusTcpClient_ +from modules.common.modbus import ModbusUdpClient_ from modules.devices.victron.victron.bat import VictronBat from modules.devices.victron.victron.config import Victron, VictronBatSetup, VictronCounterSetup, VictronInverterSetup from modules.devices.victron.victron.counter import VictronCounter @@ -38,7 +38,7 @@ def update_components(components: Iterable[Union[VictronBat, VictronCounter, Vic def initializer(): nonlocal client - client = ModbusTcpClient_(device_config.configuration.ip_address, device_config.configuration.port) + client = ModbusUdpClient_(device_config.configuration.ip_address, device_config.configuration.port) return ConfigurableDevice( device_config=device_config,