Skip to content

Commit 20ba1f3

Browse files
committed
Correct byte order in bits. (#2631)
1 parent b3c16e2 commit 20ba1f3

File tree

3 files changed

+48
-46
lines changed

3 files changed

+48
-46
lines changed

pymodbus/pdu/pdu.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,15 @@ def pack_bitstring(bits: list[bool], align_byte=True) -> bytes:
162162
bits_extra = 8 if align_byte else 16
163163
if (extra := len(bits) % bits_extra):
164164
t_bits += [False] * (bits_extra - extra)
165-
for bit in reversed(t_bits):
166-
packed <<= 1
167-
if bit:
168-
packed += 1
169-
i += 1
170-
if i == 8:
171-
ret += struct.pack(">B", packed)
172-
i = packed = 0
165+
for byte_inx in range(0, len(t_bits), 8):
166+
for bit in reversed(t_bits[byte_inx:byte_inx+8]):
167+
packed <<= 1
168+
if bit:
169+
packed += 1
170+
i += 1
171+
if i == 8:
172+
ret += struct.pack(">B", packed)
173+
i = packed = 0
173174
return ret
174175

175176

@@ -181,13 +182,11 @@ def unpack_bitstring(data: bytes) -> list[bool]:
181182
bytes 0x05 0x81
182183
result = unpack_bitstring(bytes)
183184
184-
[True, False, False, False] +
185-
[False, False, False, True] +
186-
[True, False, True, False] +
187-
[False, False, False, False]
185+
[True, False, True, False] + [False, False, False, False]
186+
[True, False, False, False] + [False, False, False, True]
188187
"""
189188
res = []
190-
for byte_index in range(len(data) -1, -1, -1):
189+
for _, t_byte in enumerate(data):
191190
for bit in (1, 2, 4, 8, 16, 32, 64, 128):
192-
res.append(bool(data[byte_index] & bit))
191+
res.append(bool(t_byte & bit))
193192
return res

test/client/test_client.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,49 +139,49 @@ def fake_execute(_self, _no_response_expected, request):
139139
(
140140
ModbusClientMixin.DATATYPE.BITS,
141141
[True] + [False] * 15,
142-
[1], # 0x00 0x01
142+
[256], # 0x01 0x00
143143
None,
144144
),
145145
(
146146
ModbusClientMixin.DATATYPE.BITS,
147147
[False] * 8 + [True] + [False] * 7,
148-
[256], # 0x01 0x00
148+
[1], # 0x00 0x01
149149
None,
150150
),
151151
(
152152
ModbusClientMixin.DATATYPE.BITS,
153153
[False] * 15 + [True],
154-
[32768], # 0x80 0x00
154+
[128], # 0x00 0x80
155155
None,
156156
),
157157
(
158158
ModbusClientMixin.DATATYPE.BITS,
159159
[True] + [False] * 14 + [True],
160-
[32769], # 0x80 0x01
160+
[384], # 0x01 0x80
161161
None,
162162
),
163163
(
164164
ModbusClientMixin.DATATYPE.BITS,
165165
[False] * 8 + [True, False, True] + [False] * 5,
166-
[1280], # 0x05 0x00
166+
[5], # 0x00 0x05
167167
None,
168168
),
169169
(
170170
ModbusClientMixin.DATATYPE.BITS,
171171
[True] + [False] * 7 + [True, False, True] + [False] * 5,
172-
[1281], # 0x05 0x01
172+
[261], # 0x01 0x05
173173
None,
174174
),
175175
(
176176
ModbusClientMixin.DATATYPE.BITS,
177177
[True] + [False] * 6 + [True, True, False, True] + [False] * 5,
178-
[1409], # 0x05 0x81
178+
[33029], # 0x81 0x05
179179
None,
180180
),
181181
(
182182
ModbusClientMixin.DATATYPE.BITS,
183183
[False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True] + [False] * 5,
184-
[1409, 256], # 92340480 = 0x05 0x81 0x01 0x00
184+
[1, 33029], # 92340480 = 0x00 0x01 0x81 0x05
185185
None,
186186
),
187187
],

test/pdu/test_pdu.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -250,21 +250,21 @@ async def test_pdu_default_datastore(self, mock_context):
250250
@pytest.mark.parametrize(
251251
("bytestream", "bitlist"),
252252
[
253-
(b"\x00\x01", [True] + [False] * 15),
254-
(b"\x01\x00", [False] * 8 + [True] + [False] * 7),
255-
(b"\x80\x00", [False] * 15 + [True]),
256-
(b"\x80\x01", [True] + [False] * 14 + [True]),
257-
(b"\x05\x00", [False] * 8 + [True, False, True] + [False] * 5),
258-
(b"\x05\x01", [True] + [False] * 7 + [True, False, True] + [False] * 5),
259-
(b"\x05\x81", [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
260-
(b"\x05\x81\x01\x00", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
253+
(b"\x01\x00", [True] + [False] * 15),
254+
(b"\x00\x80", [False] * 15 + [True]),
255+
(b"\x00\x01", [False] * 8 + [True] + [False] * 7),
256+
(b"\x01\x80", [True] + [False] * 14 + [True]),
257+
(b"\x00\x05", [False] * 8 + [True, False, True] + [False] * 5),
258+
(b"\x01\x05", [True] + [False] * 7 + [True, False, True] + [False] * 5),
259+
(b"\x81\x05", [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
260+
(b"\x00\x01\x81\x05", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
261261
262-
(b"\x00\x01", [True]),
263-
(b"\x01\x00", [False] * 8 + [True]),
264-
(b"\x05\x00", [False] * 8 + [True, False, True]),
265-
(b"\x05\x01", [True] + [False] * 7 + [True, False, True]),
266-
(b"\x05\x81", [True] + [False] * 6 + [True, True, False, True]),
267-
(b"\x05\x81\x01\x00", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True]),
262+
(b"\x01\x00", [True]),
263+
(b"\x00\x01", [False] * 8 + [True]),
264+
(b"\x00\x05", [False] * 8 + [True, False, True]),
265+
(b"\x01\x05", [True] + [False] * 7 + [True, False, True]),
266+
(b"\x81\x05", [True] + [False] * 6 + [True, True, False, True]),
267+
(b"\x00\x01\x81\x05", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True]),
268268
],
269269
)
270270
def test_bit_packing(self, bytestream, bitlist):
@@ -275,9 +275,9 @@ def test_bit_packing(self, bytestream, bitlist):
275275
("bytestream", "bitlist"),
276276
[
277277
(b"\x01", [True]),
278-
(b"\x01\x00", [False] * 8 + [True]),
278+
(b"\x00\x01", [False] * 8 + [True]),
279279
(b"\x05", [True, False, True]),
280-
(b"\x05\x01", [True] + [False] * 7 + [True, False, True]),
280+
(b"\x01\x05", [True] + [False] * 7 + [True, False, True]),
281281
],
282282
)
283283
def test_bit_packing8(self, bytestream, bitlist):
@@ -288,14 +288,17 @@ def test_bit_packing8(self, bytestream, bitlist):
288288
("bytestream", "bitlist"),
289289
[
290290
(b"\x01", [True] + [False] * 7),
291-
(b"\x00\x01", [True] + [False] * 15),
292-
(b"\x01\x00", [False] * 8 + [True] + [False] * 7),
293-
(b"\x80\x00", [False] * 15 + [True]),
294-
(b"\x80\x01", [True] + [False] * 14 + [True]),
295-
(b"\x05\x00", [False] * 8 + [True, False, True] + [False] * 5),
296-
(b"\x05\x01", [True] + [False] * 7 + [True, False, True] + [False] * 5),
297-
(b"\x05\x81", [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
298-
(b"\x05\x81\x01\x00", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
291+
(b"\x01\x00", [True] + [False] * 15),
292+
(b"\x00\x01", [False] * 8 + [True] + [False] * 7),
293+
(b"\x00\x80", [False] * 15 + [True]),
294+
(b"\x01\x80", [True] + [False] * 14 + [True]),
295+
(b"\x00\x05", [False] * 8 + [True, False, True] + [False] * 5),
296+
(b"\x01\x05", [True] + [False] * 7 + [True, False, True] + [False] * 5),
297+
(b"\x81\x05", [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
298+
(b"\x05\x81\x01\x00", [True, False, True] + [False] * 5 +
299+
[True] + [False] * 6 + [True] +
300+
[True] + [False] * 7 +
301+
[False] * 8),
299302
],
300303
)
301304
def test_bit_unpacking(self, bytestream, bitlist):

0 commit comments

Comments
 (0)