From 794978239eba2c2aaf9d4e040f2227fccae0db3a Mon Sep 17 00:00:00 2001 From: Benjamin Braatz Date: Tue, 16 Feb 2021 11:30:43 +0100 Subject: [PATCH] Retry modbus send if no answer --- gmodbus/transport.py | 56 ++++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/gmodbus/transport.py b/gmodbus/transport.py index 8405eec..89678b5 100644 --- a/gmodbus/transport.py +++ b/gmodbus/transport.py @@ -168,29 +168,35 @@ class SerialClient(ClientInterface): return value async def __send_message(self, message: bytes) -> List[int]: - await self.__port.write(message) - - # Check exception ADU (which is shorter than all other responses) first. - exception_adu_size = 5 - response_error_adu = b'' - try: - response_error_adu = await asyncio.wait_for(self.__port.read(exception_adu_size), timeout=1.0) - except asyncio.TimeoutError: - print("modbus read timed out") - rtu.raise_for_exception_adu(response_error_adu) - - expected_response_size = \ + success = False + while not success: + success = True + + await self.__port.write(message) + + # Check exception ADU (which is shorter than all other responses) first. + exception_adu_size = 5 + response_error_adu = b'' + try: + response_error_adu = await asyncio.wait_for(self.__port.read(exception_adu_size), timeout=0.1) + rtu.raise_for_exception_adu(response_error_adu) + except asyncio.TimeoutError: + print("modbus read timed out for response_error_adu") + exception_adu_size = 0 + + expected_response_size = \ expected_response_pdu_size_from_request_pdu(message[1:-2]) + 3 - response_remainder = b'' - try: - response_remainder = await asyncio.wait_for(self.__port.read(expected_response_size - exception_adu_size), timeout=1.0) - except asyncio.TimeoutError: - print("modbus read timed out") - - response = response_error_adu + response_remainder - if len(response) < expected_response_size: - return [] - result = rtu.parse_response_adu(response, message) - if not isinstance(result, list): - return [result] - return result + response_remainder = b'' + try: + response_remainder = await asyncio.wait_for(self.__port.read(expected_response_size - exception_adu_size), timeout=0.1) + except asyncio.TimeoutError: + print("modbus read timed out for response_remainder, retrying") + success = False + + response = response_error_adu + response_remainder + if len(response) < expected_response_size: + return [] + result = rtu.parse_response_adu(response, message) + if not isinstance(result, list): + return [result] + return result -- 2.34.1