Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 26 additions & 28 deletions pymodbus/transaction/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,20 @@ def _io_exception_from_request(
dev_id=request.dev_id,
)

def _no_response(self, request: ModbusPDU) -> ModbusIOException:
"""Count a request that got no response, and build the exception to raise."""
if self.count_until_disconnect < 0:
if self.comm_params.comm_type != CommType.SERIAL:
self.connection_lost(asyncio.TimeoutError("Server not responding"))
return self._io_exception_from_request(
"ERROR: No response received of the last requests (default: retries+3), CLOSING CONNECTION.",
request,
)
self.count_until_disconnect -= 1
txt = f"No response received after {self.retries} retries, continue with next request"
Log.error(txt)
return self._io_exception_from_request(txt, request)

def sync_execute(self, no_response_expected: bool, request: ModbusPDU) -> ModbusPDU:
"""Execute requests asynchronously.

Expand Down Expand Up @@ -173,32 +187,26 @@ def sync_execute(self, no_response_expected: bool, request: ModbusPDU) -> Modbus
return response
except asyncio.exceptions.TimeoutError:
count_retries += 1
if self.count_until_disconnect < 0:
if self.comm_params.comm_type != CommType.SERIAL:
self.connection_lost(asyncio.TimeoutError("Server not responding"))
raise self._io_exception_from_request(
"ERROR: No response received of the last requests (default: retries+3), CLOSING CONNECTION.",
request,
raise self._no_response(request)

async def _connect_if_needed(self) -> None:
"""Connect if there is no transport."""
if not self.transport:
Log.warning("Not connected, trying to connect!")
if not await self.connect():
raise ConnectionException(
"Client cannot connect (automatic retry continuing) !!"
)
self.count_until_disconnect -= 1
txt = f"No response received after {self.retries} retries, continue with next request"
Log.error(txt)
raise self._io_exception_from_request(txt, request)

async def execute( # noqa: C901
async def execute(
self, no_response_expected: bool, request: ModbusPDU
) -> ModbusPDU:
"""Execute requests asynchronously.

REMARK: this method is identical to sync_execute, apart from the lock, try/except
and the wait after a cancel. any changes in either method MUST be mirrored !!!
"""
if not self.transport:
Log.warning("Not connected, trying to connect!")
if not await self.connect():
raise ConnectionException(
"Client cannot connect (automatic retry continuing) !!"
)
await self._connect_if_needed()
async with self._lock:
cancel_key = (request.dev_id, request.function_code)
if cancelled := self.cancelled_requests.pop(cancel_key, None):
Expand Down Expand Up @@ -249,17 +257,7 @@ async def execute( # noqa: C901
monotonic() + self.comm_params.timeout_connect,
)
raise
if self.count_until_disconnect < 0:
if self.comm_params.comm_type != CommType.SERIAL:
self.connection_lost(asyncio.TimeoutError("Server not responding"))
raise self._io_exception_from_request(
"ERROR: No response received of the last requests (default: retries+3), CLOSING CONNECTION.",
request,
)
self.count_until_disconnect -= 1
txt = f"No response received after {self.retries} retries, continue with next request"
Log.error(txt)
raise self._io_exception_from_request(txt, request)
raise self._no_response(request)

def pdu_send(self, pdu: ModbusPDU, addr: tuple | None = None) -> None:
"""Build byte stream and send."""
Expand Down
Loading