pyModbusTCP 0.4.0a2__tar.gz → 0.4.0a3__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.
Files changed (63) hide show
  1. pymodbustcp-0.4.0a3/CHANGES +268 -0
  2. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/PKG-INFO +5 -5
  3. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/README.md +3 -3
  4. pymodbustcp-0.4.0a3/hatch_metadata.py +28 -0
  5. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/__init__.py +3 -3
  6. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/client/__init__.py +0 -1
  7. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/client/_errors.py +4 -1
  8. pymodbustcp-0.4.0a3/pyModbusTCP/client/_functions.py +426 -0
  9. pymodbustcp-0.4.0a3/pyModbusTCP/client/_transport.py +473 -0
  10. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/client/_validators.py +38 -1
  11. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/client/modbus_client.py +91 -18
  12. pymodbustcp-0.4.0a3/pyModbusTCP/codec.py +268 -0
  13. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/constants.py +10 -2
  14. pymodbustcp-0.4.0a3/pyModbusTCP/server/__init__.py +48 -0
  15. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/server/_common.py +26 -9
  16. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/server/_transport.py +103 -32
  17. pymodbustcp-0.4.0a3/pyModbusTCP/server/_validators.py +232 -0
  18. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/server/device_id.py +19 -2
  19. pymodbustcp-0.4.0a3/pyModbusTCP/server/errors.py +91 -0
  20. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/server/frames.py +1 -1
  21. pymodbustcp-0.4.0a3/pyModbusTCP/server/functions.py +254 -0
  22. pymodbustcp-0.4.0a3/pyModbusTCP/server/modbus_server.py +590 -0
  23. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/server/session.py +1 -16
  24. pymodbustcp-0.4.0a3/pyModbusTCP/server/store.py +596 -0
  25. pymodbustcp-0.4.0a3/pyModbusTCP/server/wrappers.py +141 -0
  26. pymodbustcp-0.4.0a3/pyModbusTCP/tools/_common.py +323 -0
  27. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/tools/_entry.py +8 -1
  28. pymodbustcp-0.4.0a3/pyModbusTCP/tools/_rtu.py +156 -0
  29. pymodbustcp-0.4.0a3/pyModbusTCP/tools/client.py +959 -0
  30. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/tools/rtu_to_tcp_gw.py +178 -166
  31. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/tools/server.py +40 -40
  32. pymodbustcp-0.4.0a3/pyModbusTCP/tools/tcp_to_rtu_gw.py +1049 -0
  33. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/utils.py +81 -31
  34. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyproject.toml +12 -9
  35. pymodbustcp-0.4.0a3/tests/test_client.py +1068 -0
  36. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/tests/test_client_server.py +107 -38
  37. pymodbustcp-0.4.0a3/tests/test_codec.py +165 -0
  38. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/tests/test_server.py +550 -220
  39. pymodbustcp-0.4.0a3/tests/test_store.py +594 -0
  40. pymodbustcp-0.4.0a3/tests/test_tools.py +1541 -0
  41. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/tests/test_utils.py +59 -2
  42. pymodbustcp-0.4.0a2/CHANGES +0 -355
  43. pymodbustcp-0.4.0a2/pyModbusTCP/client/_functions.py +0 -386
  44. pymodbustcp-0.4.0a2/pyModbusTCP/client/_transport.py +0 -294
  45. pymodbustcp-0.4.0a2/pyModbusTCP/server/__init__.py +0 -22
  46. pymodbustcp-0.4.0a2/pyModbusTCP/server/_functions.py +0 -365
  47. pymodbustcp-0.4.0a2/pyModbusTCP/server/_validators.py +0 -105
  48. pymodbustcp-0.4.0a2/pyModbusTCP/server/data_bank.py +0 -316
  49. pymodbustcp-0.4.0a2/pyModbusTCP/server/data_handler.py +0 -156
  50. pymodbustcp-0.4.0a2/pyModbusTCP/server/errors.py +0 -19
  51. pymodbustcp-0.4.0a2/pyModbusTCP/server/modbus_server.py +0 -357
  52. pymodbustcp-0.4.0a2/pyModbusTCP/tools/_common.py +0 -125
  53. pymodbustcp-0.4.0a2/pyModbusTCP/tools/client.py +0 -222
  54. pymodbustcp-0.4.0a2/pyModbusTCP/tools/tcp_to_rtu_gw.py +0 -693
  55. pymodbustcp-0.4.0a2/tests/test_client.py +0 -468
  56. pymodbustcp-0.4.0a2/tests/test_tools.py +0 -612
  57. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/.gitignore +0 -0
  58. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/LICENSE +0 -0
  59. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/client/_common.py +0 -0
  60. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/client/device_id.py +0 -0
  61. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/py.typed +0 -0
  62. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/tools/__init__.py +0 -0
  63. {pymodbustcp-0.4.0a2 → pymodbustcp-0.4.0a3}/pyModbusTCP/tools/__main__.py +0 -0
