Skip to content

Commit a6c5bf4

Browse files
authored
Merge branch '3.0.0' into remove_python2_compatibility_code
2 parents 7dfac6f + 9967ff0 commit a6c5bf4

33 files changed

+666
-420
lines changed

CHANGELOG.rst

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
1+
2+
version 3.0.0dev1
3+
----------------------------------------------------------
4+
* Support python3.10
5+
* Implement asyncio ModbusSerialServer
6+
* ModbusTLS updates (tls handshake, default framer)
7+
* Support broadcast messages with asyncio client
8+
* Fix for lazy loading serial module with asyncio clients.
9+
* Updated examples and tests
10+
11+
version 3.0.0dev0
12+
----------------------------------------------------------
13+
* Support python3.7 and above
14+
* Support creating asyncio clients from with in coroutines.
15+
116
version 2.5.3
217
----------------------------------------------------------
318
* Fix retries on tcp client failing randomly.
419
* Fix Asyncio client timeout arg not being used.
520
* Treat exception codes as valid responses
621
* Fix examples (modbus_payload)
722
* Add missing identity argument to async ModbusSerialServer
8-
923
version 2.5.2
1024
----------------------------------------------------------
1125
* Add kwarg `reset_socket` to control closing of the socket on read failures (set to `True` by default).

examples/common/async_asyncio_client.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ async def start_async_test(client):
4949
# individual request. This can be done by specifying the `unit` parameter
5050
# which defaults to `0x00`
5151
# ----------------------------------------------------------------------- #
52+
# client = await client
5253
log.debug("Reading Coils")
5354
rr = await client.read_coils(1, 1, unit=0x01)
5455

@@ -143,7 +144,7 @@ def run_with_not_running_loop():
143144
log.debug("")
144145

145146

