Skip to content

Commit 4a05c01

Browse files
committed
#221 Fix read transactions for different framers
1 parent 621a90e commit 4a05c01

File tree

3 files changed

+35
-16
lines changed

3 files changed

+35
-16
lines changed

pymodbus/server/sync.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,12 @@ def handle(self):
101101
data = self.request.recv(1024)
102102
if data:
103103
if _logger.isEnabledFor(logging.DEBUG):
104-
_logger.debug(" ".join([hex(byte2int(x)) for x in data]))
105-
if not isinstance(self.framer, ModbusBinaryFramer):
104+
_logger.debug("recv: " + " ".join([hex(byte2int(x)) for x in data]))
105+
if isinstance(self.framer, ModbusRtuFramer):
106106
unit_address = byte2int(data[0])
107-
else:
107+
elif isinstance(self.framer, ModbusAsciiFramer):
108+
unit_address = int(data[1:3], 16)
109+
if isinstance(self.framer, ModbusBinaryFramer):
108110
unit_address = byte2int(data[1])
109111
if unit_address in self.server.context:
110112
self.framer.processIncomingPacket(data, self.execute)
@@ -114,6 +116,7 @@ def handle(self):
114116
self.framer.resetFrame()
115117
_logger.error("Socket error occurred %s" % msg)
116118

119+
117120
def send(self, message):
118121
''' Send a request (string) to the network
119122

pymodbus/transaction.py

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import struct
66
import socket
77
from binascii import b2a_hex, a2b_hex
8-
8+
from serial import SerialException
99
from pymodbus.exceptions import ModbusIOException, NotImplementedException
1010
from pymodbus.exceptions import InvalidMessageRecievedException
1111
from pymodbus.constants import Defaults
@@ -57,13 +57,13 @@ def __init__(self, client, **kwargs):
5757
def _set_adu_size(self):
5858
# base ADU size of modbus frame in bytes
5959
if isinstance(self.client.framer, ModbusSocketFramer):
60-
self.base_adu_size = 7 # tid(2), pid(2), length(2), uid(1)
60+
self.base_adu_size = 7 # tid(2), pid(2), length(2), uid(1)
6161
elif isinstance(self.client.framer, ModbusRtuFramer):
62-
self.base_adu_size = 3 # address(1), CRC(2)
62+
self.base_adu_size = 3 # address(1), CRC(2)
6363
elif isinstance(self.client.framer, ModbusAsciiFramer):
64-
self.base_adu_size = 7 # start(1)+ Address(2), LRC(2) + end(2)
64+
self.base_adu_size = 7 # start(1)+ Address(2), LRC(2) + end(2)
6565
elif isinstance(self.client.framer, ModbusBinaryFramer):
66-
self.base_adu_size = 3 #, Address(1), CRC(2)
66+
self.base_adu_size = 5 # start(1) + Address(1), CRC(2) + end(1)
6767
else:
6868
self.base_adu_size = -1
6969

@@ -169,20 +169,35 @@ def _recv(self, expected_response_length):
169169
expected_response_length = self._calculate_exception_length()
170170
continue
171171
if isinstance(self.client.framer, ModbusSocketFramer):
172-
length = struct.unpack(">H", result[4:6])[0] -1 # Ommit UID, which is included in header size
173-
expected_response_length = self.client.framer._ModbusSocketFramer__hsize + length
174-
175-
r = self.client._recv(expected_response_length - len(result))
176-
if not r:
177-
# If no response being recived there is no point in conitnuing
172+
# Ommit UID, which is included in header size
173+
h_size = self.client.framer._ModbusSocketFramer__hsize
174+
length = struct.unpack(">H", result[4:6])[0] -1
175+
expected_response_length = h_size + length
176+
177+
if expected_response_length != len(result):
178+
_logger.debug("Expected - {} bytes, "
179+
"Actual - {} bytes".format(
180+
expected_response_length, len(result))
181+
)
182+
try:
183+
r = self.client._recv(
184+
expected_response_length - len(result)
185+
)
186+
result += r
187+
if not r:
188+
# If no response being recived there
189+
# is no point in conitnuing
190+
break
191+
except (TimeoutError, SerialException):
192+
break
193+
else:
178194
break
179-
result += r
195+
180196
if result:
181197
break
182198
retries -= 1
183199
return result
184200

185-
186201
def addTransaction(self, request, tid=None):
187202
''' Adds a transaction to the handler
188203

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
six==1.11.0
12
# -------------------------------------------------------------------
23
# if want to use the pymodbus serial stack, uncomment these
34
# -------------------------------------------------------------------

0 commit comments

Comments
 (0)