@@ -0,0 +1,268 @@
1
+ Revision history for pyModbusTCP
2
+
3
+ 0.4.0a3 2026-10-27 (alpha: the command line tools, their options and output, may still change before 0.4.0)
4
+
5
+ Summary of the changes since 0.3.1 (0.4.0a1 and 0.4.0a2 included). The details are in the documentation
6
+ (https://pymodbustcp.readthedocs.io/), the security choices in SECURITY.md.
7
+
8
+ Breaking changes, client:
9
+
10
+ - stricter argument checks: TypeError/ValueError instead of a silent conversion or truncation (numpy booleans are
11
+ no longer coil values), ModbusClient(host=...) refuses the legacy IPv4 forms ("127.1", "192.168.010.1"...).
12
+ - the arguments of ModbusClient after auto_close are keyword-only, no_delay is renamed tcp_no_delay.
13
+ - the request methods use the same argument names: address, count, value, values (write_address, write_values,
14
+ read_address, read_count for write_read_multiple_registers()). The old names (bit_addr=, reg_nb=,
15
+ regs_value=...) raise TypeError: give the values by position, or with the new names.
16
+ - an invalid reply (MBAP header, function code, size or echo that don't match the request, extra data) sets
17
+ last_error to MB_FRAME_ERR: MB_RECV_ERR is now a network error only. A device that pads its replies is refused.
18
+
19
+ Breaking changes, server:
20
+
21
+ - DataBank and DataHandler are replaced by a data store (MemoryStore), see "Migrating from DataBank and
22
+ DataHandler" in the server guide.
23
+ - secure defaults: idle_timeout (300 s), request_timeout (30 s), max_connections (64) and max_connections_per_host
24
+ (16), None disables them. start() raises NetworkError if already running.
25
+ - the arguments of ModbusServer after no_block are keyword-only, no_block and ipv6 must be bools.
26
+ - an empty host is refused (write '0.0.0.0' or '::' to listen on every interface), so is a legacy IPv4 form that
27
+ bind() reads as another address ("0", "127.1", "192.168.010.1").
28
+ - allowed_hosts is a tuple of str. In an allow list (allowed_hosts, AccessControl, -A/--allow of the tools), an
29
+ entry with host bits set ("192.168.1.5/24"), a link-local entry or an entry with an interface is refused, an
30
+ IPv4-mapped entry is converted to IPv4.
31
+ - the typed shortcuts of the store take a byte_order (ByteOrder, default ABCD) instead of big_endian
32
+ (big_endian=False is ByteOrder.CDAB).
33
+
34
+ Breaking changes, other:
35
+
36
+ - tools: mbtcp-tcp2rtu relays only the standard data functions by default (the others get exception 0x01),
37
+ "--functions all" relays every function as before.
38
+ - utils: word_list_to_long() raises ValueError when the number of words is not a multiple of 2 (4 with
39
+ long_long): the extra words were ignored.
40
+ - examples: client_serial_gw.py and server_serial_gw.py are removed (replaced by the gateways of the tools).
41
+
42
+ New features:
43
+
44
+ - server: transactions (every request is atomic, 0x17 included), access rules (ReadOnly, AccessControl, Guard),
45
+ one store per unit id, read_only, allowed_hosts. The settings are properties, checked like in the constructor,
46
+ that apply at once to a running server.
47
+ - codec: Codec(DataType, ByteOrder) for 16/32/64 bits integers and IEEE floats, in 4 byte orders (8 for 64 bits
48
+ values with ByteOrder64), for the client and the store; a typed shortcut of the store for each DataType.
49
+ - client: context manager, tcp_no_delay, timeout for the whole request, broadcast (unit id 0, no reply, spaced by
50
+ broadcast_interval), connect retries with backoff (connect_retries, connect_retry_delay). auto_open reconnects
51
+ for the current request, is_open is False as soon as the server has closed the connection.
52
+ - tools: mbtcp-server, mbtcp-client (table, csv/json, typed values), mbtcp-tcp2rtu and mbtcp-rtu2tcp gateways
53
+ (RS-485 mode, pyserial), with "python -m pyModbusTCP.tools" or the commands of "pip install pyModbusTCP[cli]".
54
+ mbtcp-tcp2rtu: whitelist of the relayed functions (--functions, --read-only), broadcasts (--allow-broadcast,
55
+ with a bounded buffer and a maximum age).
56
+ - server/tools: ipv6_host_prefix (--ipv6-host-prefix): the IPv6 network counted as one host by the limits.
57
+ - typing: type hints on the whole package (py.typed). docs: Sphinx documentation rewritten, SECURITY.md.
58
+
59
+ Fixes:
60
+
61
+ - client: robustness (timeouts, invalid replies, transaction ids, is_open, write replies check), a link-local
62
+ IPv6 address is accepted with its interface only.
63
+ - server: Modbus compliance (0x05, 0x0F, 0x10, 0x17, 0x2B/0x0E and its conformity level, MBAP length), a
64
+ malformed request is answered with an exception, a handler response too short, too long or of another function
65
+ is replaced by a "slave device failure", listen on a link-local IPv6 address.
66
+ - server: Request.reply() and unpack() use the byte order prefix of their format, no prefix is big endian
67
+ (reply() dropped the prefix, unpack() used the order of the host).
68
+ - server: read_only also refuses 0x15 and 0x16, a fallback handler only gets the read functions (a handler of the
69
+ application that writes tests server.read_only); allowed_hosts set after the constructor was ignored.
70
+ - security: port hijacking on Windows (SO_EXCLUSIVEADDRUSE); an error of user code is logged with a rate limit
71
+ (a client could fill the disk with tracebacks); bounded queue of the change events; formula injection in the
72
+ csv of mbtcp-client device-id (CWE-1236).
73
+ - tools: mbtcp-tcp2rtu no longer returns a late reply of a slave as the response of another request (a client
74
+ could read the value of another address) and has a fair queue by client host; mbtcp-rtu2tcp no longer blocks
75
+ the serial line while a broadcast is relayed.
76
+ - tools: stricter checks of the options (--max-connections, -u...); codec: decode() refuses a register out of 0
77
+ to 65535; utils: valid_host() edge cases (legacy IPv4 forms, length, NUL and non-ASCII chars).
78
+
79
+ Build: pyproject.toml with hatchling, Python 3.10 to 3.14. pyModbusTCP[cli]==X installs exactly
80
+ pyModbusTCP-cli X, which requires exactly pyModbusTCP X.
81
+
82
+ 0.4.0a2 2026-10-17 (alpha)
83
+
84
+ See 0.4.0a3.
85
+
86
+ 0.4.0a1 2026-10-15 (alpha)
87
+
88
+ See 0.4.0a3.
89
+
90
+ 0.3.1 2026-09-29
91
+
92
+ - fix ModbusServer: debug messages now include OSError exceptions produced by getpeername (thanks to Pär Åhlund).
93
+ - fix ModbusClient: prevent incomplete frame transmission by using sendall (thanks to aamir-azeez).
94
+ - updated compatibility test (python versions): remove 3.8/3.9, add 3.13/3.14.
95
+
96
+ 0.3.0 2024-09-04
97
+
98
+ - pyModbusTCP.client: now use the standard logging method as in the server part.
99
+ - ModbusClient: debug flag is removed (see examples/client_debug.py).
100
+
101
+ 0.2.2 2024-07-31
102
+
103
+ - fix ModbusServer: wrong check of discrete inputs length in DataBank (thanks to OTnetproj).
104
+ - updated compatibility test (python versions): remove 3.7, add 3.12.
105
+
106
+ 0.2.1 2023-11-21
107
+
108
+ - fix ModbusServer: wrong check of input registers length in DataBank (thanks to monsieurvor).
109
+ - improve hostname validation in utils (thanks to MCXIV and schmocker).
110
+ - experimental add of read_device_identification() (over modbus encapsulated interface) to client and server.
111
+ - experimental add of write_read_multiple_registers() function (code 0x17) to client and server (thanks to tanj).
112
+ - updated compatibility test (python versions): remove 3.5/3.6, add 3.11.
113
+
114
+ 0.2.0 2022-06-05
115
+
116
+ - ModbusClient: parameters are now properties instead of methods (more intuitive).
117
+ - ModbusClient: now TCP auto open mode is active by default (auto_open=True, auto_close=False).
118
+ - ModbusClient: add custom_request method for send user define PDU to modbus server.
119
+ - ModbusClient: remove RTU mode.
120
+ - ModbusClient: clarify some things (private methods and internal vars rename).
121
+ - ModbusServer: big redesign to improve readability and maintainability.
122
+ - ModbusServer: no longer use hard linked class DataBank (it now return a deprecation warn).
123
+ - ModbusServer: add of ModbusServerDataHandler and DefaultDataBank class for easy customize.
124
+ - add or update server examples for new modbus server design.
125
+ - some updates on tests, fix random arrays generation on client test part.
126
+ - clarify usage of root privilege for open tcp/502 (avoid Errno 13) in server example.
127
+ - python 2 end of support.
128
+
129
+ 0.1.10 2021-03-02
130
+
131
+ - word_list_to_long() and long_list_to_word(), now support 64 bits long long with opt long_long.
132
+ - encode_ieee() and decode_ieee(), now support double-precision format with opt double.
133
+ - add shortcut alias for functions with long names in utils.
134
+ - rewrite of some functions in utils.
135
+ - improve test_utils readability.
136
+ - server DataBank enforce type check on set data methods to avoid server crash (thanks to xuantw).
137
+ - now get_2comp can deal with negative python int.
138
+ - remove reference to devel github branch.
139
+ - improve last_error_txt() and last_except_txt().
140
+
141
+ 0.1.9 2021-02-26
142
+
143
+ - add module error MB_SOCK_CLOSE_ERR (occur if frame send on close socket).
144
+ - add modbus exception EXP_NEGATIVE_ACKNOWLEDGE (code 0x07) to constants.
145
+ - add last_error_txt() and last_except_txt() for produce human readable status.
146
+ - add EXP_TXT, EXP_DETAILS and MB_ERR_TXT dicts to constants (text representation of codes).
147
+ - update of the compatibility test for python version: remove 2.6/3.2/3.3, add 3.7/3.8/3.9.
148
+ - conform to PEP 396 (add pyModbusTCP.__version__ field).
149
+
150
+ 0.1.8 2018-10-15
151
+
152
+ - fix ModbusServer: avoid hard coded TCP port (thanks to akobyl).
153
+ - add stop() and is_run property to ModbusServer (thanks to Rugiewitz).
154
+
155
+ 0.1.7 2018-08-20
156
+
157
+ - fix ModbusServer issue on Windows (thanks to andreascian).
158
+
159
+ 0.1.6 2018-05-14
160
+
161
+ - fix multiple TCP packets recv issue in ModbusClient and ModbusServer (thanks Farin94).
162
+
163
+ 0.1.5 2017-11-23
164
+
165
+ - add long_list_to_word to utils.
166
+ - add float support as example.
167
+
168
+ 0.1.4 2017-11-13
169
+
170
+ - fix port and host accessors, change check now use "==" and not "is".
171
+
172
+ 0.1.3 2017-09-29
173
+
174
+ - setup now use setuptools.
175
+
176
+ 0.1.2 2017-09-28
177
+
178
+ - fix 'Rx' label on error.
179
+ - change file mode for server.py example.
180
+ - fix compatibility with modbus unit_id = 0 (thanks to mfkenney).
181
+ - fix compatibility for modbus frame with garbage.
182
+
183
+ 0.1.1 2016-05-30
184
+
185
+ - add toggle_bit() to utils.
186
+ - add server.py example.
187
+ - add HOWTO for safe PyPI upload.
188
+
189
+ 0.1.0 2016-05-30
190
+
191
+ - fix some issues in PEP 8 conformance and inline doc.
192
+ - client modbus RTU: move crc16 compute to utils.
193
+ - add write_multiple_coils() function (code 0x0f).
194
+ - add test_bit(), set_bit(), reset_bit() to utils.
195
+ - add a modbus/TCP multithreaded server through ModbusServer class (for test only).
196
+
197
+ 0.0.13 2015-12-24
198
+
199
+ - add auto_open and auto_close to README.rst and quickstart doc.
200
+ - add example min_read_bit.py for show minimal code approach.
201
+
202
+ 0.0.12 2015-12-11
203
+
204
+ - add auto_open and auto_close mode to ModbusClient.
205
+ - add accessor function for socket timeout.
206
+ - close TCP socket if hostname change
207
+ - close TCP socket if port change
208
+
209
+ 0.0.11 2015-03-27
210
+
211
+ - fix sock.settimeout missing (thanks to bonaime).
212
+ - fix PEP 8 style (thanks to bonaime).
213
+
214
+ 0.0.10 2015-01-22
215
+
216
+ - Add timeout parameter to ModbusClient constructor (thanks to bonaime).
217
+
218
+ 0.0.9 2014-10-10
219
+
220
+ - Fix rx_byte_count check in ModbusClient class.
221
+
222
+ 0.0.8 2014-09-23
223
+
224
+ - Catch excepts on socket send/recv.
225
+ - Sphinx documentation include a quickstart and examples.
226
+
227
+ 0.0.7 2014-08-31
228
+
229
+ - Add unit test (see test/).
230
+ - Add params host/port/unit_id/debug on ModbusClient constructor.
231
+ - Add utils module for modbus data mangling.
232
+
233
+ 0.0.6 2014-08-25
234
+
235
+ - Fix "socket error" message when call open() on dual stack IPv6/4 host.
236
+ - Check rx byte count field in functions 1 to 4.
237
+ - Fix max bit number problem in functions 1 and 2 (from 125 to 2000).
238
+ - Add debug message, if _send() call on close socket.
239
+ - Rename module name from const to constants.
240
+ - Update MANIFEST.in to remove docs and examples from sdist archive.
241
+ - Update README.rst sample code for Python3.
242
+
243
+ 0.0.5 2014-08-08
244
+
245
+ - Now deal with IPv6 host.
246
+ - Fix Python3 issue in _crc().
247
+ - Improve modbus RTU receive code.
248
+ - Secure frame size before struct.unpack invocation.
249
+
250
+ 0.0.4 2014-08-07
251
+
252
+ - Add class documentation (add doc/ and sphinx/ directory).
253
+ - Add sphinx docstring in client.py.
254
+
255
+ 0.0.3 2014-08-05
256
+
257
+ - Fix padding problem in write_single_coil().
258
+ - Add new examples.
259
+
260
+ 0.0.2 2014-08-05
261
+
262
+ - Compatibility with Python 3 and 2.7.
263
+ - Use RST format for README instead of markdown, now set long_description.
264
+ - Add a MANIFEST.in file and include examples/ on sdist.
265
+
266
+ 0.0.1 2014-08-04
267
+
268
+ - First release of pyModbusTCP.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pyModbusTCP
3
- Version: 0.4.0a2
3
+ Version: 0.4.0a3
4
4
  Summary: A simple Modbus/TCP library for Python
5
5
  Project-URL: Documentation, https://pymodbustcp.readthedocs.io/
6
6
  Project-URL: Source, https://github.com/sourceperl/pyModbusTCP
@@ -25,7 +25,7 @@ Classifier: Topic :: System :: Networking
25
25
  Classifier: Typing :: Typed
26
26
  Requires-Python: >=3.10
27
27
  Provides-Extra: cli
28
- Requires-Dist: pymodbustcp-cli; extra == 'cli'
28
+ Requires-Dist: pymodbustcp-cli==0.4.0a3; extra == 'cli'
29
29
  Provides-Extra: serial
30
30
  Requires-Dist: pyserial<4,>=3.5; extra == 'serial'
31
31
  Description-Content-Type: text/markdown
@@ -77,7 +77,7 @@ options and their output may still change. pip never installs a pre-release by d
77
77
 
78
78
  ```bash
79
79
  # a specific pre-release
80
- pip install pyModbusTCP==0.4.0a2
80
+ pip install pyModbusTCP==0.4.0a3
81
81
  # or the latest release, pre-releases included
82
82
  pip install --pre pyModbusTCP
83
83
  ```
@@ -151,7 +151,7 @@ server = ModbusServer(host='localhost', port=5020, no_block=True)
151
151
  server.start()
152
152
 
153
153
  # update the data seen by the clients from the application
154
- server.data_bank.set_holding_registers(0, [1, 2, 3])
154
+ server.store.app.holding_registers.write(0, [1, 2, 3])
155
155
  ```
156
156
 
157
157
  A server open to the network, with some access restrictions (see
@@ -186,7 +186,7 @@ install the optional package pyModbusTCP-cli. A plain `pip install pyModbusTCP`
186
186
 
187
187
  ```bash
188
188
  # in a virtual environment, with the library
189
- pip install "pyModbusTCP[cli]==0.4.0a2"
189
+ pip install "pyModbusTCP[cli]==0.4.0a3"
190
190
  # or as isolated command line tools
191
191
  pipx install pyModbusTCP-cli
192
192
  ```
@@ -45,7 +45,7 @@ options and their output may still change. pip never installs a pre-release by d
45
45
 
46
46
  ```bash
47
47
  # a specific pre-release
48
- pip install pyModbusTCP==0.4.0a2
48
+ pip install pyModbusTCP==0.4.0a3
49
49
  # or the latest release, pre-releases included
50
50
  pip install --pre pyModbusTCP
51
51
  ```
@@ -119,7 +119,7 @@ server = ModbusServer(host='localhost', port=5020, no_block=True)
119
119
  server.start()
120
120
 
121
121
  # update the data seen by the clients from the application
122
- server.data_bank.set_holding_registers(0, [1, 2, 3])
122
+ server.store.app.holding_registers.write(0, [1, 2, 3])
123
123
  ```
124
124
 
125
125
  A server open to the network, with some access restrictions (see
@@ -154,7 +154,7 @@ install the optional package pyModbusTCP-cli. A plain `pip install pyModbusTCP`
154
154
 
155
155
  ```bash
156
156
  # in a virtual environment, with the library
157
- pip install "pyModbusTCP[cli]==0.4.0a2"
157
+ pip install "pyModbusTCP[cli]==0.4.0a3"
158
158
  # or as isolated command line tools
159
159
  pipx install pyModbusTCP-cli
160
160
  ```
@@ -0,0 +1,28 @@
1
+ """Build of pyModbusTCP: the cli extra requires exactly the release of pyModbusTCP-cli of the same version.
2
+
3
+ pyModbusTCP-cli has no code, only the commands and its dependencies: "pip install pyModbusTCP[cli]==X" installs
4
+ exactly the commands released (and tested) with X, never another release with other dependencies. The other way is
5
+ set by pyModbusTCP-cli/hatch_metadata_cli.py (pyModbusTCP-cli X requires pyModbusTCP[serial]==X).
6
+
7
+ The version is read from pyModbusTCP/constants.py by hatchling ([tool.hatch.version] of pyproject.toml): no version to
8
+ update by hand. This file is in the sdist, so a build from it (like the one of a downstream packager) runs it too.
9
+
10
+ The metadata hook of [tool.hatch.metadata.hooks.custom] (path = "hatch_metadata.py" in pyproject.toml): not the default
11
+ name hatch_build.py, and not the name of the hook of pyModbusTCP-cli (hatch_metadata_cli.py): two modules of the
12
+ same name would stop mypy.
13
+ """
14
+
15
+ from typing import Any
16
+
17
+ from hatchling.metadata.plugin.interface import MetadataHookInterface
18
+
19
+
20
+ class CustomMetadataHook(MetadataHookInterface):
21
+ def update(self, metadata: dict[str, Any]) -> None:
22
+ metadata['optional-dependencies'] = {
23
+ # serial line of the gateways of pyModbusTCP.tools (python -m pyModbusTCP.tools tcp2rtu/rtu2tcp)
24
+ 'serial': ['pyserial>=3.5,<4'],
25
+ # commands mbtcp-* in the PATH: a separate package without code (console scripts can't depend on an extra,
26
+ # so a plain install of the library puts no command in the PATH), exactly this release
27
+ 'cli': [f"pyModbusTCP-cli=={metadata['version']}"],
28
+ }
@@ -2,9 +2,9 @@
2
2
  # Website: https://github.com/sourceperl/pyModbusTCP
3
3
  # License: MIT (https://opensource.org/license/mit)
4
4
  # Description: Client/Server ModBus/TCP
5
- # Support functions 3 and 16 (class 0)
6
- # 1,2,4,5,6 (Class 1)
7
- # 15,23,43
5
+ # Functions of the client and the server: 0x01 to 0x06, 0x0F, 0x10, 0x17 and 0x2B/0x0E (read
6
+ # device identification); any other with ModbusClient.custom_request() and a function handler of
7
+ # ModbusServer
8
8
 
9
9
  import logging
10
10
 
@@ -11,7 +11,6 @@ The client is split in modules, but everything is imported from here (``from pyM
11
11
  """
12
12
 
13
13
  from ._common import logger
14
- from ._functions import _decode_regs # noqa: F401 (kept for compatibility: private helper used by tests)
15
14
  from .device_id import DeviceIdentificationResponse
16
15
  from .modbus_client import ModbusClient
17
16
 
@@ -8,10 +8,13 @@ class InternalError(Exception):
8
8
  class NetworkError(InternalError):
9
9
  """ Network or frame error: code is a MB_xxx_ERR constant. """
10
10
 
11
- def __init__(self, code: int, message: str):
11
+ def __init__(self, code: int, message: str, *, retryable: bool = False):
12
12
  super().__init__(message)
13
13
  self.code = code
14
14
  self.message = message
15
+ # True if a new attempt is safe and may succeed: a connect error (but not an unknown host name), or a request
16
+ # that the server has surely not read (connection reset before any reply on a reused connection)
17
+ self.retryable = retryable
15
18
 
16
19
 
17
20
  class ModbusExcept(InternalError):