Repository: pymodbus-dev/pymodbus

Issue:
Retry logic fails when retries parameter is set to 1
### Versions

- Python: 3.11
- OS: Linux
- Pymodbus: 3.4.1

### Pymodbus Specific

- Client: tcp - async

### Description

The `async_execute` method of `ModbusBaseClient` includes a retry logic, which does not work properly if the value of `retries` parameter is 1. In this case, even if the response is received successfully, the method raises `ModbusIOException`.

It can be assumed that this issue is related to #1702. Because, setting the value of `retries` parameter to 1 can be used as a workaround for #1702.

### Code and Logs

```python
import asyncio
import logging

from pymodbus import pymodbus_apply_logging_config
from pymodbus.client import AsyncModbusTcpClient
from pymodbus.exceptions import ModbusException

logger = logging.getLogger()


async def main() -> None:
    pymodbus_apply_logging_config()
    try:
        async with AsyncModbusTcpClient("10.10.2.23", retries=1) as client:
            response = await client.read_holding_registers(38, 2, slave=247)
            if not response.isError():
                logger.info(response.registers)
    except ModbusException as err:
        logger.error(err)


if __name__ == "__main__":
    asyncio.run(main())
```

```shell
2023-08-13 02:04:38,188 DEBUG logging:102 Connecting to 10.10.2.23:502.
2023-08-13 02:04:38,188 DEBUG logging:102 Connecting comm
2023-08-13 02:04:40,117 DEBUG logging:102 Connected to comm
2023-08-13 02:04:40,118 DEBUG logging:102 callback_connected called
2023-08-13 02:04:40,119 DEBUG logging:102 send: 0x0 0x1 0x0 0x0 0x0 0x6 0xf7 0x3 0x0 0x26 0x0 0x2
2023-08-13 02:04:40,119 DEBUG logging:102 Adding transaction 1
2023-08-13 02:04:40,487 DEBUG logging:102 recv: 0x0 0x1 0x0 0x0 0x0 0x7 0xf7 0x3 0x4 0xc1 0xe 0xa8 0x0 addr=None
2023-08-13 02:04:40,488 DEBUG logging:102 Processing: 0x0 0x1 0x0 0x0 0x0 0x7 0xf7 0x3 0x4 0xc1 0xe 0xa8 0x0
2023-08-13 02:04:40,488 DEBUG logging:102 Factory Response[ReadHoldingRegistersResponse': 3]
2023-08-13 02:04:40,488 DEBUG logging:102 Getting transaction 1
2023-08-13 02:04:40,488 DEBUG logging:102 Connection lost comm due to Server not responding
Modbus Error: [Input/Output] ERROR: No response received after 1 retries
```


Discussion:

Resolving patch:
diff --git a/pymodbus/client/base.py b/pymodbus/client/base.py
--- a/pymodbus/client/base.py
+++ b/pymodbus/client/base.py
@@ -198,13 +198,14 @@ async def async_execute(self, request=None):
             while count < self.params.retries:
                 count += 1
                 try:
+                    req = self._build_response(request.transaction_id)
                     resp = await asyncio.wait_for(
                         req, timeout=self.comm_params.timeout_connect
                     )
                     break
                 except asyncio.exceptions.TimeoutError:
                     pass
-            if count == self.params.retries:
+            if count > self.params.retries:
                 self.close(reconnect=True)
                 raise ModbusIOException(
                     f"ERROR: No response received after {self.params.retries} retries"


Test patch: