Skip to content

Commit 0a1c01c

Browse files
Use response byte length if available
Co-authored-by: jan Iversen <jancasacondor@gmail.com>
1 parent f7fe305 commit 0a1c01c

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

pymodbus/framer/rtu_framer.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,9 @@ def populateHeader(self, data=None): # pylint: disable=invalid-name
153153
`self._buffer` is not yet long enough.
154154
"""
155155
data = data if data is not None else self._buffer
156-
self._header["uid"] = int(data[0])
157-
func_code = int(data[1])
158-
pdu_class = self.decoder.lookupPduClass(func_code)
159-
size = pdu_class.calculateRtuFrameSize(data)
160-
self._header["len"] = size
156+
self._header['uid'] = int(data[0])
157+
size = self.get_expected_response_length(data)
158+
self._header['len'] = size
161159

162160
if len(data) < size:
163161
# crc yet not available
@@ -330,5 +328,15 @@ def getRawFrame(self): # pylint: disable=invalid-name
330328
_logger.debug(txt)
331329
return self._buffer
332330

331+
def get_expected_response_length(self, data):
332+
"""Get the expected response length.
333+
334+
:param data: Message data read so far
335+
:raises IndexError: If not enough data to read byte count
336+
:return: Total frame size
337+
"""
338+
func_code = int(data[1])
339+
pdu_class = self.decoder.lookupPduClass(func_code)
340+
return pdu_class.calculateRtuFrameSize(data)
333341

334342
# __END__

pymodbus/transaction.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ def _recv(self, expected_response_length, full): # NOSONAR
343343
if isinstance(self.client.framer, ModbusSocketFramer):
344344
min_size = 8
345345
elif isinstance(self.client.framer, ModbusRtuFramer):
346-
min_size = 2
346+
min_size = 4
347347
elif isinstance(self.client.framer, ModbusAsciiFramer):
348348
min_size = 5
349349
elif isinstance(self.client.framer, ModbusBinaryFramer):
@@ -362,7 +362,7 @@ def _recv(self, expected_response_length, full): # NOSONAR
362362
if isinstance(self.client.framer, ModbusSocketFramer):
363363
func_code = int(read_min[-1])
364364
elif isinstance(self.client.framer, ModbusRtuFramer):
365-
func_code = int(read_min[-1])
365+
func_code = int(read_min[1])
366366
elif isinstance(self.client.framer, ModbusAsciiFramer):
367367
func_code = int(read_min[3:5], 16)
368368
elif isinstance(self.client.framer, ModbusBinaryFramer):
@@ -378,6 +378,12 @@ def _recv(self, expected_response_length, full): # NOSONAR
378378
)
379379
length = struct.unpack(">H", read_min[4:6])[0] - 1
380380
expected_response_length = h_size + length
381+
elif expected_response_length is None and isinstance(self.client.framer, ModbusRtuFramer):
382+
try:
383+
expected_response_length = self.client.framer.get_expected_response_length(read_min)
384+
except IndexError:
385+
# Could not determine response length with available bytes
386+
pass
381387
if expected_response_length is not None:
382388
expected_response_length -= min_size
383389
total = expected_response_length + min_size

0 commit comments

Comments
 (0)