Skip to content
Merged
Show file tree
Hide file tree
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
11 changes: 8 additions & 3 deletions pymodbus/client/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ class ModbusBaseClient(ModbusClientMixin):
:param close_comm_on_error: (optional) Close connection on error.
:param strict: (optional) Strict timing, 1.5 character between requests.
:param broadcast_enable: (optional) True to treat id 0 as broadcast address.
:param reconnect_delay: (optional) Delay in milliseconds before reconnecting.
:param reconnect_delay: (optional) Minimum delay in milliseconds before reconnecting.
:param reconnect_delay_max: (optional) Maximum delay in milliseconds before reconnecting.
:param kwargs: (optional) Experimental parameters.

.. tip::
Common parameters and all external methods for all clients are documented here,
and not repeated with each client.

.. tip::
**reconnect_delay** doubles automatically with each unsuccessful connect.
**delay_ms** doubles automatically with each unsuccessful connect, from
**reconnect_delay** to **reconnect_delay_max**.
Set `reconnect_delay=0` to avoid automatic reconnection.

:mod:`ModbusBaseClient` is normally not referenced outside :mod:`pymodbus`,
Expand Down Expand Up @@ -82,6 +84,7 @@ class _params: # pylint: disable=too-many-instance-attributes
broadcast_enable: bool = None
kwargs: dict = None
reconnect_delay: int = None
reconnect_delay_max: int = None

baudrate: int = None
bytesize: int = None
Expand All @@ -107,6 +110,7 @@ def __init__(
strict: bool = Defaults.Strict,
broadcast_enable: bool = Defaults.BroadcastEnable,
reconnect_delay: int = Defaults.ReconnectDelay,
reconnect_delay_max: int = Defaults.ReconnectDelayMax,
**kwargs: any,
) -> None:
"""Initialize a client instance."""
Expand All @@ -118,7 +122,8 @@ def __init__(
self.params.close_comm_on_error = bool(close_comm_on_error)
self.params.strict = bool(strict)
self.params.broadcast_enable = bool(broadcast_enable)
self.params.reconnect_delay = reconnect_delay
self.params.reconnect_delay = int(reconnect_delay)
self.params.reconnect_delay_max = int(reconnect_delay_max)
self.params.kwargs = kwargs

# Common variables.
Expand Down
3 changes: 2 additions & 1 deletion pymodbus/client/tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def _create_protocol(self):
strict=self.params.strict,
broadcast_enable=self.params.broadcast_enable,
reconnect_delay=self.params.reconnect_delay,
reconnect_delay_max=self.params.reconnect_delay_max,
**self.params.kwargs,
)
protocol.factory = self
Expand Down Expand Up @@ -144,7 +145,7 @@ async def _reconnect(self):
txt = f"Waiting {self.delay_ms} ms before next connection attempt."
_logger.debug(txt)
await asyncio.sleep(self.delay_ms / 1000)
self.delay_ms = 2 * self.delay_ms
self.delay_ms = min(2 * self.delay_ms, self.params.reconnect_delay_max)

return await self._connect()

