pyModbusTCP 0.3.0__tar.gz → 0.4.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pymodbustcp-0.4.0a1/.gitignore +14 -0
- pymodbustcp-0.4.0a1/CHANGES +290 -0
- pymodbustcp-0.4.0a1/PKG-INFO +192 -0
- pymodbustcp-0.4.0a1/README.md +160 -0
- {pyModbusTCP-0.3.0 → pymodbustcp-0.4.0a1}/pyModbusTCP/__init__.py +1 -1
- pymodbustcp-0.4.0a1/pyModbusTCP/client/__init__.py +18 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/client/_common.py +13 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/client/_errors.py +23 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/client/_functions.py +371 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/client/_transport.py +295 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/client/_validators.py +61 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/client/device_id.py +51 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/client/modbus_client.py +280 -0
- {pyModbusTCP-0.3.0 → pymodbustcp-0.4.0a1}/pyModbusTCP/constants.py +7 -1
- pymodbustcp-0.4.0a1/pyModbusTCP/py.typed +0 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/__init__.py +22 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/_common.py +13 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/_functions.py +364 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/_transport.py +244 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/_validators.py +89 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/data_bank.py +319 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/data_handler.py +156 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/device_id.py +171 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/errors.py +23 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/frames.py +112 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/modbus_server.py +329 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/server/session.py +49 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/tools/__init__.py +15 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/tools/__main__.py +7 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/tools/_common.py +69 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/tools/_entry.py +65 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/tools/client.py +214 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/tools/rtu_to_tcp_gw.py +460 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/tools/server.py +133 -0
- pymodbustcp-0.4.0a1/pyModbusTCP/tools/tcp_to_rtu_gw.py +549 -0
- {pyModbusTCP-0.3.0 → pymodbustcp-0.4.0a1}/pyModbusTCP/utils.py +143 -20
- pymodbustcp-0.4.0a1/pyproject.toml +63 -0
- pyModbusTCP-0.3.0/CHANGES +0 -175
- pyModbusTCP-0.3.0/MANIFEST.in +0 -6
- pyModbusTCP-0.3.0/PKG-INFO +0 -120
- pyModbusTCP-0.3.0/README.rst +0 -109
- pyModbusTCP-0.3.0/pyModbusTCP/client.py +0 -946
- pyModbusTCP-0.3.0/pyModbusTCP/server.py +0 -1307
- pyModbusTCP-0.3.0/pyModbusTCP.egg-info/PKG-INFO +0 -120
- pyModbusTCP-0.3.0/pyModbusTCP.egg-info/SOURCES.txt +0 -19
- pyModbusTCP-0.3.0/pyModbusTCP.egg-info/dependency_links.txt +0 -1
- pyModbusTCP-0.3.0/pyModbusTCP.egg-info/top_level.txt +0 -1
- pyModbusTCP-0.3.0/setup.cfg +0 -8
- pyModbusTCP-0.3.0/setup.py +0 -18
- pyModbusTCP-0.3.0/tests/test_client.py +0 -58
- pyModbusTCP-0.3.0/tests/test_client_server.py +0 -214
- pyModbusTCP-0.3.0/tests/test_server.py +0 -43
- pyModbusTCP-0.3.0/tests/test_utils.py +0 -143
- {pyModbusTCP-0.3.0 → pymodbustcp-0.4.0a1}/LICENSE +0 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
Revision history for pyModbusTCP
|
|
2
|
+
|
|
3
|
+
0.4.0a1 xxxx-xx-xx (alpha: the command line tools, their options and output, may still change before 0.4.0)
|
|
4
|
+
|
|
5
|
+
Breaking changes:
|
|
6
|
+
|
|
7
|
+
- DataBank: remove deprecated class methods (get_bits, set_bits, get_words and set_words).
|
|
8
|
+
- DataBank: set_*() methods raise a TypeError on non-integer items and a ValueError on registers values out of
|
|
9
|
+
the 0-65535 range (values were silently converted before, see below).
|
|
10
|
+
- ModbusClient: non-integer arguments raise a TypeError, custom_request() checks its pdu argument
|
|
11
|
+
(TypeError/ValueError) and auto_open, auto_close and no_delay only accept bool or int values.
|
|
12
|
+
- ModbusClient: the function code of a reply must match the request (or with the exception flag), else the
|
|
13
|
+
request fails with MB_RECV_ERR (this also applies to custom_request()).
|
|
14
|
+
- ModbusServer: idle_timeout (300 s) and max_connections (64) are active by default: an idle client session is
|
|
15
|
+
closed after 5 min (its next request fails once, then the client reconnects), set them to None
|
|
16
|
+
to get the previous behavior.
|
|
17
|
+
- ModbusServer: start() raises a NetworkError if the server is already running (the call was silently ignored).
|
|
18
|
+
- ModbusServer: the internal request handler class ModbusService is replaced by ModbusRequestHandler and
|
|
19
|
+
CustomThreadingTCPServer, is_run is deprecated (use is_running).
|
|
20
|
+
- examples: client_serial_gw.py and server_serial_gw.py are removed, replaced by the gateways of
|
|
21
|
+
pyModbusTCP.tools ("python -m pyModbusTCP.tools tcp2rtu/rtu2tcp", or the commands mbtcp-tcp2rtu and
|
|
22
|
+
mbtcp-rtu2tcp of pyModbusTCP-cli).
|
|
23
|
+
|
|
24
|
+
Changes:
|
|
25
|
+
|
|
26
|
+
- docs: README.rst converted to Markdown (README.md), like the other docs of the repository.
|
|
27
|
+
- docs: Sphinx documentation rewritten: up to date quick start, user guides for the client (connection, errors,
|
|
28
|
+
threads), the server (data bank, change callbacks, custom handler, access restrictions) and the data conversion
|
|
29
|
+
functions, new pages for the command line tools (with their generated --help), the security policy, the
|
|
30
|
+
changelog and the constants, every example documented. tools/build_docs.sh builds it (HTML, PDF...) in a
|
|
31
|
+
temporary venv, the docs build is checked by the CI (warnings are errors).
|
|
32
|
+
- pyModbusTCP.client and pyModbusTCP.server are now packages (one module per concern: main class, Modbus
|
|
33
|
+
functions, TCP layer, argument checks...) with the same layout for both. No change for the users: same
|
|
34
|
+
imports, same logger names, nested names kept (ModbusServer.PDU, ModbusServer.NetworkError...). Exceptions
|
|
35
|
+
of the server are now shown as pyModbusTCP.server.errors.NetworkError (and so on) in tracebacks.
|
|
36
|
+
- new module pyModbusTCP.tools: command line tools (Modbus/TCP server and client, TCP to RTU and RTU to TCP
|
|
37
|
+
gateways), run them with "python -m pyModbusTCP.tools {server,client,tcp2rtu,rtu2tcp}". The gateways need
|
|
38
|
+
pyserial, a new optional dependency: "pip install pyModbusTCP[serial]".
|
|
39
|
+
- new package pyModbusTCP-cli (directory of the same name, no code): installs the tools as the commands
|
|
40
|
+
mbtcp-server, mbtcp-client, mbtcp-tcp2rtu and mbtcp-rtu2tcp, with pyserial. Install it with
|
|
41
|
+
"pip install pyModbusTCP[tools]" or "pipx install pyModbusTCP-cli". A plain "pip install pyModbusTCP" puts
|
|
42
|
+
no command in the PATH and still has no dependency.
|
|
43
|
+
- build: migrate from setup.py to pyproject.toml, with the hatchling build backend (no more MANIFEST.in, tests are
|
|
44
|
+
no longer in the sdist).
|
|
45
|
+
- fix ModbusClient: is_open is now False only for a closed socket (file descriptor 0 is valid).
|
|
46
|
+
- fix ModbusClient: non-integer arguments (float, str...) now raise a TypeError instead of an uncaught struct.error.
|
|
47
|
+
- fix ModbusClient: treat socket.gaierror as MB_CONNECT_ERR (like any other connect error).
|
|
48
|
+
- fix ModbusClient: timeout is now a limit for the whole request (send + receive) and no more for each socket I/O. A
|
|
49
|
+
server sending its response byte by byte could hold the client much longer than timeout.
|
|
50
|
+
- fix ModbusClient: validate write_multiple_coils items to reject non-integer values (like 'a', None, [], 1.5),
|
|
51
|
+
matching write_single_coil behavior.
|
|
52
|
+
- fix ModbusClient: write_multiple_coils() and write_multiple_registers() now set last_error (MB_RECV_ERR) when the
|
|
53
|
+
server reply does not match the request, they returned False with last_error == MB_NO_ERR.
|
|
54
|
+
- fix ModbusClient: close the connection on an invalid MBAP header in a reply (the stream can't be trusted).
|
|
55
|
+
- fix ModbusClient: use an incremental MBAP transaction ID (from a random start value) instead of a random one at
|
|
56
|
+
each request, a late reply to the previous request is always detected.
|
|
57
|
+
- fix ModbusClient: avoid an AttributeError in __del__() when __init__() fails.
|
|
58
|
+
- fix ModbusServer: close the session on send timeout (a partial send leaves the TCP stream out of sync).
|
|
59
|
+
- fix ModbusServer.PDU: is_valid property was inverted.
|
|
60
|
+
- fix ModbusServer: an unexpected exception during a request (like one raised by a user callback) is now logged and
|
|
61
|
+
answered with a SLAVE_DEVICE_FAILURE (0x04) exception instead of dropping the TCP session.
|
|
62
|
+
- fix ModbusServer: a malformed request PDU (too short...) is answered with ILLEGAL DATA VALUE (0x03) and a request
|
|
63
|
+
with a function code >= 0x80 with ILLEGAL FUNCTION (0x01), the session was closed before.
|
|
64
|
+
- fix ModbusServer: a data handler that returns a wrong number of items gets a SLAVE_DEVICE_FAILURE (0x04).
|
|
65
|
+
- fix ModbusServer: start() no longer modifies class attributes of socketserver, since ThreadingTCPServer can be
|
|
66
|
+
shared with the rest of the process.
|
|
67
|
+
- fix ModbusServer: close the listening socket when start() fails to bind.
|
|
68
|
+
- fix ModbusServer: make function Write/Read Multiple Registers (0x17) atomic to prevent writing when the read range
|
|
69
|
+
is out of bounds.
|
|
70
|
+
- fix ModbusServer: ensure Write Single Coil (0x05) complies fully with the Modbus specification.
|
|
71
|
+
- fix ModbusServer: for functions 0x0F, 0x10 and 0x17 the byte count must exactly match the quantity.
|
|
72
|
+
- fix ModbusServer: Read Device Identification (0x2B/0x0E) compliance with the spec (stream access restarts at the
|
|
73
|
+
first object of the category, an unknown object in individual access gets exception 0x02).
|
|
74
|
+
- fix ModbusServer: support MBAP header length from 2 to 253.
|
|
75
|
+
- fix ModbusServer: limit client info to (address, port) for IPv6 peers.
|
|
76
|
+
- fix DataBank: set_coils(), set_discrete_inputs(), set_holding_registers() and set_input_registers() now check
|
|
77
|
+
their input. Non-integer items (float, str, None...) raise a TypeError (numpy integers and
|
|
78
|
+
booleans are accepted), and register values out of the 0-65535 range raise a ValueError.
|
|
79
|
+
Before, they were silently converted (a value like 70000 or -1 was truncated to 16 bits).
|
|
80
|
+
- fix utils: valid_host() returns False for an empty host or a host with a NUL char, it raised an IndexError or a
|
|
81
|
+
ValueError (so ModbusClient(host='') raised an IndexError instead of a ValueError).
|
|
82
|
+
- improve ModbusClient: decode/encode registers and bits in one pass (faster reads and writes).
|
|
83
|
+
- improve ModbusClient: set TCP_NODELAY on connect (new no_delay argument, on by default) to reduce latency on small
|
|
84
|
+
request/response frames.
|
|
85
|
+
- improve ModbusClient: improve socket lifecycle, parameter validation, and timeout safety.
|
|
86
|
+
- improve ModbusClient: add context manager support (with ModbusClient(...) as c:), closes the connection on exit.
|
|
87
|
+
- improve ModbusServer: decode/encode registers and bits in one pass for requests 0x01, 0x02, 0x0F, 0x10 and 0x17
|
|
88
|
+
(like the client), instead of one Python loop iteration per bit or register.
|
|
89
|
+
- improve ModbusServer: stop() is now faster, the main loop polls the stop request every 50 ms instead of 500 ms.
|
|
90
|
+
- improve ModbusServer: stop() now closes the active sessions and waits for the server thread.
|
|
91
|
+
- improve ModbusServer: add request_timeout (default 30 s): a client session with a stalled request (incomplete MBAP
|
|
92
|
+
header or PDU) is now closed, it was kept (with its thread) until the client closed it.
|
|
93
|
+
Set request_timeout=None to get the previous behavior.
|
|
94
|
+
- improve ModbusServer: add idle_timeout (close a session without any request for this time, default 300 s) and
|
|
95
|
+
max_connections (reject connections over this limit, default 64), None disables them.
|
|
96
|
+
- improve ModbusServer: add allowed_hosts (whitelist of client IP addresses or networks, CIDR notation) and
|
|
97
|
+
read_only (refuse the write functions 0x05, 0x06, 0x0F, 0x10 and 0x17), see SECURITY.md.
|
|
98
|
+
- improve ModbusServer: increase the listen backlog from 5 to 128, a burst of simultaneous connections (like clients
|
|
99
|
+
reconnecting together) no longer waits for a TCP retransmission (1 s or more).
|
|
100
|
+
- improve ModbusServer: allow dynamic TCP port allocation (port=0), start() returns the bound (host, port).
|
|
101
|
+
- improve ModbusServer: add is_running, wait(), active_sessions and shutdown_sessions().
|
|
102
|
+
- improve ModbusServer: an exception raised by an external engine (ext_engine) is logged and closes the session.
|
|
103
|
+
- improve DataBank: set_coils() and set_holding_registers() now compare the whole slice before writing, and
|
|
104
|
+
only build the list of changes when a server request needs it for the on_*_change()
|
|
105
|
+
callbacks. Writing unchanged values is much faster.
|
|
106
|
+
- improve DeviceIdentification: support the "in" operator, an object value over 244 bytes raises a ValueError.
|
|
107
|
+
- improve typing: type hints on the whole package and add py.typed (PEP 561).
|
|
108
|
+
- add SECURITY.md (threat model, deployment recommendations, server and client protections).
|
|
109
|
+
- add tools/ (benchmark, server fuzzing, code audit) and init_dev_venv.sh (test and build venv).
|
|
110
|
+
- examples: add server_dynamic_port.py, add type hints to examples.
|
|
111
|
+
|
|
112
|
+
0.3.1 2026-09-29
|
|
113
|
+
|
|
114
|
+
- fix ModbusServer: debug messages now include OSError exceptions produced by getpeername (thanks to Pär Åhlund).
|
|
115
|
+
- fix ModbusClient: prevent incomplete frame transmission by using sendall (thanks to aamir-azeez).
|
|
116
|
+
- updated compatibility test (python versions): remove 3.8/3.9, add 3.13/3.14.
|
|
117
|
+
|
|
118
|
+
0.3.0 2024-09-04
|
|
119
|
+
|
|
120
|
+
- pyModbusTCP.client: now use the standard logging method as in the server part.
|
|
121
|
+
- ModbusClient: debug flag is removed (see examples/client_debug.py).
|
|
122
|
+
|
|
123
|
+
0.2.2 2024-07-31
|
|
124
|
+
|
|
125
|
+
- fix ModbusServer: wrong check of discrete inputs length in DataBank (thanks to OTnetproj).
|
|
126
|
+
- updated compatibility test (python versions): remove 3.7, add 3.12.
|
|
127
|
+
|
|
128
|
+
0.2.1 2023-11-21
|
|
129
|
+
|
|
130
|
+
- fix ModbusServer: wrong check of input registers length in DataBank (thanks to monsieurvor).
|
|
131
|
+
- improve hostname validation in utils (thanks to MCXIV and schmocker).
|
|
132
|
+
- experimental add of read_device_identification() (over modbus encapsulated interface) to client and server.
|
|
133
|
+
- experimental add of write_read_multiple_registers() function (code 0x17) to client and server (thanks to tanj).
|
|
134
|
+
- updated compatibility test (python versions): remove 3.5/3.6, add 3.11.
|
|
135
|
+
|
|
136
|
+
0.2.0 2022-06-05
|
|
137
|
+
|
|
138
|
+
- ModbusClient: parameters are now properties instead of methods (more intuitive).
|
|
139
|
+
- ModbusClient: now TCP auto open mode is active by default (auto_open=True, auto_close=False).
|
|
140
|
+
- ModbusClient: add custom_request method for send user define PDU to modbus server.
|
|
141
|
+
- ModbusClient: remove RTU mode.
|
|
142
|
+
- ModbusClient: clarify some things (private methods and internal vars rename).
|
|
143
|
+
- ModbusServer: big redesign to improve readability and maintainability.
|
|
144
|
+
- ModbusServer: no longer use hard linked class DataBank (it now return a deprecation warn).
|
|
145
|
+
- ModbusServer: add of ModbusServerDataHandler and DefaultDataBank class for easy customize.
|
|
146
|
+
- add or update server examples for new modbus server design.
|
|
147
|
+
- some updates on tests, fix random arrays generation on client test part.
|
|
148
|
+
- clarify usage of root privilege for open tcp/502 (avoid Errno 13) in server example.
|
|
149
|
+
- python 2 end of support.
|
|
150
|
+
|
|
151
|
+
0.1.10 2021-03-02
|
|
152
|
+
|
|
153
|
+
- word_list_to_long() and long_list_to_word(), now support 64 bits long long with opt long_long.
|
|
154
|
+
- encode_ieee() and decode_ieee(), now support double-precision format with opt double.
|
|
155
|
+
- add shortcut alias for functions with long names in utils.
|
|
156
|
+
- rewrite of some functions in utils.
|
|
157
|
+
- improve test_utils readability.
|
|
158
|
+
- server DataBank enforce type check on set data methods to avoid server crash (thanks to xuantw).
|
|
159
|
+
- now get_2comp can deal with negative python int.
|
|
160
|
+
- remove reference to devel github branch.
|
|
161
|
+
- improve last_error_txt() and last_except_txt().
|
|
162
|
+
|
|
163
|
+
0.1.9 2021-02-26
|
|
164
|
+
|
|
165
|
+
- add module error MB_SOCK_CLOSE_ERR (occur if frame send on close socket).
|
|
166
|
+
- add modbus exception EXP_NEGATIVE_ACKNOWLEDGE (code 0x07) to constants.
|
|
167
|
+
- add last_error_txt() and last_except_txt() for produce human readable status.
|
|
168
|
+
- add EXP_TXT, EXP_DETAILS and MB_ERR_TXT dicts to constants (text representation of codes).
|
|
169
|
+
- update of the compatibility test for python version: remove 2.6/3.2/3.3, add 3.7/3.8/3.9.
|
|
170
|
+
- conform to PEP 396 (add pyModbusTCP.__version__ field).
|
|
171
|
+
|
|
172
|
+
0.1.8 2018-10-15
|
|
173
|
+
|
|
174
|
+
- fix ModbusServer: avoid hard coded TCP port (thanks to akobyl).
|
|
175
|
+
- add stop() and is_run property to ModbusServer (thanks to Rugiewitz).
|
|
176
|
+
|
|
177
|
+
0.1.7 2018-08-20
|
|
178
|
+
|
|
179
|
+
- fix ModbusServer issue on Windows (thanks to andreascian).
|
|
180
|
+
|
|
181
|
+
0.1.6 2018-05-14
|
|
182
|
+
|
|
183
|
+
- fix multiple TCP packets recv issue in ModbusClient and ModbusServer (thanks Farin94).
|
|
184
|
+
|
|
185
|
+
0.1.5 2017-11-23
|
|
186
|
+
|
|
187
|
+
- add long_list_to_word to utils.
|
|
188
|
+
- add float support as example.
|
|
189
|
+
|
|
190
|
+
0.1.4 2017-11-13
|
|
191
|
+
|
|
192
|
+
- fix port and host accessors, change check now use "==" and not "is".
|
|
193
|
+
|
|
194
|
+
0.1.3 2017-09-29
|
|
195
|
+
|
|
196
|
+
- setup now use setuptools.
|
|
197
|
+
|
|
198
|
+
0.1.2 2017-09-28
|
|
199
|
+
|
|
200
|
+
- fix 'Rx' label on error.
|
|
201
|
+
- change file mode for server.py example.
|
|
202
|
+
- fix compatibility with modbus unit_id = 0 (thanks to mfkenney).
|
|
203
|
+
- fix compatibility for modbus frame with garbage.
|
|
204
|
+
|
|
205
|
+
0.1.1 2016-05-30
|
|
206
|
+
|
|
207
|
+
- add toggle_bit() to utils.
|
|
208
|
+
- add server.py example.
|
|
209
|
+
- add HOWTO for safe PyPI upload.
|
|
210
|
+
|
|
211
|
+
0.1.0 2016-05-30
|
|
212
|
+
|
|
213
|
+
- fix some issues in PEP 8 conformance and inline doc.
|
|
214
|
+
- client modbus RTU: move crc16 compute to utils.
|
|
215
|
+
- add write_multiple_coils() function (code 0x0f).
|
|
216
|
+
- add test_bit(), set_bit(), reset_bit() to utils.
|
|
217
|
+
- add a modbus/TCP multithreaded server through ModbusServer class (for test only).
|
|
218
|
+
|
|
219
|
+
0.0.13 2015-12-24
|
|
220
|
+
|
|
221
|
+
- add auto_open and auto_close to README.rst and quickstart doc.
|
|
222
|
+
- add example min_read_bit.py for show minimal code approach.
|
|
223
|
+
|
|
224
|
+
0.0.12 2015-12-11
|
|
225
|
+
|
|
226
|
+
- add auto_open and auto_close mode to ModbusClient.
|
|
227
|
+
- add accessor function for socket timeout.
|
|
228
|
+
- close TCP socket if hostname change
|
|
229
|
+
- close TCP socket if port change
|
|
230
|
+
|
|
231
|
+
0.0.11 2015-03-27
|
|
232
|
+
|
|
233
|
+
- fix sock.settimeout missing (thanks to bonaime).
|
|
234
|
+
- fix PEP 8 style (thanks to bonaime).
|
|
235
|
+
|
|
236
|
+
0.0.10 2015-01-22
|
|
237
|
+
|
|
238
|
+
- Add timeout parameter to ModbusClient constructor (thanks to bonaime).
|
|
239
|
+
|
|
240
|
+
0.0.9 2014-10-10
|
|
241
|
+
|
|
242
|
+
- Fix rx_byte_count check in ModbusClient class.
|
|
243
|
+
|
|
244
|
+
0.0.8 2014-09-23
|
|
245
|
+
|
|
246
|
+
- Catch excepts on socket send/recv.
|
|
247
|
+
- Sphinx documentation include a quickstart and examples.
|
|
248
|
+
|
|
249
|
+
0.0.7 2014-08-31
|
|
250
|
+
|
|
251
|
+
- Add unit test (see test/).
|
|
252
|
+
- Add params host/port/unit_id/debug on ModbusClient constructor.
|
|
253
|
+
- Add utils module for modbus data mangling.
|
|
254
|
+
|
|
255
|
+
0.0.6 2014-08-25
|
|
256
|
+
|
|
257
|
+
- Fix "socket error" message when call open() on dual stack IPv6/4 host.
|
|
258
|
+
- Check rx byte count field in functions 1 to 4.
|
|
259
|
+
- Fix max bit number problem in functions 1 and 2 (from 125 to 2000).
|
|
260
|
+
- Add debug message, if _send() call on close socket.
|
|
261
|
+
- Rename module name from const to constants.
|
|
262
|
+
- Update MANIFEST.in to remove docs and examples from sdist archive.
|
|
263
|
+
- Update README.rst sample code for Python3.
|
|
264
|
+
|
|
265
|
+
0.0.5 2014-08-08
|
|
266
|
+
|
|
267
|
+
- Now deal with IPv6 host.
|
|
268
|
+
- Fix Python3 issue in _crc().
|
|
269
|
+
- Improve modbus RTU receive code.
|
|
270
|
+
- Secure frame size before struct.unpack invocation.
|
|
271
|
+
|
|
272
|
+
0.0.4 2014-08-07
|
|
273
|
+
|
|
274
|
+
- Add class documentation (add doc/ and sphinx/ directory).
|
|
275
|
+
- Add sphinx docstring in client.py.
|
|
276
|
+
|
|
277
|
+
0.0.3 2014-08-05
|
|
278
|
+
|
|
279
|
+
- Fix padding problem in write_single_coil().
|
|
280
|
+
- Add new examples.
|
|
281
|
+
|
|
282
|
+
0.0.2 2014-08-05
|
|
283
|
+
|
|
284
|
+
- Compatibility with Python 3 and 2.7.
|
|
285
|
+
- Use RST format for README instead of markdown, now set long_description.
|
|
286
|
+
- Add a MANIFEST.in file and include examples/ on sdist.
|
|
287
|
+
|
|
288
|
+
0.0.1 2014-08-04
|
|
289
|
+
|
|
290
|
+
- First release of pyModbusTCP.
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pyModbusTCP
|
|
3
|
+
Version: 0.4.0a1
|
|
4
|
+
Summary: A simple Modbus/TCP library for Python
|
|
5
|
+
Project-URL: Documentation, https://pymodbustcp.readthedocs.io/
|
|
6
|
+
Project-URL: Source, https://github.com/sourceperl/pyModbusTCP
|
|
7
|
+
Project-URL: Issues, https://github.com/sourceperl/pyModbusTCP/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/sourceperl/pyModbusTCP/blob/master/CHANGES
|
|
9
|
+
Author: Loïc Lefebvre
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: automation,client,industrial,modbus,modbus-tcp,plc,server
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: System :: Networking
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Provides-Extra: serial
|
|
28
|
+
Requires-Dist: pyserial<4,>=3.5; extra == 'serial'
|
|
29
|
+
Provides-Extra: tools
|
|
30
|
+
Requires-Dist: pymodbustcp-cli; extra == 'tools'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# pyModbusTCP [](https://github.com/sourceperl/pyModbusTCP/actions/workflows/tests.yml) [](https://pymodbustcp.readthedocs.io/)
|
|
34
|
+
|
|
35
|
+
A simple Modbus/TCP client and server library for Python.
|
|
36
|
+
|
|
37
|
+
pyModbusTCP is pure Python code without any extension or external module dependency.
|
|
38
|
+
|
|
39
|
+
## Tests
|
|
40
|
+
|
|
41
|
+
The module is currently tested on Python 3.10, 3.11, 3.12, 3.13 and 3.14, on Linux, macOS and Windows.
|
|
42
|
+
|
|
43
|
+
## Documentation
|
|
44
|
+
|
|
45
|
+
Documentation of the last release is available online at https://pymodbustcp.readthedocs.io/.
|
|
46
|
+
|
|
47
|
+
## Security
|
|
48
|
+
|
|
49
|
+
Modbus/TCP has no authentication and no encryption: never expose a Modbus/TCP server on the Internet or on an
|
|
50
|
+
untrusted network. See [SECURITY](https://github.com/sourceperl/pyModbusTCP/blob/master/SECURITY.md) for the
|
|
51
|
+
protections of the client and the server, the deployment recommendations, the known limitations and how to report
|
|
52
|
+
a vulnerability.
|
|
53
|
+
|
|
54
|
+
## Setup
|
|
55
|
+
|
|
56
|
+
Install the package in a virtual environment:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
python3 -m venv venv
|
|
60
|
+
source venv/bin/activate
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
From PyPI, the easy way:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# install the last available release (stable)
|
|
67
|
+
pip install pyModbusTCP
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# install a specific version (here release 0.3.1)
|
|
72
|
+
pip install pyModbusTCP==0.3.1
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Pre-release (alpha) of the next version 0.4.0, to test it before the final release: the command line tools, their
|
|
76
|
+
options and their output may still change. pip never installs a pre-release by default, ask for it explicitly:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# a specific pre-release
|
|
80
|
+
pip install pyModbusTCP==0.4.0a1
|
|
81
|
+
# or the latest release, pre-releases included
|
|
82
|
+
pip install --pre pyModbusTCP
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
From GitHub:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# install a specific version (here release 0.3.1) directly from github servers
|
|
89
|
+
pip install git+https://github.com/sourceperl/pyModbusTCP.git@v0.3.1
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Note on the use of versions:
|
|
93
|
+
|
|
94
|
+
Over time, some things can change. So, it's a good practice to always use a specific version of a package for your
|
|
95
|
+
project, instead of just relying on the default behavior: without it, the installation tools always install the latest
|
|
96
|
+
available version of a package. For example, in pyModbusTCP, the automatic TCP open mode (`auto_open`) is on by
|
|
97
|
+
default since version 0.2.0, it was off in the previous versions and doesn't exist before version 0.0.12. This can lead
|
|
98
|
+
to some strange behavior of your application if you are not aware of the change. Look at
|
|
99
|
+
[CHANGES](https://github.com/sourceperl/pyModbusTCP/blob/master/CHANGES) for details on the available versions.
|
|
100
|
+
|
|
101
|
+
## Usage example
|
|
102
|
+
|
|
103
|
+
See [examples/](https://github.com/sourceperl/pyModbusTCP/tree/master/examples) for full scripts.
|
|
104
|
+
|
|
105
|
+
### Client
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from pyModbusTCP.client import ModbusClient
|
|
109
|
+
|
|
110
|
+
# TCP connection is opened at the first request (auto_open is on by default) and kept open
|
|
111
|
+
c = ModbusClient(host='localhost', port=502, unit_id=1)
|
|
112
|
+
|
|
113
|
+
# or: TCP connection opened before each request and closed after it
|
|
114
|
+
c = ModbusClient(host='127.0.0.1', auto_close=True)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Read 2x 16 bits registers at modbus address 0:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
regs = c.read_holding_registers(0, 2)
|
|
121
|
+
|
|
122
|
+
if regs:
|
|
123
|
+
print(regs)
|
|
124
|
+
else:
|
|
125
|
+
print('read error: %s' % c.last_error_as_txt)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Write values 44 and 55 to registers at modbus address 10:
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
if c.write_multiple_registers(10, [44, 55]):
|
|
132
|
+
print('write ok')
|
|
133
|
+
else:
|
|
134
|
+
print('write error: %s' % c.last_error_as_txt)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Use the client as a context manager (the TCP connection is closed at the end of the block):
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
with ModbusClient(host='localhost', port=502) as c:
|
|
141
|
+
print(c.read_coils(0, 8))
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Server
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from pyModbusTCP.server import ModbusServer
|
|
148
|
+
|
|
149
|
+
# listen on localhost only (the default host), port 502 needs root privileges on Unix systems: use another one
|
|
150
|
+
server = ModbusServer(host='localhost', port=5020, no_block=True)
|
|
151
|
+
server.start()
|
|
152
|
+
|
|
153
|
+
# update the data seen by the clients from the application
|
|
154
|
+
server.data_bank.set_holding_registers(0, [1, 2, 3])
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
A server open to the network, with some access restrictions (see
|
|
158
|
+
[SECURITY](https://github.com/sourceperl/pyModbusTCP/blob/master/SECURITY.md)):
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
# only the hosts of the 192.168.1.0/24 network can connect, every write request is refused
|
|
162
|
+
server = ModbusServer(host='0.0.0.0', port=5020, allowed_hosts=['192.168.1.0/24'], read_only=True)
|
|
163
|
+
server.start()
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Command line tools
|
|
167
|
+
|
|
168
|
+
***The tools are new in 0.4.0 (only pre-releases for now): without a version or `--pre`, `pip install "pyModbusTCP"`
|
|
169
|
+
installs the stable 0.3.1, without the tools (pip only shows a warning).***
|
|
170
|
+
|
|
171
|
+
The library comes with command line tools: a Modbus/TCP server, a Modbus/TCP client, and two gateways between
|
|
172
|
+
Modbus/TCP and Modbus/RTU (serial line). They run from the library itself:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
python -m pyModbusTCP.tools server --help
|
|
176
|
+
python -m pyModbusTCP.tools client -H 192.168.1.10 read-holding 0 -n 4
|
|
177
|
+
|
|
178
|
+
# the gateways need pyserial (an optional dependency)
|
|
179
|
+
pip install "pyModbusTCP[serial]"
|
|
180
|
+
python -m pyModbusTCP.tools tcp2rtu --help
|
|
181
|
+
python -m pyModbusTCP.tools rtu2tcp --help
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
To have them as commands in the PATH (`mbtcp-server`, `mbtcp-client`, `mbtcp-tcp2rtu` and `mbtcp-rtu2tcp`),
|
|
185
|
+
install the optional package pyModbusTCP-cli. A plain `pip install pyModbusTCP` puts no command in the PATH.
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# in a virtual environment, with the library
|
|
189
|
+
pip install "pyModbusTCP[tools]==0.4.0a1"
|
|
190
|
+
# or as isolated command line tools
|
|
191
|
+
pipx install pyModbusTCP-cli
|
|
192
|
+
```
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# pyModbusTCP [](https://github.com/sourceperl/pyModbusTCP/actions/workflows/tests.yml) [](https://pymodbustcp.readthedocs.io/)
|
|
2
|
+
|
|
3
|
+
A simple Modbus/TCP client and server library for Python.
|
|
4
|
+
|
|
5
|
+
pyModbusTCP is pure Python code without any extension or external module dependency.
|
|
6
|
+
|
|
7
|
+
## Tests
|
|
8
|
+
|
|
9
|
+
The module is currently tested on Python 3.10, 3.11, 3.12, 3.13 and 3.14, on Linux, macOS and Windows.
|
|
10
|
+
|
|
11
|
+
## Documentation
|
|
12
|
+
|
|
13
|
+
Documentation of the last release is available online at https://pymodbustcp.readthedocs.io/.
|
|
14
|
+
|
|
15
|
+
## Security
|
|
16
|
+
|
|
17
|
+
Modbus/TCP has no authentication and no encryption: never expose a Modbus/TCP server on the Internet or on an
|
|
18
|
+
untrusted network. See [SECURITY](https://github.com/sourceperl/pyModbusTCP/blob/master/SECURITY.md) for the
|
|
19
|
+
protections of the client and the server, the deployment recommendations, the known limitations and how to report
|
|
20
|
+
a vulnerability.
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
Install the package in a virtual environment:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
python3 -m venv venv
|
|
28
|
+
source venv/bin/activate
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
From PyPI, the easy way:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# install the last available release (stable)
|
|
35
|
+
pip install pyModbusTCP
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# install a specific version (here release 0.3.1)
|
|
40
|
+
pip install pyModbusTCP==0.3.1
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Pre-release (alpha) of the next version 0.4.0, to test it before the final release: the command line tools, their
|
|
44
|
+
options and their output may still change. pip never installs a pre-release by default, ask for it explicitly:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# a specific pre-release
|
|
48
|
+
pip install pyModbusTCP==0.4.0a1
|
|
49
|
+
# or the latest release, pre-releases included
|
|
50
|
+
pip install --pre pyModbusTCP
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
From GitHub:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# install a specific version (here release 0.3.1) directly from github servers
|
|
57
|
+
pip install git+https://github.com/sourceperl/pyModbusTCP.git@v0.3.1
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Note on the use of versions:
|
|
61
|
+
|
|
62
|
+
Over time, some things can change. So, it's a good practice to always use a specific version of a package for your
|
|
63
|
+
project, instead of just relying on the default behavior: without it, the installation tools always install the latest
|
|
64
|
+
available version of a package. For example, in pyModbusTCP, the automatic TCP open mode (`auto_open`) is on by
|
|
65
|
+
default since version 0.2.0, it was off in the previous versions and doesn't exist before version 0.0.12. This can lead
|
|
66
|
+
to some strange behavior of your application if you are not aware of the change. Look at
|
|
67
|
+
[CHANGES](https://github.com/sourceperl/pyModbusTCP/blob/master/CHANGES) for details on the available versions.
|
|
68
|
+
|
|
69
|
+
## Usage example
|
|
70
|
+
|
|
71
|
+
See [examples/](https://github.com/sourceperl/pyModbusTCP/tree/master/examples) for full scripts.
|
|
72
|
+
|
|
73
|
+
### Client
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pyModbusTCP.client import ModbusClient
|
|
77
|
+
|
|
78
|
+
# TCP connection is opened at the first request (auto_open is on by default) and kept open
|
|
79
|
+
c = ModbusClient(host='localhost', port=502, unit_id=1)
|
|
80
|
+
|
|
81
|
+
# or: TCP connection opened before each request and closed after it
|
|
82
|
+
c = ModbusClient(host='127.0.0.1', auto_close=True)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Read 2x 16 bits registers at modbus address 0:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
regs = c.read_holding_registers(0, 2)
|
|
89
|
+
|
|
90
|
+
if regs:
|
|
91
|
+
print(regs)
|
|
92
|
+
else:
|
|
93
|
+
print('read error: %s' % c.last_error_as_txt)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Write values 44 and 55 to registers at modbus address 10:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
if c.write_multiple_registers(10, [44, 55]):
|
|
100
|
+
print('write ok')
|
|
101
|
+
else:
|
|
102
|
+
print('write error: %s' % c.last_error_as_txt)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Use the client as a context manager (the TCP connection is closed at the end of the block):
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
with ModbusClient(host='localhost', port=502) as c:
|
|
109
|
+
print(c.read_coils(0, 8))
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Server
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from pyModbusTCP.server import ModbusServer
|
|
116
|
+
|
|
117
|
+
# listen on localhost only (the default host), port 502 needs root privileges on Unix systems: use another one
|
|
118
|
+
server = ModbusServer(host='localhost', port=5020, no_block=True)
|
|
119
|
+
server.start()
|
|
120
|
+
|
|
121
|
+
# update the data seen by the clients from the application
|
|
122
|
+
server.data_bank.set_holding_registers(0, [1, 2, 3])
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
A server open to the network, with some access restrictions (see
|
|
126
|
+
[SECURITY](https://github.com/sourceperl/pyModbusTCP/blob/master/SECURITY.md)):
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
# only the hosts of the 192.168.1.0/24 network can connect, every write request is refused
|
|
130
|
+
server = ModbusServer(host='0.0.0.0', port=5020, allowed_hosts=['192.168.1.0/24'], read_only=True)
|
|
131
|
+
server.start()
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Command line tools
|
|
135
|
+
|
|
136
|
+
***The tools are new in 0.4.0 (only pre-releases for now): without a version or `--pre`, `pip install "pyModbusTCP"`
|
|
137
|
+
installs the stable 0.3.1, without the tools (pip only shows a warning).***
|
|
138
|
+
|
|
139
|
+
The library comes with command line tools: a Modbus/TCP server, a Modbus/TCP client, and two gateways between
|
|
140
|
+
Modbus/TCP and Modbus/RTU (serial line). They run from the library itself:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
python -m pyModbusTCP.tools server --help
|
|
144
|
+
python -m pyModbusTCP.tools client -H 192.168.1.10 read-holding 0 -n 4
|
|
145
|
+
|
|
146
|
+
# the gateways need pyserial (an optional dependency)
|
|
147
|
+
pip install "pyModbusTCP[serial]"
|
|
148
|
+
python -m pyModbusTCP.tools tcp2rtu --help
|
|
149
|
+
python -m pyModbusTCP.tools rtu2tcp --help
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
To have them as commands in the PATH (`mbtcp-server`, `mbtcp-client`, `mbtcp-tcp2rtu` and `mbtcp-rtu2tcp`),
|
|
153
|
+
install the optional package pyModbusTCP-cli. A plain `pip install pyModbusTCP` puts no command in the PATH.
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# in a virtual environment, with the library
|
|
157
|
+
pip install "pyModbusTCP[tools]==0.4.0a1"
|
|
158
|
+
# or as isolated command line tools
|
|
159
|
+
pipx install pyModbusTCP-cli
|
|
160
|
+
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Python package: Client and Server for ModBus/TCP
|
|
2
2
|
# Website: https://github.com/sourceperl/pyModbusTCP
|
|
3
|
-
# License: MIT (
|
|
3
|
+
# License: MIT (https://opensource.org/license/mit)
|
|
4
4
|
# Description: Client/Server ModBus/TCP
|
|
5
5
|
# Support functions 3 and 16 (class 0)
|
|
6
6
|
# 1,2,4,5,6 (Class 1)
|