Skip to content

Commit 3f65d2a

Browse files
authored
Correct byte order in bits. (#2631)
1 parent 6c9c0a6 commit 3f65d2a

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
@@ -164,14 +164,15 @@ def pack_bitstring(bits: list[bool], align_byte=True) -> bytes:
164164
bits_extra = 8 if align_byte else 16
165165
if (extra := len(bits) % bits_extra):
166166
t_bits += [False] * (bits_extra - extra)
167-
for bit in reversed(t_bits):
168-
packed <<= 1
169-
if bit:
170-
packed += 1
171-
i += 1
172-
if i == 8:
173-
ret += struct.pack(">B", packed)
174-
i = packed = 0
167+
for byte_inx in range(0, len(t_bits), 8):
168+
for bit in reversed(t_bits[byte_inx:byte_inx+8]):
169+
packed <<= 1
170+
if bit:
171+
packed += 1
172+
i += 1
173+
if i == 8:
174+
ret += struct.pack(">B", packed)
175+
i = packed = 0
175176
return ret
176177

177178

@@ -183,13 +184,11 @@ def unpack_bitstring(data: bytes) -> list[bool]:
183184
bytes 0x05 0x81
184185
result = unpack_bitstring(bytes)
185186
186-
[True, False, False, False] +
187-
[False, False, False, True] +
188-
[True, False, True, False] +
189-
[False, False, False, False]
187+
[True, False, True, False] + [False, False, False, False]
188+
[True, False, False, False] + [False, False, False, True]
190189
"""
191190
res = []
192-
for byte_index in range(len(data) -1, -1, -1):
191+
for _, t_byte in enumerate(data):
193192
for bit in (1, 2, 4, 8, 16, 32, 64, 128):
194-
res.append(bool(data[byte_index] & bit))
193+
res.append(bool(t_byte & bit))
195194
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
@@ -255,21 +255,21 @@ async def test_pdu_default_datastore(self, mock_context):
255255
@pytest.mark.parametrize(
256256
("bytestream", "bitlist"),
257257
[
258-
(b"\x00\x01", [True] + [False] * 15),
259-
(b"\x01\x00", [False] * 8 + [True] + [False] * 7),
260-
(b"\x80\x00", [False] * 15 + [True]),
261-
(b"\x80\x01", [True] + [False] * 14 + [True]),
262-
(b"\x05\x00", [False] * 8 + [True, False, True] + [False] * 5),
263-
(b"\x05\x01", [True] + [False] * 7 + [True, False, True] + [False] * 5),
264-
(b"\x05\x81", [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
265-
(b"\x05\x81\x01\x00", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
258+
(b"\x01\x00", [True] + [False] * 15),
259+
(b"\x00\x80", [False] * 15 + [True]),
260+
(b"\x00\x01", [False] * 8 + [True] + [False] * 7),
261+
(b"\x01\x80", [True] + [False] * 14 + [True]),
262+
(b"\x00\x05", [False] * 8 + [True, False, True] + [False] * 5),
263+
(b"\x01\x05", [True] + [False] * 7 + [True, False, True] + [False] * 5),
264+
(b"\x81\x05", [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
265+
(b"\x00\x01\x81\x05", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
266266
267-
(b"\x00\x01", [True]),
268-
(b"\x01\x00", [False] * 8 + [True]),
269-
(b"\x05\x00", [False] * 8 + [True, False, True]),
270-
(b"\x05\x01", [True] + [False] * 7 + [True, False, True]),
271-
(b"\x05\x81", [True] + [False] * 6 + [True, True, False, True]),
272-
(b"\x05\x81\x01\x00", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True]),
267+
(b"\x01\x00", [True]),
268+
(b"\x00\x01", [False] * 8 + [True]),
269+
(b"\x00\x05", [False] * 8 + [True, False, True]),
270+
(b"\x01\x05", [True] + [False] * 7 + [True, False, True]),
271+
(b"\x81\x05", [True] + [False] * 6 + [True, True, False, True]),
272+
(b"\x00\x01\x81\x05", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True]),
273273
],
274274
)
275275
def test_bit_packing(self, bytestream, bitlist):
@@ -280,9 +280,9 @@ def test_bit_packing(self, bytestream, bitlist):
280280
("bytestream", "bitlist"),
281281
[
282282
(b"\x01", [True]),
283-
(b"\x01\x00", [False] * 8 + [True]),
283+
(b"\x00\x01", [False] * 8 + [True]),
284284
(b"\x05", [True, False, True]),
285-
(b"\x05\x01", [True] + [False] * 7 + [True, False, True]),
285+
(b"\x01\x05", [True] + [False] * 7 + [True, False, True]),
286286
],
287287
)
288288
def test_bit_packing8(self, bytestream, bitlist):
@@ -293,14 +293,17 @@ def test_bit_packing8(self, bytestream, bitlist):
293293
("bytestream", "bitlist"),
294294
[
295295
(b"\x01", [True] + [False] * 7),
296-
(b"\x00\x01", [True] + [False] * 15),
297-
(b"\x01\x00", [False] * 8 + [True] + [False] * 7),
298-
(b"\x80\x00", [False] * 15 + [True]),
299-
(b"\x80\x01", [True] + [False] * 14 + [True]),
300-
(b"\x05\x00", [False] * 8 + [True, False, True] + [False] * 5),
301-
(b"\x05\x01", [True] + [False] * 7 + [True, False, True] + [False] * 5),
302-
(b"\x05\x81", [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
303-
(b"\x05\x81\x01\x00", [False] * 8 + [True] + [False] * 7 + [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
296+
(b"\x01\x00", [True] + [False] * 15),
297+
(b"\x00\x01", [False] * 8 + [True] + [False] * 7),
298+
(b"\x00\x80", [False] * 15 + [True]),
299+
(b"\x01\x80", [True] + [False] * 14 + [True]),
300+
(b"\x00\x05", [False] * 8 + [True, False, True] + [False] * 5),
301+
(b"\x01\x05", [True] + [False] * 7 + [True, False, True] + [False] * 5),
302+
(b"\x81\x05", [True] + [False] * 6 + [True, True, False, True] + [False] * 5),
303+
(b"\x05\x81\x01\x00", [True, False, True] + [False] * 5 +
304+
[True] + [False] * 6 + [True] +
305+
[True] + [False] * 7 +
306+
[False] * 8),
304307
],
305308
)
306309
def test_bit_unpacking(self, bytestream, bitlist):

0 commit comments

Comments
 (0)