Skip to content

Commit 48ab8de

Browse files
authored
dev_id=0 no response expected (returns ExceptionResponse(0xff)). (#2567)
1 parent fe6136e commit 48ab8de

File tree

3 files changed

+21
-19
lines changed

3 files changed

+21
-19
lines changed

examples/client_async_calls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ async def async_execute_diagnostic_requests(client):
266266
assert not rr.isError() # test that call was OK
267267
rr = await client.diag_getclear_modbus_response(slave=SLAVE)
268268
assert not rr.isError() # test that call was OK
269-
assert not await client.diag_force_listen_only(slave=SLAVE, no_response_expected=True)
269+
rr = await client.diag_force_listen_only(slave=SLAVE, no_response_expected=True)
270+
assert rr.isError() # test that call was OK, error indicate no response
270271

271272

272273
# ------------------------

pymodbus/transaction/transaction.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def sync_execute(self, no_response_expected: bool, request: ModbusPDU) -> Modbus
102102
count_retries = 0
103103
while count_retries <= self.retries:
104104
self.pdu_send(request)
105-
if no_response_expected:
105+
if not request.dev_id or no_response_expected:
106106
return ExceptionResponse(0xff)
107107
try:
108108
return self.sync_get_response()
@@ -118,7 +118,7 @@ def sync_execute(self, no_response_expected: bool, request: ModbusPDU) -> Modbus
118118
Log.error(txt)
119119
raise ModbusIOException(txt)
120120

121-
async def execute(self, no_response_expected: bool, request: ModbusPDU) -> ModbusPDU | None:
121+
async def execute(self, no_response_expected: bool, request: ModbusPDU) -> ModbusPDU:
122122
"""Execute requests asynchronously.
123123
124124
REMARK: this method is identical to sync_execute, apart from the lock and try/except.
@@ -134,8 +134,8 @@ async def execute(self, no_response_expected: bool, request: ModbusPDU) -> Modbu
134134
while count_retries <= self.retries:
135135
self.response_future = asyncio.Future()
136136
self.pdu_send(request)
137-
if no_response_expected:
138-
return None
137+
if not request.dev_id or no_response_expected:
138+
return ExceptionResponse(0xff)
139139
try:
140140
response = await asyncio.wait_for(
141141
self.response_future, timeout=self.comm_params.timeout_connect

test/transaction/test_transaction.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from pymodbus.client import ModbusBaseSyncClient
88
from pymodbus.exceptions import ConnectionException, ModbusIOException
99
from pymodbus.framer import FramerRTU, FramerSocket, FramerType
10-
from pymodbus.pdu import DecodePDU
10+
from pymodbus.pdu import DecodePDU, ExceptionResponse
1111
from pymodbus.pdu.bit_message import ReadCoilsRequest, ReadCoilsResponse
1212
from pymodbus.transaction import TransactionManager
1313

@@ -134,8 +134,8 @@ async def test_transaction_execute(self, use_clc, scenario):
134134
None,
135135
)
136136
transact.send = mock.Mock()
137-
request = ReadCoilsRequest(address=117, count=5)
138-
response = ReadCoilsResponse(bits=[True, False, True, True, False])
137+
request = ReadCoilsRequest(address=117, count=5, dev_id=1)
138+
response = ReadCoilsResponse(bits=[True, False, True, True, False], dev_id=1)
139139
transact.retries = 0
140140
transact.connection_made(mock.AsyncMock())
141141
transact.transport.write = mock.Mock()
@@ -206,7 +206,7 @@ async def test_client_protocol_execute_outside(self, use_clc, no_resp):
206206
None,
207207
)
208208
transact.send = mock.Mock()
209-
request = ReadCoilsRequest(address=117, count=5)
209+
request = ReadCoilsRequest(address=117, count=5, dev_id=1)
210210
transact.retries = 0
211211
transact.connection_made(mock.AsyncMock())
212212
transact.transport.write = mock.Mock()
@@ -216,7 +216,8 @@ async def test_client_protocol_execute_outside(self, use_clc, no_resp):
216216
transact.data_received(data)
217217
result = await resp
218218
if no_resp:
219-
assert not result
219+
assert result.isError()
220+
assert isinstance(result, ExceptionResponse)
220221
else:
221222
assert not result.isError()
222223
assert isinstance(result, ReadCoilsResponse)
@@ -281,8 +282,8 @@ async def test_sync_transaction_execute(self, use_clc, scenario):
281282
)
282283
transact.send = mock.Mock()
283284
transact.sync_client.connect = mock.Mock(return_value=True)
284-
request = ReadCoilsRequest(address=117, count=5)
285-
response = ReadCoilsResponse(bits=[True, False, True, True, False, False, False, False])
285+
request = ReadCoilsRequest(address=117, count=5, dev_id=1)
286+
response = ReadCoilsResponse(bits=[True, False, True, True, False, False, False, False], dev_id=1)
286287
transact.retries = 0
287288
if scenario == 0: # transport not ok and no connect
288289
transact.transport = None
@@ -298,7 +299,7 @@ async def test_sync_transaction_execute(self, use_clc, scenario):
298299
transact.trace_packet = mock.Mock(return_value=b'123')
299300
transact.sync_execute(True, request)
300301
transact.trace_pdu.assert_called_once_with(True, request)
301-
transact.trace_packet.assert_called_once_with(True, b'\x00\x01\x00u\x00\x05\xec\x02')
302+
transact.trace_packet.assert_called_once_with(True, b'\x01\x01\x00u\x00\x05\xed\xd3')
302303
elif scenario == 3: # wait receive,timeout, no_responses
303304
transact.comm_params.timeout_connect = 0.1
304305
transact.count_no_responses = 10
@@ -339,8 +340,8 @@ def test_sync_transaction_receiver(self, use_clc):
339340
)
340341
transact.sync_client.connect = mock.Mock(return_value=True)
341342
transact.sync_client.send = mock.Mock()
342-
request = ReadCoilsRequest(address=117, count=5)
343-
response = ReadCoilsResponse(bits=[True, False, True, True, False, False, False, False])
343+
request = ReadCoilsRequest(address=117, count=5, dev_id=1)
344+
response = ReadCoilsResponse(bits=[True, False, True, True, False, False, False, False], dev_id=1)
344345
transact.retries = 0
345346
transact.transport = 1
346347
resp_bytes = transact.framer.buildFrame(response)
@@ -372,8 +373,8 @@ def test_sync_client_protocol_execute_outside(self, use_clc, no_resp):
372373
sync_client=client,
373374
)
374375
transact.sync_client.connect = mock.Mock(return_value=True)
375-
request = ReadCoilsRequest(address=117, count=5)
376-
response = ReadCoilsResponse(bits=[True, False, True, True, False, False, False, False])
376+
request = ReadCoilsRequest(address=117, count=5, dev_id=1)
377+
response = ReadCoilsResponse(bits=[True, False, True, True, False, False, False, False], dev_id=1)
377378
transact.retries = 0
378379
transact.transport = 1
379380
resp_bytes = transact.framer.buildFrame(response)
@@ -407,8 +408,8 @@ def test_sync_client_protocol_execute_no_pdu(self, use_clc):
407408
sync_client=client,
408409
)
409410
transact.sync_client.connect = mock.Mock(return_value=True)
410-
request = ReadCoilsRequest(address=117, count=5)
411-
response = ReadCoilsResponse(bits=[True, False, True, True, False, False, False, False])
411+
request = ReadCoilsRequest(address=117, count=5, dev_id=1)
412+
response = ReadCoilsResponse(bits=[True, False, True, True, False, False, False, False], dev_id=1)
412413
transact.retries = 0
413414
transact.transport = 1
414415
resp_bytes = transact.framer.buildFrame(response)[:-1]

0 commit comments

Comments
 (0)