Skip to content

Commit

Permalink
Be able to create asyncio modbusclients from within a coroutine
Browse files Browse the repository at this point in the history
  • Loading branch information
Emilv2 committed Feb 12, 2021
1 parent 7e8e7cf commit 3bdb32d
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 12 deletions.
16 changes: 11 additions & 5 deletions pymodbus/client/asynchronous/factory/serial.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,13 @@ def async_io_factory(port=None, framer=None, **kwargs):
import asyncio
from pymodbus.client.asynchronous.async_io import (ModbusClientProtocol,
AsyncioModbusSerialClient)
loop = kwargs.pop("loop", None) or asyncio.get_event_loop()
proto_cls = kwargs.pop("proto_cls", None) or ModbusClientProtocol

try:
loop = kwargs.pop("loop", None) or asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()

proto_cls = kwargs.get("proto_cls") or ModbusClientProtocol

try:
from serial_asyncio import create_serial_connection
Expand All @@ -103,11 +108,12 @@ def async_io_factory(port=None, framer=None, **kwargs):

client = AsyncioModbusSerialClient(port, proto_cls, framer, loop, **kwargs)
coro = client.connect()
if loop.is_running():
if not loop.is_running():
loop.run_until_complete(coro)
elif loop is not asyncio.get_event_loop():
future = asyncio.run_coroutine_threadsafe(coro, loop=loop)
future.result()
else:
loop.run_until_complete(coro)

return loop, client


Expand Down
12 changes: 10 additions & 2 deletions pymodbus/client/asynchronous/factory/tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,20 @@ 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)

try:
loop = kwargs.get("loop") or asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()

proto_cls = kwargs.get("proto_cls")

if not loop.is_running():
asyncio.set_event_loop(loop)
cor = init_tcp_client(proto_cls, loop, host, port)
client = loop.run_until_complete(asyncio.gather(cor))[0]
elif loop is asyncio.get_event_loop():
client = init_tcp_client(proto_cls, loop, host, port)
else:
cor = init_tcp_client(proto_cls, loop, host, port)
future = asyncio.run_coroutine_threadsafe(cor, loop=loop)
Expand Down
12 changes: 10 additions & 2 deletions pymodbus/client/asynchronous/factory/tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,21 @@ 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)

try:
loop = kwargs.get("loop") or asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()

proto_cls = kwargs.get("proto_cls")

if not loop.is_running():
asyncio.set_event_loop(loop)
cor = init_tls_client(proto_cls, loop, host, port, sslctx, server_hostname,
framer)
client = loop.run_until_complete(asyncio.gather(cor))[0]
elif loop is asyncio.get_event_loop():
return loop, init_tls_client(proto_cls, loop, host, port)
else:
cor = init_tls_client(proto_cls, loop, host, port, sslctx, server_hostname,
framer)
Expand Down
16 changes: 13 additions & 3 deletions pymodbus/client/asynchronous/factory/udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,24 @@ 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)

try:
loop = kwargs.get("loop") or asyncio.get_running_loop()
except RuntimeError:
loop = asyncio.new_event_loop()

proto_cls = kwargs.get("proto_cls")

if not loop.is_running():
cor = init_udp_client(proto_cls, loop, host, port)
client = loop.run_until_complete(asyncio.gather(cor))[0]
elif loop is asyncio.get_event_loop():
return loop, init_udp_client(proto_cls, loop, host, port)
else:
cor = init_udp_client(proto_cls, loop, host, port)
client = asyncio.run_coroutine_threadsafe(cor, loop=loop)
client = client.result()

return loop, client


Expand Down

0 comments on commit 3bdb32d

Please sign in to comment.