Repository: pymodbus-dev/pymodbus

Issue:
tiemout parameter can not be changed. Always takes 3.0 seconds
<!--
Please use the Pymodbus gitter channel at https://gitter.im/pymodbus_dev/Lobby or Stack Overflow(tag [pymodbus](https://stackoverflow.com/questions/tagged/pymodbus) for
support questions.

Before opening a new issue, make sure you do the following:
    * check that your issue isn't already filed: https://github.com/riptideio/pymodbus/issues
    * check the discussions forum https://github.com/riptideio/pymodbus/discussions
    * prepare a short, runnable example that reproduce the issue with the latest development version of Pymodbus
-->

### Versions

* Python: 3.8
* OS: ubuntu 20.04
* Pymodbus: 2.5.3
* Modbus Hardware (if used): SHT20 Temperature Sensor

### Pymodbus Specific
* Server: N/A
* Client: serial rtu-async

### Description
No matter the timeout I set, it always takes 3.0 seconds when the modbus peripheral has an issue.

What were you trying, what has happened, what went wrong, and what did you expect?
The sensor fails from time to time. Most of the time is ok, but sometimes is not processing modbus requests. So we are aware of this issue, but we expected the pymodbus library timeout in the given timeout parameter, But it does not. Always takes 3.0 seconds

### Code and Logs

```
# code and logs here.
loop, client =  AsyncModbusSerialClient(schedulers.ASYNC_IO, port=self.commPort, baudrate=self.commSpeed, method=self.modbusMode, timeout=self.commTimeout, loop=fakeLoop)

# please use the following to format logs when posting them here
import pymodbus
pymodbus.pymodbus_apply_logging_config()
```



Discussion:
You need to supply a log otherwise we cannot see what happens.

Did you try e.g. with timeout=10 to check if 3 is just your minimum.

Which values did you try less than 3, supply logs please.

And I just saw you are using 2.5.3, that version have many known issues with timeout especially in async, please upgrade to 3.0.0
This is present in 3.0, I supplied timeout of 30.0s to the AsyncModbusTcpClient and it still timeouts at 3.0s. When the class is initialized the variable seems to be fine. but when it connects to the device and you have a .protocol property, the timeout value in that protocol is 3.0 seconds.
This dirty workaround is implemented on my end to force it to wait the actual timeout, but this needs to be fixed.
```py
client.protocol.params.timeout = 30
client.protocol.transaction.client.params.timeout = 30
```
Thanks for the research, I will take a look soon and expect to solve it before 3.0.1 is released.

Resolving patch:
diff --git a/pymodbus/client/tcp.py b/pymodbus/client/tcp.py
--- a/pymodbus/client/tcp.py
+++ b/pymodbus/client/tcp.py
@@ -77,7 +77,16 @@ async def close(self):  # pylint: disable=invalid-overridden-method
     def _create_protocol(self):
         """Create initialized protocol instance with factory function."""
         protocol = ModbusClientProtocol(
-            framer=self.params.framer, xframer=self.framer, **self.params.kwargs
+            framer=self.params.framer,
+            xframer=self.framer,
+            timeout=self.params.timeout,
+            retries=self.params.retries,
+            retry_on_empty=self.params.retry_on_empty,
+            close_comm_on_error=self.params.close_comm_on_error,
+            strict=self.params.strict,
+            broadcast_enable=self.params.broadcast_enable,
+            reconnect_delay=self.params.reconnect_delay,
+            **self.params.kwargs,
         )
         protocol.factory = self
         return protocol
diff --git a/pymodbus/client/udp.py b/pymodbus/client/udp.py
--- a/pymodbus/client/udp.py
+++ b/pymodbus/client/udp.py
@@ -99,6 +99,13 @@ def _create_protocol(self, host=None, port=0):
             use_udp=True,
             framer=self.params.framer,
             xframer=self.framer,
+            timeout=self.params.timeout,
+            retries=self.params.retries,
+            retry_on_empty=self.params.retry_on_empty,
+            close_comm_on_error=self.params.close_comm_on_error,
+            strict=self.params.strict,
+            broadcast_enable=self.params.broadcast_enable,
+            reconnect_delay=self.params.reconnect_delay,
             **self.params.kwargs,
         )
         protocol.params.host = host


Test patch: