Skip to content

Commit 03542f6

Browse files
authored
Remove _header from framers. (#2305)
1 parent 8bb12f5 commit 03542f6

11 files changed

+66
-145
lines changed

examples/message_parser.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,7 @@ def decode(self, message):
8080
print(f"{decoder.decoder.__class__.__name__}")
8181
print("-" * 80)
8282
try:
83-
slave = decoder._header.get( # pylint: disable=protected-access
84-
"uid", 0x00
85-
)
86-
decoder.processIncomingPacket(message, self.report, slave)
83+
decoder.processIncomingPacket(message, self.report, 0)
8784
except Exception: # pylint: disable=broad-except
8885
self.check_errors(decoder, message)
8986

pymodbus/framer/old_framer_ascii.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def frameProcessIncomingPacket(self, single, callback, slave, tid=None):
5757
return
5858
self._buffer = self._buffer[used_len :]
5959
continue
60-
self._header["uid"] = dev_id
60+
self.dev_id = dev_id
6161
if not self._validate_slave_id(slave, single):
6262
Log.error("Not a valid slave id - {}, ignoring!!", dev_id)
6363
self.resetFrame()
@@ -67,5 +67,5 @@ def frameProcessIncomingPacket(self, single, callback, slave, tid=None):
6767
raise ModbusIOException("Unable to decode response")
6868
self.populateResult(result)
6969
self._buffer = self._buffer[used_len :]
70-
self._header = {"uid": 0x00}
70+
self.dev_id = 0
7171
callback(result) # defer this

pymodbus/framer/old_framer_base.py

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
import time
6-
from typing import TYPE_CHECKING, Any
6+
from typing import TYPE_CHECKING
77

88
from pymodbus.factory import ClientDecoder, ServerDecoder
99
from pymodbus.framer.base import FramerBase
@@ -41,20 +41,10 @@ def __init__(
4141
"""
4242
self.decoder = decoder
4343
self.client = client
44-
self._header: dict[str, Any]
45-
self._reset_header()
4644
self._buffer = b""
4745
self.message_handler: FramerBase
48-
49-
def _reset_header(self) -> None:
50-
self._header = {
51-
"lrc": "0000",
52-
"len": 0,
53-
"uid": 0x00,
54-
"tid": 0,
55-
"pid": 0,
56-
"crc": b"\x00\x00",
57-
}
46+
self.tid = 0
47+
self.dev_id = 0
5848

5949
def _validate_slave_id(self, slaves: list, single: bool) -> bool:
6050
"""Validate if the received data is valid for the client.
@@ -69,7 +59,7 @@ def _validate_slave_id(self, slaves: list, single: bool) -> bool:
6959
# Handle Modbus TCP slave identifier (0x00 0r 0xFF)
7060
# in asynchronous requests
7161
return True
72-
return self._header["uid"] in slaves
62+
return self.dev_id in slaves
7363

7464
def sendPacket(self, message: bytes):
7565
"""Send packets on the bus.
@@ -104,14 +94,8 @@ def resetFrame(self):
10494
"Resetting frame - Current Frame in buffer - {}", self._buffer, ":hex"
10595
)
10696
self._buffer = b""
107-
self._header = {
108-
"lrc": "0000",
109-
"crc": b"\x00\x00",
110-
"len": 0,
111-
"uid": 0x00,
112-
"pid": 0,
113-
"tid": 0,
114-
}
97+
self.dev_id = 0
98+
self.tid = 0
11599

116100
def populateResult(self, result):
117101
"""Populate the modbus result header.
@@ -121,9 +105,9 @@ def populateResult(self, result):
121105
122106
:param result: The response packet
123107
"""
124-
result.slave_id = self._header.get("uid", 0)
125-
result.transaction_id = self._header.get("tid", 0)
126-
result.protocol_id = self._header.get("pid", 0)
108+
result.slave_id = self.dev_id
109+
result.transaction_id = self.tid
110+
result.protocol_id = 0
127111

128112
def processIncomingPacket(self, data: bytes, callback, slave, single=False, tid=None):
129113
"""Process new packet pattern.

pymodbus/framer/old_framer_rtu.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def __init__(self, decoder, client=None):
6060
self._hsize = 0x01
6161
self.function_codes = decoder.lookup.keys() if decoder else {}
6262
self.message_handler = FramerRTU()
63+
self.msg_len = 0
6364

6465
def decode_data(self, data):
6566
"""Decode data."""
@@ -75,20 +76,17 @@ def frameProcessIncomingPacket(self, _single, callback, slave, tid=None): # noq
7576

7677
def is_frame_ready(self):
7778
"""Check if we should continue decode logic."""
78-
size = self._header.get("len", 0)
79+
size = self.msg_len
7980
if not size and len(self._buffer) > self._hsize:
8081
try:
81-
self._header["uid"] = int(self._buffer[0])
82-
self._header["tid"] = int(self._buffer[0])
83-
self._header["tid"] = 0 # fix for now
82+
self.dev_id = int(self._buffer[0])
8483
func_code = int(self._buffer[1])
8584
pdu_class = self.decoder.lookupPduClass(func_code)
8685
size = pdu_class.calculateRtuFrameSize(self._buffer)
87-
self._header["len"] = size
86+
self.msg_len = size
8887

8988
if len(self._buffer) < size:
9089
raise IndexError
91-
self._header["crc"] = self._buffer[size - 2 : size]
9290
except IndexError:
9391
return False
9492
return len(self._buffer) >= size if size > 0 else False
@@ -116,20 +114,17 @@ def get_frame_start(self, slaves, broadcast, skip_cur_frame):
116114
def check_frame(self):
117115
"""Check if the next frame is available."""
118116
try:
119-
self._header["uid"] = int(self._buffer[0])
120-
self._header["tid"] = int(self._buffer[0])
121-
self._header["tid"] = 0 # fix for now
117+
self.dev_id = int(self._buffer[0])
122118
func_code = int(self._buffer[1])
123119
pdu_class = self.decoder.lookupPduClass(func_code)
124120
size = pdu_class.calculateRtuFrameSize(self._buffer)
125-
self._header["len"] = size
121+
self.msg_len = size
126122

127123
if len(self._buffer) < size:
128124
raise IndexError
129-
self._header["crc"] = self._buffer[size - 2 : size]
130-
frame_size = self._header["len"]
125+
frame_size = self.msg_len
131126
data = self._buffer[: frame_size - 2]
132-
crc = self._header["crc"]
127+
crc = self._buffer[size - 2 : size]
133128
crc_val = (int(crc[0]) << 8) + int(crc[1])
134129
return FramerRTU.check_CRC(data, crc_val)
135130
except (IndexError, KeyError, struct.error):
@@ -138,7 +133,8 @@ def check_frame(self):
138133
broadcast = not slave[0]
139134
skip_cur_frame = False
140135
while get_frame_start(self, slave, broadcast, skip_cur_frame):
141-
self._header = {"uid": 0x00, "len": 0, "crc": b"\x00\x00"}
136+
self.dev_id = 0
137+
self.msg_len = 0
142138
if not is_frame_ready(self):
143139
Log.debug("Frame - not ready")
144140
break
@@ -150,7 +146,7 @@ def check_frame(self):
150146
skip_cur_frame = True
151147
continue
152148
start = self._hsize
153-
end = self._header["len"] - 2
149+
end = self.msg_len - 2
154150
buffer = self._buffer[start:end]
155151
if end > 0:
156152
Log.debug("Getting Frame - {}", buffer, ":hex")
@@ -159,9 +155,9 @@ def check_frame(self):
159155
data = b""
160156
if (result := self.decoder.decode(data)) is None:
161157
raise ModbusIOException("Unable to decode request")
162-
result.slave_id = self._header["uid"]
158+
result.slave_id = self.dev_id
163159
result.transaction_id = 0
164-
self._buffer = self._buffer[self._header["len"] :]
160+
self._buffer = self._buffer[self.msg_len :]
165161
Log.debug("Frame advanced, resetting header!!")
166162
callback(result) # defer or push to a thread?
167163

pymodbus/framer/old_framer_socket.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,10 @@ def __init__(self, decoder, client=None):
4747
def decode_data(self, data):
4848
"""Decode data."""
4949
if len(data) > self._hsize:
50-
tid, pid, length, uid, fcode = struct.unpack(
50+
_tid, _pid, length, uid, fcode = struct.unpack(
5151
SOCKET_FRAME_HEADER, data[0 : self._hsize + 1]
5252
)
5353
return {
54-
"tid": tid,
55-
"pid": pid,
5654
"length": length,
5755
"slave": uid,
5856
"fcode": fcode,
@@ -77,9 +75,8 @@ def frameProcessIncomingPacket(self, single, callback, slave, tid=None):
7775
used_len, use_tid, dev_id, data = self.message_handler.decode(self._buffer)
7876
if not data:
7977
return
80-
self._header["uid"] = dev_id
81-
self._header["tid"] = use_tid
82-
self._header["pid"] = 0
78+
self.dev_id = dev_id
79+
self.tid = use_tid
8380
if not self._validate_slave_id(slave, single):
8481
Log.debug("Not a valid slave id - {}, ignoring!!", dev_id)
8582
self.resetFrame()
@@ -89,7 +86,6 @@ def frameProcessIncomingPacket(self, single, callback, slave, tid=None):
8986
raise ModbusIOException("Unable to decode request")
9087
self.populateResult(result)
9188
self._buffer: bytes = self._buffer[used_len:]
92-
self._reset_header()
9389
if tid and tid != result.transaction_id:
9490
self.resetFrame()
9591
else:

pymodbus/framer/old_framer_tls.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,12 @@ def frameProcessIncomingPacket(self, _single, callback, _slave, tid=None):
5656
used_len, use_tid, dev_id, data = self.message_handler.decode(self._buffer)
5757
if not data:
5858
return
59-
self._header["uid"] = dev_id
60-
self._header["tid"] = use_tid
61-
self._header["pid"] = 0
59+
self.dev_id = dev_id
60+
self.tid = use_tid
6261

6362
if (result := self.decoder.decode(data)) is None:
6463
self.resetFrame()
6564
raise ModbusIOException("Unable to decode request")
6665
self.populateResult(result)
6766
self._buffer: bytes = self._buffer[used_len:]
68-
self._reset_header()
6967
callback(result) # defer or push to a thread?

test/framers/test_framer.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,17 @@ async def test_framer_decode(self, dummy_framer, data, res_id, res_tid, res_len
7474
assert res_data == t_data
7575

7676
@pytest.mark.parametrize(
77-
("data", "dev_id", "tid", "res_data"), [
77+
("data", "dev_id", "tr_id", "res_data"), [
7878
(b'\x01\x02', 5, 6, b'\x05\x06\x01\x02'),
7979
(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09', 17, 25, b'\x11\x19\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09'),
8080
])
81-
async def test_framer_encode(self, dummy_framer, data, dev_id, tid, res_data):
81+
async def test_framer_encode(self, dummy_framer, data, dev_id, tr_id, res_data):
8282
"""Test decode method in all types."""
83-
t_data = dummy_framer.handle.encode(data, dev_id, tid)
83+
t_data = dummy_framer.handle.encode(data, dev_id, tr_id)
8484
assert res_data == t_data
8585

8686
@pytest.mark.parametrize(
87-
("func", "lrc", "expect"),
87+
("func", "test_compare", "expect"),
8888
[(FramerAscii.check_LRC, 0x1c, True),
8989
(FramerAscii.check_LRC, 0x0c, False),
9090
(FramerAscii.compute_LRC, None, 0x1c),
@@ -93,10 +93,10 @@ async def test_framer_encode(self, dummy_framer, data, dev_id, tid, res_data):
9393
(FramerRTU.compute_CRC, None, 0xE2DB),
9494
]
9595
)
96-
def test_LRC_CRC(self, func, lrc, expect):
96+
def test_LRC_CRC(self, func, test_compare, expect):
9797
"""Test check_LRC."""
9898
data = b'\x12\x34\x23\x45\x34\x56\x45\x67'
99-
assert expect == func(data, lrc) if lrc else func(data)
99+
assert expect == func(data, test_compare) if test_compare else func(data)
100100

101101
def test_roundtrip_LRC(self):
102102
"""Test combined compute/check LRC."""
@@ -226,23 +226,23 @@ class TestFramerType:
226226
]
227227
)
228228
@pytest.mark.parametrize(
229-
("inx3", "tid"),
229+
("inx3", "tr_id"),
230230
[
231231
(0, 0),
232232
(9, 3077),
233233
]
234234
)
235-
def test_encode_type(self, frame, frame_expected, data, dev_id, tid, inx1, inx2, inx3):
235+
def test_encode_type(self, frame, frame_expected, data, dev_id, tr_id, inx1, inx2, inx3):
236236
"""Test encode method."""
237-
if frame == FramerTLS and dev_id + tid:
237+
if frame == FramerTLS and dev_id + tr_id:
238238
return
239239
frame_obj = frame()
240240
expected = frame_expected[inx1 + inx2 + inx3]
241-
encoded_data = frame_obj.encode(data, dev_id, tid)
241+
encoded_data = frame_obj.encode(data, dev_id, tr_id)
242242
assert encoded_data == expected
243243

244244
@pytest.mark.parametrize(
245-
("entry", "is_server", "data", "dev_id", "tid", "expected"),
245+
("entry", "is_server", "data", "dev_id", "tr_id", "expected"),
246246
[
247247
(FramerType.ASCII, True, b':0003007C00027F\r\n', 0, 0, b"\x03\x00\x7c\x00\x02",), # Request
248248
(FramerType.ASCII, False, b':000304008D008EDE\r\n', 0, 0, b"\x03\x04\x00\x8d\x00\x8e",), # Response
@@ -293,7 +293,7 @@ def test_encode_type(self, frame, frame_expected, data, dev_id, tid, inx1, inx2,
293293
"single",
294294
]
295295
)
296-
async def test_decode_type(self, entry, dummy_framer, data, dev_id, tid, expected, split):
296+
async def test_decode_type(self, entry, dummy_framer, data, dev_id, tr_id, expected, split):
297297
"""Test encode method."""
298298
if entry == FramerType.TLS and split != "no":
299299
return
@@ -314,7 +314,7 @@ async def test_decode_type(self, entry, dummy_framer, data, dev_id, tid, expecte
314314
dummy_framer.callback_request_response.assert_not_called()
315315
used_len = dummy_framer.callback_data(data)
316316
assert used_len == len(data)
317-
dummy_framer.callback_request_response.assert_called_with(expected, dev_id, tid)
317+
dummy_framer.callback_request_response.assert_called_with(expected, dev_id, tr_id)
318318

319319
@pytest.mark.parametrize(
320320
("entry", "data", "exp"),

0 commit comments

Comments
 (0)