Skip to content

Commit 3d4db88

Browse files
authored
Merge pull request #281 from sfstar/feature/prepare_for_pymodbus_3_9_0
Ensure ha core 2025.07 compatibility
2 parents 94a3bd5 + 0d304b5 commit 3d4db88

File tree

6 files changed

+60
-36
lines changed

6 files changed

+60
-36
lines changed

custom_components/victron/binary_sensor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def is_on(self) -> bool:
106106
self.description.slave,
107107
self.description.key,
108108
)
109-
return cast(bool, data)
109+
return cast("bool", data)
110110

111111
@property
112112
def available(self) -> bool:

custom_components/victron/coordinator.py

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import logging
88

99
import pymodbus
10-
from pymodbus.constants import Endian
11-
from pymodbus.payload import BinaryPayloadDecoder
1210

1311
if "3.7.0" <= pymodbus.__version__ <= "3.7.4":
1412
from pymodbus.pdu.register_read_message import ReadHoldingRegistersResponse
@@ -112,42 +110,36 @@ async def _async_update_data(self) -> dict:
112110
def parse_register_data(
113111
self,
114112
buffer: ReadHoldingRegistersResponse,
115-
registerInfo: OrderedDict(str, RegisterInfo),
113+
registerInfo: OrderedDict[str, RegisterInfo],
116114
unit: int,
117115
) -> dict:
118-
"""Parse the register data."""
119-
decoder = BinaryPayloadDecoder.fromRegisters(
120-
buffer.registers, byteorder=Endian.BIG
121-
)
116+
"""Parse the register data using convert_from_registers."""
122117
decoded_data = OrderedDict()
118+
registers = buffer.registers
119+
offset = 0
120+
123121
for key, value in registerInfo.items():
124-
full_key = str(unit) + "." + key
125-
if value.dataType == UINT16:
126-
decoded_data[full_key] = self.decode_scaling(
127-
decoder.decode_16bit_uint(), value.scale, value.unit
128-
)
129-
elif value.dataType == INT16:
130-
decoded_data[full_key] = self.decode_scaling(
131-
decoder.decode_16bit_int(), value.scale, value.unit
132-
)
133-
elif value.dataType == UINT32:
134-
decoded_data[full_key] = self.decode_scaling(
135-
decoder.decode_32bit_uint(), value.scale, value.unit
136-
)
137-
elif value.dataType == INT32:
138-
decoded_data[full_key] = self.decode_scaling(
139-
decoder.decode_32bit_int(), value.scale, value.unit
140-
)
122+
full_key = f"{unit}.{key}"
123+
count = 0
124+
if value.dataType in (INT16, UINT16):
125+
count = 1
126+
elif value.dataType in (INT32, UINT32):
127+
count = 2
141128
elif isinstance(value.dataType, STRING):
142-
decoded_data[full_key] = (
143-
decoder.decode_string(value.dataType.readLength)
144-
.split(b"\x00")[0]
145-
.decode()
146-
)
129+
count = value.dataType.length
130+
segment = registers[offset : offset + count]
131+
132+
if isinstance(value.dataType, STRING):
133+
raw = self.api.convert_string_from_register(segment)
134+
decoded_data[full_key] = raw
147135
else:
148-
raise DecodeDataTypeUnsupported(
149-
f"Not supported dataType: {value.dataType}"
136+
raw = self.api.convert_number_from_register(segment, value.dataType)
137+
# _LOGGER.warning("trying to decode %s with value %s", key, raw)
138+
decoded_data[full_key] = self.decode_scaling(
139+
raw, value.scale, value.unit
150140
)
141+
offset += count
142+
151143
return decoded_data
152144

153145
def decode_scaling(self, number, scale, unit):

custom_components/victron/hub.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@
88

99
from homeassistant.exceptions import HomeAssistantError
1010

11-
from .const import INT32, STRING, UINT32, register_info_dict, valid_unit_ids
11+
from .const import (
12+
INT16,
13+
INT32,
14+
STRING,
15+
UINT16,
16+
UINT32,
17+
register_info_dict,
18+
valid_unit_ids,
19+
)
1220

1321
_LOGGER = logging.getLogger(__name__)
1422

@@ -27,6 +35,32 @@ def is_still_connected(self):
2735
"""Check if the connection is still open."""
2836
return self._client.is_socket_open()
2937

38+
def convert_string_from_register(self, segment, string_encoding="ascii"):
39+
"""Convert from registers to the appropriate data type."""
40+
return self._client.convert_from_registers(
41+
segment, self._client.DATATYPE.STRING, string_encoding="ascii"
42+
).split("\x00")[0]
43+
44+
def convert_number_from_register(self, segment, dataType):
45+
"""Convert from registers to the appropriate data type."""
46+
if dataType == UINT16:
47+
raw = self._client.convert_from_registers(
48+
segment, data_type=self._client.DATATYPE.UINT16
49+
)
50+
elif dataType == INT16:
51+
raw = self._client.convert_from_registers(
52+
segment, data_type=self._client.DATATYPE.INT16
53+
)
54+
elif dataType == UINT32:
55+
raw = self._client.convert_from_registers(
56+
segment, data_type=self._client.DATATYPE.UINT32
57+
)
58+
elif dataType == INT32:
59+
raw = self._client.convert_from_registers(
60+
segment, data_type=self._client.DATATYPE.INT32
61+
)
62+
return raw
63+
3064
def connect(self):
3165
"""Connect to the Modbus TCP server."""
3266
return self._client.connect()

custom_components/victron/sensor.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ def _handle_coordinator_update(self) -> None:
191191
"The reported value %s for entity %s isn't a decobale value. Please report this error to the integrations maintainer",
192192
data,
193193
self._attr_name,
194-
exc_info=1,
195194
)
196195
else:
197196
self._attr_native_value = data

custom_components/victron/switch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def is_on(self) -> bool:
124124
self.description.slave,
125125
self.description.key,
126126
)
127-
return cast(bool, data)
127+
return cast("bool", data)
128128

129129
@property
130130
def available(self) -> bool:

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,6 @@ select = [
452452
"S317", # suspicious-xml-sax-usage
453453
"S318", # suspicious-xml-mini-dom-usage
454454
"S319", # suspicious-xml-pull-dom-usage
455-
"S320", # suspicious-xmle-tree-usage
456455
"S601", # paramiko-call
457456
"S602", # subprocess-popen-with-shell-equals-true
458457
"S604", # call-with-shell-equals-true

0 commit comments

Comments
 (0)