Skip to content
Merged

2.5.3 #660

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
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
version 2.5.3
----------------------------------------------------------
* Fix retries on tcp client failing randomly.
* Fix Asyncio client timeout arg not being used.
* Treat exception codes as valid responses
* Fix examples (modbus_payload)
* Add missing identity argument to async ModbusSerialServer

version 2.5.2
----------------------------------------------------------
* Add kwarg `reset_socket` to control closing of the socket on read failures (set to `True` by default).
Expand Down
33 changes: 19 additions & 14 deletions pymodbus/client/asynchronous/async_io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class ReconnectingAsyncioModbusTcpClient(object):
#: Maximum delay in milli seconds before reconnect is attempted.
DELAY_MAX_MS = 1000 * 60 * 5

def __init__(self, protocol_class=None, loop=None):
def __init__(self, protocol_class=None, loop=None, **kwargs):
"""
Initialize ReconnectingAsyncioModbusTcpClient
:param protocol_class: Protocol used to talk to modbus device.
Expand All @@ -251,6 +251,7 @@ def __init__(self, protocol_class=None, loop=None):
self.connected = False
#: Reconnect delay in milli seconds.
self.delay_ms = self.DELAY_MIN_MS
self._proto_args = kwargs

def reset_delay(self):
"""
Expand Down Expand Up @@ -291,7 +292,7 @@ def _create_protocol(self):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class()
protocol = self.protocol_class(**self._proto_args)
protocol.factory = self
return protocol

Expand Down Expand Up @@ -350,7 +351,7 @@ def _reconnect(self):
class AsyncioModbusTcpClient(object):
"""Client to connect to modbus device over TCP/IP."""

def __init__(self, host=None, port=502, protocol_class=None, loop=None):
def __init__(self, host=None, port=502, protocol_class=None, loop=None, **kwargs):
"""
Initializes Asyncio Modbus Tcp Client
:param host: Host IP address
Expand All @@ -369,6 +370,7 @@ def __init__(self, host=None, port=502, protocol_class=None, loop=None):
self.port = port

self.connected = False
self._proto_args = kwargs

def stop(self):
"""
Expand All @@ -384,7 +386,7 @@ def _create_protocol(self):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class()
protocol = self.protocol_class(**self._proto_args)
protocol.factory = self
return protocol