146-
def run_with_already_running_loop():
147+
async def run_with_already_running_loop():
147148
"""
148149
An already running loop is passed to ModbusClient Factory
149150
:return:
@@ -168,9 +169,11 @@ def start_loop(loop):
168169
t.daemon = True
169170
# Start the loop
170171
t.start()
172+
time.sleep(1)
171173
assert loop.is_running()
172174
asyncio.set_event_loop(loop)
173175
loop, client = ModbusClient(schedulers.ASYNC_IO, port=5020, loop=loop)
176+
# client = await client
174177
future = asyncio.run_coroutine_threadsafe(
175178
start_async_test(client.protocol), loop=loop)
176179
future.add_done_callback(done)
@@ -198,12 +201,12 @@ def run_with_no_loop():
198201
# Run with No loop
199202
log.debug("Running Async client")
200203
log.debug("------------------------------------------------------")
201-
run_with_no_loop()
204+
# run_with_no_loop()
202205

203206
# Run with loop not yet started
204207
# run_with_not_running_loop()
205208

206209
# Run with already running loop
207-
# run_with_already_running_loop()
210+
asyncio.run(run_with_already_running_loop())
208211

209212
log.debug("")

examples/common/async_asyncio_serial_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ async def start_async_test(client):
128128
# ----------------------------------------------------------------------- #
129129
# socat -d -d PTY,link=/tmp/ptyp0,raw,echo=0,ispeed=9600 PTY,
130130
# link=/tmp/ttyp0,raw,echo=0,ospeed=9600
131-
loop, client = ModbusClient(schedulers.ASYNC_IO, port='/tmp/ptyp0',
131+
loop, client = ModbusClient(schedulers.ASYNC_IO, port='/tmp/ttyp0',
132132
baudrate=9600, method="rtu")
133133
loop.run_until_complete(start_async_test(client.protocol))
134134
loop.close()

examples/common/asyncio_server.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@ async def run_server():
131131

132132
# Tls:
133133
# await StartTlsServer(context, identity=identity, address=("localhost", 8020),
134-
# certfile="server.crt", keyfile="server.key",
134+
# certfile="server.crt", keyfile="server.key", password="pwd",
135+
# allow_reuse_address=True, allow_reuse_port=True,
136+
# defer_start=False)
137+
138+
# Tls and force require client's certificate for TLS full handshake:
139+
# await StartTlsServer(context, identity=identity, address=("localhost", 8020),
140+
# certfile="server.crt", keyfile="server.key", password="pwd", reqclicert=True,
135141
# allow_reuse_address=True, allow_reuse_port=True,
136142
# defer_start=False)
137143

@@ -141,17 +147,16 @@ async def run_server():
141147
# #
142148
# await server.serve_forever()
143149

144-
# !!! SERIAL SERVER NOT IMPLEMENTED !!!
145150
# Ascii:
146-
# StartSerialServer(context, identity=identity,
147-
# port='/dev/ttyp0', timeout=1)
151+
# await StartSerialServer(context, identity=identity,
152+
# port='/dev/ttyp0', timeout=1, autoreconnect=True)
148153

149154
# RTU:
150-
# StartSerialServer(context, framer=ModbusRtuFramer, identity=identity,
151-
# port='/dev/ttyp0', timeout=.005, baudrate=9600)
155+
# await StartSerialServer(context, framer=ModbusRtuFramer, identity=identity,
156+
# port='/dev/ttyp0', timeout=.005, baudrate=9600, autoreconnect=True)
152157

153158
# Binary
154-
# StartSerialServer(context,
159+
# await StartSerialServer(context,
155160
# identity=identity,
156161
# framer=ModbusBinaryFramer,
157162
# port='/dev/ttyp0',

examples/common/synchronous_server.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,21 @@ def run_server():
113113
# run the server you want
114114
# ----------------------------------------------------------------------- #
115115
# Tcp:
116-
StartTcpServer(context, identity=identity, address=("", 5020))
116+
# StartTcpServer(context, identity=identity, address=("", 5020))
117117
#
118118
# TCP with different framer
119119
# StartTcpServer(context, identity=identity,
120120
# framer=ModbusRtuFramer, address=("0.0.0.0", 5020))
121121

122122
# TLS
123-
# StartTlsServer(context, identity=identity, certfile="server.crt",
124-
# keyfile="server.key", address=("0.0.0.0", 8020))
123+
# StartTlsServer(context, identity=identity,
124+
# certfile="server.crt", keyfile="server.key", password="pwd",
125+
# address=("0.0.0.0", 8020))
126+
127+
# Tls and force require client's certificate for TLS full handshake:
128+
# StartTlsServer(context, identity=identity,
129+
# certfile="server.crt", keyfile="server.key", password="pwd", reqclicert=True,
130+
# address=("0.0.0.0", 8020))
125131

126132
# Udp:
127133
# StartUdpServer(context, identity=identity, address=("0.0.0.0", 5020))

examples/contrib/asynchronous_asyncio_modbus_tls_client.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717
# -------------------------------------------------------------------------- #
1818
# the TLS detail security can be set in SSLContext which is the context here
1919
# -------------------------------------------------------------------------- #
20-
context = ssl.create_default_context()
21-
context.options |= ssl.OP_NO_SSLv2
22-
context.options |= ssl.OP_NO_SSLv3
23-
context.options |= ssl.OP_NO_TLSv1
24-
context.options |= ssl.OP_NO_TLSv1_1
20+
sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
21+
sslctx.verify_mode = ssl.CERT_REQUIRED
22+
sslctx.check_hostname = True
23+
24+
# Prepare client's certificate which the server requires for TLS full handshake
25+
# sslctx.load_cert_chain(certfile="client.crt", keyfile="client.key",
26+
# password="pwd")
27+
2528

2629
async def start_async_test(client):
2730
result = await client.read_coils(1, 8)
@@ -31,10 +34,10 @@ async def start_async_test(client):
3134
print(result.bits)
3235

3336
if __name__ == '__main__':
34-
# -------------------------------------------------------------------------- #
35-
# pass SSLContext which is the context here to ModbusTcpClient()
36-
# -------------------------------------------------------------------------- #
37+
# ----------------------------------------------------------------------- #
38+
# pass SSLContext which is the context here to ModbusTcpClient()
39+
# ----------------------------------------------------------------------- #
3740
loop, client = AsyncModbusTLSClient(ASYNC_IO, 'test.host.com', 8020,
38-
sslctx=context)
41+
sslctx=sslctx)
3942
loop.run_until_complete(start_async_test(client.protocol))
4043
loop.close()

examples/contrib/asynchronous_asyncio_serial_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def make_protocol():
108108

109109
if __name__ == '__main__':
110110
loop = asyncio.get_event_loop()
111-
coro = create_serial_connection(loop, make_protocol, '/dev/ptyp0',
111+
coro = create_serial_connection(loop, make_protocol, '/tmp/ttyp0',
112112
baudrate=9600)
113113
transport, protocol = loop.run_until_complete(asyncio.gather(coro))[0]
114114
loop.run_until_complete(start_async_test(protocol))

examples/contrib/modbus_tls_client.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@
1616
# -------------------------------------------------------------------------- #
1717
# the TLS detail security can be set in SSLContext which is the context here
1818
# -------------------------------------------------------------------------- #
19-
context = ssl.create_default_context()
20-
context.options |= ssl.OP_NO_SSLv2
21-
context.options |= ssl.OP_NO_SSLv3
22-
context.options |= ssl.OP_NO_TLSv1
23-
context.options |= ssl.OP_NO_TLSv1_1
19+
sslctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
20+
sslctx.verify_mode = ssl.CERT_REQUIRED
21+
sslctx.check_hostname = True
22+
23+
# Prepare client's certificate which the server requires for TLS full handshake
24+
# sslctx.load_cert_chain(certfile="client.crt", keyfile="client.key",
25+
# password="pwd")
2426

2527
# -------------------------------------------------------------------------- #
2628
# pass SSLContext which is the context here to ModbusTcpClient()
2729
# -------------------------------------------------------------------------- #
28-
client = ModbusTlsClient('test.host.com', 8020, sslctx=context)
30+
client = ModbusTlsClient('test.host.com', 8020, sslctx=sslctx)
2931
client.connect()
3032

3133
result = client.read_coils(1, 8)

examples/tools/test_install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ elif [[ "`which easy_install`" != "" ]]; then
1616
INSTALL="easy_install -qU"
1717
else
1818
echo -e "\E[31m"
19-
echo "\E[31mPlease install distutils before continuing"
19+
echo "\E[31mPlease install setuptools before continuing"
2020
echo "wget http://peak.telecommunity.com/dist/ez_setup.py | sudo python"
2121
echo -e "\E[0m"
2222
exit -1

0 commit comments

Comments
 (0)