Expand Down
1 change: 1 addition & 0 deletions pymodbus/client/udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def _create_protocol(self, host=None, port=0):
strict=self.params.strict,
broadcast_enable=self.params.broadcast_enable,
reconnect_delay=self.params.reconnect_delay,
reconnect_delay_max=self.params.reconnect_delay_max,
**self.params.kwargs,
)
protocol.params.host = host
Expand Down
140 changes: 78 additions & 62 deletions pymodbus/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,105 +11,120 @@
class Defaults(Singleton): # pylint: disable=too-few-public-methods
"""A collection of modbus default values.

.. attribute:: Port
.. attribute:: Port

The default modbus tcp server port (502)
The default modbus tcp server port (502)

.. attribute:: TLSPort
.. attribute:: TLSPort

The default modbus tcp over tls server port (802)
The default modbus tcp over tls server port (802)


.. attribute:: Backoff
.. attribute:: Backoff

The default exponential backoff delay (0.3 seconds)
The default exponential backoff delay (0.3 seconds) for a request

.. attribute:: Retries
.. attribute:: Retries

The default number of times a client should retry the given
request before failing (3)
The default number of times a client should retry the given
request before failing (3)

.. attribute:: RetryOnEmpty
.. attribute:: RetryOnEmpty

A flag indicating if a transaction should be retried in the
case that an empty response is received. This is useful for
slow clients that may need more time to process a request.
A flag indicating if a transaction should be retried in the
case that an empty response is received. This is useful for
slow clients that may need more time to process a request.

.. attribute:: RetryOnInvalid
.. attribute:: RetryOnInvalid

A flag indicating if a transaction should be retried in the
case that an invalid response is received.
A flag indicating if a transaction should be retried in the
case that an invalid response is received.

.. attribute:: Timeout
.. attribute:: Timeout

The default amount of time a client should wait for a request
to be processed (3 seconds)
The default amount of time a client should wait for a request
to be processed (3 seconds)

.. attribute:: Reconnects
.. attribute:: Reconnects

The default number of times a client should attempt to reconnect
before deciding the server is down (0)
The default number of times a client should attempt to reconnect
before deciding the server is down (0)

.. attribute:: TransactionId
.. attribute:: TransactionId

The starting transaction identifier number (0)
The starting transaction identifier number (0)

.. attribute:: ProtocolId
.. attribute:: ProtocolId

The modbus protocol id. Currently, this is set to 0 in all
but proprietary implementations.
The modbus protocol id. Currently, this is set to 0 in all
but proprietary implementations.

.. attribute:: Slave
.. attribute:: Slave

The modbus slave address. Currently, this is set to 0x00 which
means this request should be broadcast to all the slave devices
(really means that all the devices should respond).
The modbus slave address. Currently, this is set to 0x00 which
means this request should be broadcast to all the slave devices
(really means that all the devices should respond).

.. attribute:: Baudrate
.. attribute:: Baudrate

The speed at which the data is transmitted over the serial line.
This defaults to 19200.
The speed at which the data is transmitted over the serial line.
This defaults to 19200.

.. attribute:: Parity
.. attribute:: Parity

The type of checksum to use to verify data integrity. This can be
on of the following::
The type of checksum to use to verify data integrity. This can be
on of the following::

- (E)ven - 1 0 1 0 | P(0)
- (O)dd - 1 0 1 0 | P(1)
- (N)one - 1 0 1 0 | no parity
- (E)ven - 1 0 1 0 | P(0)
- (O)dd - 1 0 1 0 | P(1)
- (N)one - 1 0 1 0 | no parity

This defaults to (N)one.
This defaults to (N)one.

.. attribute:: Bytesize
.. attribute:: Bytesize

The number of bits in a byte of serial data. This can be one of
5, 6, 7, or 8. This defaults to 8.
The number of bits in a byte of serial data. This can be one of
5, 6, 7, or 8. This defaults to 8.

.. attribute:: Stopbits
.. attribute:: Stopbits

The number of bits sent after each character in a message to
indicate the end of the byte. This defaults to 1.
The number of bits sent after each character in a message to
indicate the end of the byte. This defaults to 1.

.. attribute:: ZeroMode
.. attribute:: ZeroMode

Indicates if the slave datastore should use indexing at 0 or 1.
More about this can be read in section 4.4 of the modbus specification.
Indicates if the slave datastore should use indexing at 0 or 1.
More about this can be read in section 4.4 of the modbus specification.

.. attribute:: IgnoreMissingSlaves
.. attribute:: IgnoreMissingSlaves

In case a request is made to a missing slave, this defines if an error
should be returned or simply ignored. This is useful for the case of a
serial server emulater where a request to a non-existent slave on a bus
will never respond. The client in this case will simply timeout.
In case a request is made to a missing slave, this defines if an error
should be returned or simply ignored. This is useful for the case of a
serial server emulater where a request to a non-existent slave on a bus
will never respond. The client in this case will simply timeout.

.. attribute:: broadcast_enable
.. attribute:: broadcastEnable

When False unit_id 0 will be treated as any other unit_id. When True and
the unit_id is 0 the server will execute all requests on all server
contexts and not respond and the client will skip trying to receive a
response. Default value False does not conform to Modbus spec but maintains
legacy behavior for existing pymodbus users.

.. attribute: reconnectDelayMin

When a connection has been dropped, the client will initially wait
reconnectDelayMin milliseconds before attempting a reconnect. If the
attempt fails, it will double the delay before attempting again, up to a
a maximum of ReconnectDelayMax. (binary exponential backoff).

.. attribute: reconnectDelayMax

When a connection has been dropped, the client will initially wait
reconnectDelayMin milliseconds before attempting a reconnect. If the
attempt fails, it will double the delay before attempting again, up to a
a maximum of ReconnectDelayMax. (binary exponential backoff)

When False unit_id 0 will be treated as any other unit_id. When True and
the unit_id is 0 the server will execute all requests on all server
contexts and not respond and the client will skip trying to receive a
response. Default value False does not conform to Modbus spec but maintains
legacy behavior for existing pymodbus users.

"""

Expand All @@ -136,7 +151,8 @@ class Defaults(Singleton): # pylint: disable=too-few-public-methods
IgnoreMissingSlaves = False
ReadSize = 1024
BroadcastEnable = False
ReconnectDelay = 1000 * 60 * 5
ReconnectDelay = 100
ReconnectDelayMax = 1000 * 60 * 5
Count = 1


Expand Down
2 changes: 2 additions & 0 deletions test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def test_client_mixin(arglist, method, arg, response):
"strict": not Defaults.Strict,
"broadcast_enable": not Defaults.BroadcastEnable,
"reconnect_delay": 117,
"reconnect_delay_max": 250,
},
"defaults": {
"timeout": Defaults.Timeout,
Expand All @@ -119,6 +120,7 @@ def test_client_mixin(arglist, method, arg, response):
"strict": Defaults.Strict,
"broadcast_enable": Defaults.BroadcastEnable,
"reconnect_delay": Defaults.ReconnectDelay,
"reconnect_delay_max": Defaults.ReconnectDelayMax,
},
},
"serial": {
Expand Down