Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions packages/modules/common/modbus.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
20 changes: 11 additions & 9 deletions packages/modules/devices/victron/victron/counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

class KwargsDict(TypedDict):
device_id: int
client: modbus.ModbusTcpClient_
client: modbus.ModbusUdpClient_


class VictronCounter(AbstractCounter):
Expand All @@ -24,26 +24,28 @@ 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))

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)
Expand Down
4 changes: 2 additions & 2 deletions packages/modules/devices/victron/victron/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down