Expand Down Expand Up @@ -439,14 +441,14 @@ class ReconnectingAsyncioModbusTlsClient(ReconnectingAsyncioModbusTcpClient):
"""
Client to connect to modbus device repeatedly over TLS."
"""
def __init__(self, protocol_class=None, loop=None, framer=None):
def __init__(self, protocol_class=None, loop=None, framer=None, **kwargs):
"""
Initialize ReconnectingAsyncioModbusTcpClient
:param protocol_class: Protocol used to talk to modbus device.
:param loop: Event loop to use
"""
self.framer = framer
ReconnectingAsyncioModbusTcpClient.__init__(self, protocol_class, loop)
ReconnectingAsyncioModbusTcpClient.__init__(self, protocol_class, loop, **kwargs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove protocol_class and loop from kwargs


@asyncio.coroutine
def start(self, host, port=802, sslctx=None, server_hostname=None):
Expand Down Expand Up @@ -490,7 +492,7 @@ def _create_protocol(self):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class(framer=self.framer)
protocol = self.protocol_class(framer=self.framer, **self._proto_args)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove framer from self._proto_args

protocol.transaction = FifoTransactionManager(self)
protocol.factory = self
return protocol
Expand All @@ -506,7 +508,7 @@ class ReconnectingAsyncioModbusUdpClient(object):
#: Maximum delay in milli seconds before reconnect is attempted.
DELAY_MAX_MS = 1000 * 60 * 5

def __init__(self, protocol_class=None, loop=None):
def __init__(self, protocol_class=None, loop=None, **kwargs):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove protocol_class and loop from kwargs

"""
Initializes ReconnectingAsyncioModbusUdpClient
:param protocol_class: Protocol used to talk to modbus device.
Expand All @@ -523,6 +525,7 @@ def __init__(self, protocol_class=None, loop=None):
self.port = 0

self.connected = False
self._proto_args = kwargs
self.reset_delay()

def reset_delay(self):
Expand Down Expand Up @@ -572,7 +575,7 @@ def _create_protocol(self, host=None, port=0):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class()
protocol = self.protocol_class(**self._proto_args)
protocol.host = host
protocol.port = port
protocol.factory = self
Expand Down Expand Up @@ -637,7 +640,7 @@ class AsyncioModbusUdpClient(object):
Client to connect to modbus device over UDP.
"""

def __init__(self, host=None, port=502, protocol_class=None, loop=None):
def __init__(self, host=None, port=502, protocol_class=None, loop=None, **kwargs):
"""
Initializes Asyncio Modbus UDP Client
:param host: Host IP address
Expand All @@ -656,6 +659,7 @@ def __init__(self, host=None, port=502, protocol_class=None, loop=None):
self.port = port

self.connected = False
self._proto_args = kwargs

def stop(self):
"""
Expand All @@ -674,7 +678,7 @@ def _create_protocol(self, host=None, port=0):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class()
protocol = self.protocol_class(**self._proto_args)
protocol.host = host
protocol.port = port
protocol.factory = self
Expand Down Expand Up @@ -842,7 +846,7 @@ def init_tcp_client(proto_cls, loop, host, port, **kwargs):
:return:
"""
client = ReconnectingAsyncioModbusTcpClient(protocol_class=proto_cls,
loop=loop)
loop=loop, **kwargs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove loop and protocol_class from kwargs

yield from client.start(host, port)
return client

Expand All @@ -863,7 +867,8 @@ def init_tls_client(proto_cls, loop, host, port, sslctx=None,
:return:
"""
client = ReconnectingAsyncioModbusTlsClient(protocol_class=proto_cls,
loop=loop, framer=framer)
loop=loop, framer=framer,
**kwargs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove loop and framer from kwargs

yield from client.start(host, port, sslctx, server_hostname)
return client

Expand All @@ -880,6 +885,6 @@ def init_udp_client(proto_cls, loop, host, port, **kwargs):
:return:
"""
client = ReconnectingAsyncioModbusUdpClient(protocol_class=proto_cls,
loop=loop)
loop=loop, **kwargs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove from kwargs (i.e. {arg:argv[arg] for arg in kwargs if arg not in ["loop", "protocol_class"]}

yield from client.start(host, port)
return client
11 changes: 5 additions & 6 deletions pymodbus/client/asynchronous/factory/tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ def io_loop_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
return protocol, future


def async_io_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
source_address=None, timeout=None, **kwargs):
def async_io_factory(host="127.0.0.1", port=Defaults.Port, **kwargs):
"""
Factory to create asyncio based asynchronous tcp clients
:param host: Host IP address
Expand All @@ -91,14 +90,14 @@ def async_io_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
"""
import asyncio
from pymodbus.client.asynchronous.async_io import init_tcp_client
loop = kwargs.get("loop") or asyncio.new_event_loop()
proto_cls = kwargs.get("proto_cls", None)
loop = kwargs.pop("loop", None) or asyncio.new_event_loop()
proto_cls = kwargs.pop("proto_cls", None)
if not loop.is_running():
asyncio.set_event_loop(loop)
cor = init_tcp_client(proto_cls, loop, host, port)
cor = init_tcp_client(proto_cls, loop, host, port, **kwargs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove from kwargs (i.e. {arg:argv[arg] for arg in kwargs if arg not in ["proto_cls","loop","host","port"]}

client = loop.run_until_complete(asyncio.gather(cor))[0]
else:
cor = init_tcp_client(proto_cls, loop, host, port)
cor = init_tcp_client(proto_cls, loop, host, port, **kwargs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove from kwargs (i.e. {arg:argv[arg] for arg in kwargs if arg not in ["proto_cls","loop","host","port"]}

future = asyncio.run_coroutine_threadsafe(cor, loop=loop)
client = future.result()

Expand Down
11 changes: 5 additions & 6 deletions pymodbus/client/asynchronous/factory/tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
LOGGER = logging.getLogger(__name__)

def async_io_factory(host="127.0.0.1", port=Defaults.TLSPort, sslctx=None,
server_hostname=None, framer=None, source_address=None,
timeout=None, **kwargs):
server_hostname=None, framer=None, **kwargs):
"""
Factory to create asyncio based asynchronous tls clients
:param host: Host IP address
Expand All @@ -29,16 +28,16 @@ def async_io_factory(host="127.0.0.1", port=Defaults.TLSPort, sslctx=None,
"""
import asyncio
from pymodbus.client.asynchronous.async_io import init_tls_client
loop = kwargs.get("loop") or asyncio.new_event_loop()
proto_cls = kwargs.get("proto_cls", None)
loop = kwargs.pop("loop", None) or asyncio.new_event_loop()
proto_cls = kwargs.pop("proto_cls", None)
if not loop.is_running():
asyncio.set_event_loop(loop)
cor = init_tls_client(proto_cls, loop, host, port, sslctx, server_hostname,
framer)
framer, **kwargs)
client = loop.run_until_complete(asyncio.gather(cor))[0]
else:
cor = init_tls_client(proto_cls, loop, host, port, sslctx, server_hostname,
framer)
framer, **kwargs)
future = asyncio.run_coroutine_threadsafe(cor, loop=loop)
client = future.result()

Expand Down
9 changes: 4 additions & 5 deletions pymodbus/client/asynchronous/factory/udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ def io_loop_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
return protocol, future


def async_io_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
source_address=None, timeout=None, **kwargs):
def async_io_factory(host="127.0.0.1", port=Defaults.Port, **kwargs):
"""
Factory to create asyncio based asynchronous udp clients
:param host: Host IP address
Expand All @@ -66,9 +65,9 @@ def async_io_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
"""
import asyncio
from pymodbus.client.asynchronous.async_io import init_udp_client
loop = kwargs.get("loop") or asyncio.get_event_loop()
proto_cls = kwargs.get("proto_cls", None)
cor = init_udp_client(proto_cls, loop, host, port)
loop = kwargs.pop("loop", None) or asyncio.get_event_loop()
proto_cls = kwargs.pop("proto_cls", None)
cor = init_udp_client(proto_cls, loop, host, port, **kwargs)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

before this, remove from kwargs (i.e. {arg:argv[arg] for arg in kwargs if arg not in ["proto_cls","loop","host","port"]}

if not loop.is_running():
client = loop.run_until_complete(asyncio.gather(cor))[0]
else:
Expand Down
2 changes: 1 addition & 1 deletion pymodbus/client/asynchronous/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(self, host="127.0.0.1", port=Defaults.Port, framer=None,
self.host = host
self.port = port
self.source_address = source_address or ("", 0)
self.timeout = timeout if timeout is not None else Defaults.Timeout
self._timeout = timeout if timeout is not None else Defaults.Timeout


class AsyncModbusSerialClientMixin(BaseAsyncModbusClient):
Expand Down
2 changes: 1 addition & 1 deletion pymodbus/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __str__(self):
return '[%s, version %s]' % (self.package, self.short())


version = Version('pymodbus', 2, 5, 2)
version = Version('pymodbus', 2, 5, 3)

version.__name__ = 'pymodbus' # fix epydoc error

Expand Down