Skip to content

Commit e73e28c

Browse files
authored
Handle "little" for multiple values in to_registers (#2678)
1 parent bc1404e commit e73e28c

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

pymodbus/client/mixin.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,5 +771,19 @@ def convert_to_registers(
771771
for x in range(0, len(byte_list), 2)
772772
]
773773
if word_order == "little":
774-
regs.reverse()
774+
return cls._get_reversed_registers(regs, data_type)
775+
775776
return regs
777+
778+
@classmethod
779+
def _get_reversed_registers(cls, regs: list[int], data_type: DATATYPE) -> list[int]:
780+
if not (data_type_len := data_type.value[1]):
781+
regs.reverse()
782+
return regs
783+
784+
reversed_regs: list[int] = []
785+
for x in range(0, len(regs), data_type_len):
786+
single_value_regs = regs[x: x + data_type_len]
787+
single_value_regs.reverse()
788+
reversed_regs = reversed_regs + single_value_regs
789+
return reversed_regs

test/client/test_client.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,22 @@ def fake_execute(_self, _no_response_expected, request):
105105
(ModbusClientMixin.DATATYPE.STRING, "a", [0x6100], None),
106106
(ModbusClientMixin.DATATYPE.UINT16, 27123, [0x69F3], None),
107107
(ModbusClientMixin.DATATYPE.INT16, -27123, [0x960D], None),
108+
(ModbusClientMixin.DATATYPE.INT16, [-27123, 27123], [0x960D, 0x69F3], None),
108109
(ModbusClientMixin.DATATYPE.UINT32, 27123, [0x0000, 0x69F3], None),
109110
(ModbusClientMixin.DATATYPE.UINT32, 32145678, [0x01EA, 0x810E], None),
111+
(
112+
ModbusClientMixin.DATATYPE.UINT32,
113+
[27123, 32145678],
114+
[0x0000, 0x69F3, 0x01EA, 0x810E],
115+
None
116+
),
110117
(ModbusClientMixin.DATATYPE.INT32, -32145678, [0xFE15, 0x7EF2], None),
118+
(
119+
ModbusClientMixin.DATATYPE.INT32,
120+
[32145678, -32145678],
121+
[0x01EA, 0x810E, 0xFE15, 0x7EF2],
122+
None
123+
),
111124
(
112125
ModbusClientMixin.DATATYPE.UINT64,
113126
1234567890123456789,
@@ -120,9 +133,21 @@ def fake_execute(_self, _no_response_expected, request):
120133
[0xEEDD, 0xEF0B, 0x8216, 0x7EEB],
121134
None,
122135
),
136+
(
137+
ModbusClientMixin.DATATYPE.INT64,
138+
[1234567890123456789, -1234567890123456789],
139+
[0x1122, 0x10F4, 0x7DE9, 0x8115, 0xEEDD, 0xEF0B, 0x8216, 0x7EEB],
140+
None,
141+
),
123142
(ModbusClientMixin.DATATYPE.FLOAT32, 27123.5, [0x46D3, 0xE700], None),
124143
(ModbusClientMixin.DATATYPE.FLOAT32, 3.141592, [0x4049, 0x0FD8], None),
125144
(ModbusClientMixin.DATATYPE.FLOAT32, -3.141592, [0xC049, 0x0FD8], None),
145+
(
146+
ModbusClientMixin.DATATYPE.FLOAT32,
147+
[27123.5, 3.141592, -3.141592],
148+
[0x46D3, 0xE700, 0x4049, 0x0FD8, 0xC049, 0x0FD8],
149+
None
150+
),
126151
(ModbusClientMixin.DATATYPE.FLOAT64, 27123.5, [0x40DA, 0x7CE0, 0x0000, 0x0000], None),
127152
(
128153
ModbusClientMixin.DATATYPE.FLOAT64,
@@ -136,6 +161,12 @@ def fake_execute(_self, _no_response_expected, request):
136161
[0xC009, 0x21FB, 0x5444, 0x2D11],
137162
None,
138163
),
164+
(
165+
ModbusClientMixin.DATATYPE.FLOAT64,
166+
[3.14159265358979, -3.14159265358979],
167+
[0x4009, 0x21FB, 0x5444, 0x2D11, 0xC009, 0x21FB, 0x5444, 0x2D11],
168+
None,
169+
),
139170
(
140171
ModbusClientMixin.DATATYPE.BITS,
141172
[True],
@@ -195,7 +226,16 @@ def fake_execute(_self, _no_response_expected, request):
195226
def test_client_mixin_convert(self, datatype, word_order, registers, value, string_encoding):
196227
"""Test converter methods."""
197228
if word_order == "little":
198-
registers = list(reversed(registers))
229+
if not (datatype_len := datatype.value[1]):
230+
registers = list(reversed(registers))
231+
else:
232+
reversed_regs: list[int] = []
233+
for x in range(0, len(registers), datatype_len):
234+
single_value_regs = registers[x: x + datatype_len]
235+
single_value_regs.reverse()
236+
reversed_regs = reversed_regs + single_value_regs
237+
registers = reversed_regs
238+
199239

200240
kwargs = {**({"word_order": word_order} if word_order else {}),
201241
**({"string_encoding": string_encoding} if string_encoding else {})}
@@ -207,7 +247,10 @@ def test_client_mixin_convert(self, datatype, word_order, registers, value, stri
207247
if (missing := len(value) % 16):
208248
value = value + [False] * (16 - missing)
209249
if datatype == ModbusClientMixin.DATATYPE.FLOAT32:
210-
result = round(result, 6)
250+
if isinstance(result, list):
251+
result = [round(v, 6) for v in result]
252+
else:
253+
result = round(result, 6)
211254
assert result == value
212255

213256
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)