Skip to content

Commit 7650421

Browse files
committed
Fix #387 Transactions failing on 2.2.0rc2.
1 parent f66f464 commit 7650421

File tree

4 files changed

+37
-24
lines changed

4 files changed

+37
-24
lines changed

CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ from pymodbus.client.asynchronous import ModbusTcpClient
1818
* Support broadcasting in Modbus Client and Servers (sync).
1919
* Fix asyncio examples.
2020
* Improved logging in Modbus Server .
21+
* Fix regression introduced in 2.2.0rc2 (Modbus sync client transaction failing)
2122
* Minor update in factory.py, now server logs prints received request instead of only function code
2223

2324
```

pymodbus/server/sync.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,21 @@ def handle(self):
181181
reset_frame = False
182182
while self.running:
183183
try:
184+
units = self.server.context.slaves()
184185
data = self.request.recv(1024)
185186
if not data:
186187
self.running = False
188+
else:
189+
if not isinstance(units, (list, tuple)):
190+
units = [units]
191+
# if broadcast is enabled make sure to
192+
# process requests to address 0
193+
if self.server.broadcast_enable:
194+
if 0 not in units:
195+
units.append(0)
196+
187197
if _logger.isEnabledFor(logging.DEBUG):
188198
_logger.debug('Handling data: ' + hexlify_packets(data))
189-
# if not self.server.control.ListenOnly:
190-
191-
units = self.server.context.slaves()
192199
single = self.server.context.single
193200
self.framer.processIncomingPacket(data, self.execute, units,
194201
single=single)

pymodbus/transaction.py

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,17 @@ def execute(self, request):
112112
)
113113
retries = self.retries
114114
request.transaction_id = self.getNextTID()
115-
_logger.debug("Running transaction %d" % request.transaction_id)
115+
_logger.debug("Running transaction "
116+
"{}".format(request.transaction_id))
116117
_buffer = hexlify_packets(self.client.framer._buffer)
117118
if _buffer:
118-
_logger.debug("Clearing current Frame : - {}".format(_buffer))
119+
_logger.debug("Clearing current Frame "
120+
": - {}".format(_buffer))
119121
self.client.framer.resetFrame()
120-
121-
if request.unit_id == 0 and self.client.broadcast_enable:
122-
response, last_exception = self._transact(request, None)
122+
broadcast = (self.client.broadcast_enable
123+
and request.unit_id == 0)
124+
if broadcast:
125+
self._transact(request, None, broadcast=True)
123126
response = b'Broadcast write sent - no response expected'
124127
else:
125128
expected_response_length = None
@@ -139,10 +142,12 @@ def execute(self, request):
139142
full = True
140143
if not expected_response_length:
141144
expected_response_length = Defaults.ReadSize
142-
response, last_exception = self._transact(request,
143-
expected_response_length,
144-
full=full
145-
)
145+
response, last_exception = self._transact(
146+
request,
147+
expected_response_length,
148+
full=full,
149+
broadcast=broadcast
150+
)
146151
if not response and (
147152
request.unit_id not in self._no_response_devices):
148153
self._no_response_devices.append(request.unit_id)
@@ -193,7 +198,7 @@ def execute(self, request):
193198
self.client.state = ModbusTransactionState.TRANSACTION_COMPLETE
194199
return ex
195200

196-
def _transact(self, packet, response_length, full=False):
201+
def _transact(self, packet, response_length, full=False, broadcast=False):
197202
"""
198203
Does a Write and Read transaction
199204
:param packet: packet to be sent
@@ -209,20 +214,20 @@ def _transact(self, packet, response_length, full=False):
209214
if _logger.isEnabledFor(logging.DEBUG):
210215
_logger.debug("SEND: " + hexlify_packets(packet))
211216
size = self._send(packet)
212-
if response_length is not None:
213-
if size:
214-
_logger.debug("Changing transaction state from 'SENDING' "
215-
"to 'WAITING FOR REPLY'")
216-
self.client.state = ModbusTransactionState.WAITING_FOR_REPLY
217-
result = self._recv(response_length, full)
218-
if _logger.isEnabledFor(logging.DEBUG):
219-
_logger.debug("RECV: " + hexlify_packets(result))
220-
else:
217+
if broadcast:
221218
if size:
222219
_logger.debug("Changing transaction state from 'SENDING' "
223220
"to 'TRANSACTION_COMPLETE'")
224221
self.client.state = ModbusTransactionState.TRANSACTION_COMPLETE
225-
result = b''
222+
return b'', None
223+
if size:
224+
_logger.debug("Changing transaction state from 'SENDING' "
225+
"to 'WAITING FOR REPLY'")
226+
self.client.state = ModbusTransactionState.WAITING_FOR_REPLY
227+
result = self._recv(response_length, full)
228+
if _logger.isEnabledFor(logging.DEBUG):
229+
_logger.debug("RECV: " + hexlify_packets(result))
230+
226231
except (socket.error, ModbusIOException,
227232
InvalidMessageReceivedException) as msg:
228233
self.client.close()

pymodbus/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def __str__(self):
4141
return '[%s, version %s]' % (self.package, self.short())
4242

4343

44-
version = Version('pymodbus', 2, 2, 0, "rc2")
44+
version = Version('pymodbus', 2, 2, 0, "rc3")
4545

4646

4747
version.__name__ = 'pymodbus' # fix epydoc error

0 commit comments

Comments
 (0)