Repository: pymodbus-dev/pymodbus

Issue:
Minimum client timeout 1s?
<!--
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.11
* OS: macOS
* Pymodbus: 3.0
* Modbus Hardware (if used):

### Pymodbus Specific
* Server: tcp - sync
* Client: tcp - sync

### Description

The minimum timeout that can be set on a client is one seconds as the timeout parameter is an int and at 0 it does not connect. Wouldn't it be better to have timeout as a float to be able to specify tighter timeouts especially for TCP clients?

### Code and Logs

None



Discussion:
Pull requests are welcome.
I understand, but this seems to be a design decision and I have no idea what would break if this would be turned into a float. Beyond my horizon. Sorry.

With pymodbus 2.5.3 a float such as 0.3 was accepted and the client connected fine. Now that 0.3 gets converted to int(0.3)=0 and connection fails.
Yes it is a design decision, not due to the speed of the communication but actually more due to the speed of some slow devices.But decisions can be changed as long as you do not expect us to make it.


And btw. when changing something you test it and that is how you see if something broke.
This is new to me as well, we shouldn't be doing the conversion for float to int and process it as it is. It is the responsibility of the user to use the correct timeouts depending on the modbus device under use. 
But in any case, since the timeout is the max time allowed to wait for response and if the device can respond faster everything is good. Let's keep this as an low priority enhancement /change request and track it later if required.
Not a blocker for me, but an incompatibility between the previous version and 3.x. Had my TCP sync client timeout set to 0.3 with the result that it did not connect any longer.
Let us just take this down a notch, before telling what should not be done!

We talk about EXAMPLE code, which are meant to be adapted. I wrote these examples and added command line options that in my mind makes sense….if someone do not like it change it ! The old examples (in examples/common worked quite differently).

The timeout in the library did not change type, I did however solve several issues because timeout essentially did not work in 2.5.3 apart from in connect().
@dhoomakethu if you think otherwise, then please point to the code where timeout is converted to an int.
Hm. I am confused now (but I am a confused person anyhow). With timeout=0.3 my TCP sync client did not connect with v3.0 but it did before with v2.5.3. I expected that there is a conversion to int. In client/base.py there are type annotations for the timeout parameter stating it is 'str | int' and further down in the __init__() function of the class _params (L112) the timeout parameter gets converted to int(). Maybe this is the change causing the difference in behavior?




The type hint does not affect the actual code….but you are right that the new init code actually wrongly does a convert. will be fixed.
Should be solved on dev, I will make sure doc. etc are updated at the end of the week.

Resolving patch:
diff --git a/pymodbus/client/base.py b/pymodbus/client/base.py
--- a/pymodbus/client/base.py
+++ b/pymodbus/client/base.py
@@ -25,7 +25,7 @@ class ModbusBaseClient(ModbusClientMixin):
     **Parameters common to all clients**:
 
     :param framer: (optional) Modbus Framer class.
-    :param timeout: (optional) Timeout for a request.
+    :param timeout: (optional) Timeout for a request, in seconds.
     :param retries: (optional) Max number of retries pr request.
     :param retry_on_empty: (optional) Retry on empty response.
     :param close_comm_on_error: (optional) Close connection on error.
@@ -69,9 +69,9 @@ class _params:  # pylint: disable=too-many-instance-attributes
         """Parameter class."""
 
         host: str = None
-        port: str | float = None
+        port: str | int = None
         framer: ModbusFramer = None
-        timeout: int = None
+        timeout: float = None
         retries: int = None
         retry_on_empty: bool = None
         close_comm_on_error: bool = None


Test patch: