python-snap7 3.2.0__tar.gz → 3.3.0__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 (143) hide show
  1. python_snap7-3.3.0/CHANGES.md +424 -0
  2. python_snap7-3.3.0/MANIFEST.in +9 -0
  3. {python_snap7-3.2.0/python_snap7.egg-info → python_snap7-3.3.0}/PKG-INFO +27 -1
  4. {python_snap7-3.2.0 → python_snap7-3.3.0}/README.rst +25 -0
  5. python_snap7-3.3.0/doc/API/client-base.rst +9 -0
  6. python_snap7-3.3.0/doc/API/client.rst +45 -0
  7. python_snap7-3.3.0/doc/API/connection.rst +8 -0
  8. python_snap7-3.3.0/doc/API/datatypes.rst +7 -0
  9. python_snap7-3.3.0/doc/API/demo.rst +9 -0
  10. python_snap7-3.3.0/doc/API/discovery.rst +7 -0
  11. python_snap7-3.3.0/doc/API/error.rst +5 -0
  12. python_snap7-3.3.0/doc/API/log.rst +33 -0
  13. python_snap7-3.3.0/doc/API/logo.rst +5 -0
  14. python_snap7-3.3.0/doc/API/optimizer.rst +79 -0
  15. python_snap7-3.3.0/doc/API/partner.rst +24 -0
  16. python_snap7-3.3.0/doc/API/ppi.rst +10 -0
  17. python_snap7-3.3.0/doc/API/rate-limiter.rst +10 -0
  18. python_snap7-3.3.0/doc/API/s7protocol.rst +7 -0
  19. python_snap7-3.3.0/doc/API/server.rst +19 -0
  20. python_snap7-3.3.0/doc/API/szl.rst +8 -0
  21. python_snap7-3.3.0/doc/API/tags.rst +97 -0
  22. python_snap7-3.3.0/doc/API/type.rst +5 -0
  23. python_snap7-3.3.0/doc/API/util.rst +24 -0
  24. python_snap7-3.3.0/doc/Makefile +153 -0
  25. python_snap7-3.3.0/doc/advanced.rst +90 -0
  26. python_snap7-3.3.0/doc/cli.rst +191 -0
  27. python_snap7-3.3.0/doc/conf.py +92 -0
  28. python_snap7-3.3.0/doc/connecting.rst +183 -0
  29. python_snap7-3.3.0/doc/connection-issues.rst +190 -0
  30. python_snap7-3.3.0/doc/development.rst +86 -0
  31. python_snap7-3.3.0/doc/error-reference.rst +57 -0
  32. python_snap7-3.3.0/doc/index.rst +76 -0
  33. python_snap7-3.3.0/doc/installation.rst +60 -0
  34. python_snap7-3.3.0/doc/introduction.rst +65 -0
  35. python_snap7-3.3.0/doc/limitations.rst +29 -0
  36. python_snap7-3.3.0/doc/multi-variable.rst +51 -0
  37. python_snap7-3.3.0/doc/plc-support.rst +159 -0
  38. python_snap7-3.3.0/doc/ppi.rst +67 -0
  39. python_snap7-3.3.0/doc/reading-writing.rst +437 -0
  40. python_snap7-3.3.0/doc/real-plc-testing.rst +92 -0
  41. python_snap7-3.3.0/doc/server.rst +113 -0
  42. python_snap7-3.3.0/doc/thread-safety.rst +39 -0
  43. python_snap7-3.3.0/doc/tia-portal-config.rst +56 -0
  44. python_snap7-3.3.0/example/boolean.py +46 -0
  45. python_snap7-3.3.0/example/db1_layout.txt +46 -0
  46. python_snap7-3.3.0/example/db_layouts.py +123 -0
  47. python_snap7-3.3.0/example/example.py +201 -0
  48. python_snap7-3.3.0/example/logo_7_8.py +53 -0
  49. python_snap7-3.3.0/example/ppi.py +13 -0
  50. python_snap7-3.3.0/example/prometheus_metrics.py +166 -0
  51. python_snap7-3.3.0/example/read_multi.py +68 -0
  52. python_snap7-3.3.0/example/s7_symbols.py +38 -0
  53. python_snap7-3.3.0/example/write_multi.py +52 -0
  54. {python_snap7-3.2.0 → python_snap7-3.3.0}/pyproject.toml +8 -2
  55. {python_snap7-3.2.0 → python_snap7-3.3.0/python_snap7.egg-info}/PKG-INFO +27 -1
  56. {python_snap7-3.2.0 → python_snap7-3.3.0}/python_snap7.egg-info/SOURCES.txt +68 -1
  57. {python_snap7-3.2.0 → python_snap7-3.3.0}/python_snap7.egg-info/requires.txt +1 -0
  58. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/async_client.py +399 -67
  59. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/client.py +96 -92
  60. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/client_base.py +75 -2
  61. python_snap7-3.3.0/snap7/py.typed +0 -0
  62. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/s7protocol.py +251 -231
  63. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/server/__init__.py +216 -249
  64. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/szl.py +1 -1
  65. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/util/getters.py +19 -10
  66. python_snap7-3.3.0/tests/__init__.py +0 -0
  67. python_snap7-3.3.0/tests/conftest.py +189 -0
  68. python_snap7-3.3.0/tests/features/real_plc/connection.feature +17 -0
  69. python_snap7-3.3.0/tests/features/real_plc/lifecycle.feature +19 -0
  70. python_snap7-3.3.0/tests/features/real_plc/read.feature +19 -0
  71. python_snap7-3.3.0/tests/features/real_plc/report.schema.json +32 -0
  72. python_snap7-3.3.0/tests/features/real_plc/write.feature +23 -0
  73. python_snap7-3.3.0/tests/plc_setup/e2e_test_dbs.scl +160 -0
  74. python_snap7-3.3.0/tests/real_plc/__init__.py +1 -0
  75. python_snap7-3.3.0/tests/real_plc/reporting.py +123 -0
  76. python_snap7-3.3.0/tests/real_plc/support.py +228 -0
  77. python_snap7-3.3.0/tests/real_plc/test_acceptance.py +218 -0
  78. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_async_client.py +14 -0
  79. python_snap7-3.3.0/tests/test_async_typed_access.py +168 -0
  80. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_client.py +2 -2
  81. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_client_e2e.py +59 -62
  82. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_hypothesis.py +1 -2
  83. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_lean_regressions.py +19 -1
  84. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_multipacket.py +14 -3
  85. python_snap7-3.3.0/tests/test_operation_hook.py +201 -0
  86. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_property.py +2 -2
  87. python_snap7-3.3.0/tests/test_real_plc_support.py +117 -0
  88. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_s7protocol.py +279 -85
  89. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_server.py +233 -15
  90. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_util.py +31 -1
  91. python_snap7-3.3.0/tox.ini +36 -0
  92. python_snap7-3.2.0/MANIFEST.in +0 -1
  93. {python_snap7-3.2.0 → python_snap7-3.3.0}/LICENSE +0 -0
  94. /python_snap7-3.2.0/snap7/py.typed → /python_snap7-3.3.0/doc/_static/.phony +0 -0
  95. {python_snap7-3.2.0 → python_snap7-3.3.0}/python_snap7.egg-info/dependency_links.txt +0 -0
  96. {python_snap7-3.2.0 → python_snap7-3.3.0}/python_snap7.egg-info/entry_points.txt +0 -0
  97. {python_snap7-3.2.0 → python_snap7-3.3.0}/python_snap7.egg-info/top_level.txt +0 -0
  98. {python_snap7-3.2.0 → python_snap7-3.3.0}/s7/__init__.py +0 -0
  99. {python_snap7-3.2.0 → python_snap7-3.3.0}/setup.cfg +0 -0
  100. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/__init__.py +0 -0
  101. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/cli.py +0 -0
  102. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/connection.py +0 -0
  103. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/datatypes.py +0 -0
  104. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/demo.py +0 -0
  105. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/discovery.py +0 -0
  106. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/error.py +0 -0
  107. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/log.py +0 -0
  108. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/logo.py +0 -0
  109. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/optimizer.py +0 -0
  110. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/partner.py +0 -0
  111. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/ppi.py +0 -0
  112. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/rate_limiter.py +0 -0
  113. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/server/__main__.py +0 -0
  114. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/tags.py +0 -0
  115. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/type.py +0 -0
  116. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/util/__init__.py +0 -0
  117. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/util/db.py +0 -0
  118. {python_snap7-3.2.0 → python_snap7-3.3.0}/snap7/util/setters.py +0 -0
  119. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_api_surface.py +0 -0
  120. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_behavioral_compatibility.py +0 -0
  121. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_cli.py +0 -0
  122. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_conformance.py +0 -0
  123. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_connection.py +0 -0
  124. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_coverage_gaps.py +0 -0
  125. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_datatypes.py +0 -0
  126. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_demo.py +0 -0
  127. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_discovery.py +0 -0
  128. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_error.py +0 -0
  129. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_finalize.py +0 -0
  130. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_logging.py +0 -0
  131. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_logo_client.py +0 -0
  132. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_logo_reconnect_options.py +0 -0
  133. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_mainloop.py +0 -0
  134. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_optimizer.py +0 -0
  135. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_partner.py +0 -0
  136. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_ppi.py +0 -0
  137. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_rate_limiter.py +0 -0
  138. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_reconnect.py +0 -0
  139. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_routing.py +0 -0
  140. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_server_cli.py +0 -0
  141. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_stress.py +0 -0
  142. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_tags.py +0 -0
  143. {python_snap7-3.2.0 → python_snap7-3.3.0}/tests/test_typed_access.py +0 -0
@@ -0,0 +1,424 @@
1
+ CHANGES
2
+ ========
3
+
4
+ 3.3.0
5
+ -----
6
+
7
+ ### New features
8
+
9
+ * Add the typed DB accessors (`db_read_int`, `db_write_real`, `db_read_string`, ...,
10
+ `db_read_array`/`db_write_array`) and the tag helpers (`read_tag`, `write_tag`,
11
+ `read_tags`) to `AsyncClient`, matching the synchronous `Client`, as well as
12
+ `is_alive`, `connect_routed`, and `read_diagnostic_buffer`. (#922)
13
+
14
+ ### Bug fixes
15
+
16
+ * `get_string` and `get_wstring` now raise `ValueError` when the buffer is shorter than the declared current length,
17
+ instead of silently returning a truncated value (#945).
18
+ * USERDATA responses whose last-data-unit byte is neither `0x00` nor `0x01` are rejected with `S7ProtocolError`
19
+ instead of being treated as "more data" (#946).
20
+ * `get_wstring` compared the declared maximum in bytes with the 16382-character limit, so any WSTRING with a
21
+ capacity of 8192 characters or more was rejected, including ones written by `set_wstring` (#923).
22
+ * The get-block-info request now places the trailing `A` after the block number, as native Snap7 does
23
+ (`'0' type '00001' 'A'`), instead of before it. The bundled server parses the new layout (#929).
24
+ * `set_plc_datetime` encoded the weekday as Monday=1, but S7 DATE_AND_TIME counts Sunday=1 .. Saturday=7, so every
25
+ day was off by one position. The bundled server's clock reply uses the same convention now (#932).
26
+ * `set_plc_datetime` now raises `ValueError` for years outside 1990-2089 instead of silently sending a different
27
+ year, since the two-digit S7 year cannot represent them (#933).
28
+ * `parse_get_clock_response` now accepts the ten-byte S7 clock reply (reserved, century, then the time with milliseconds)
29
+ that native Snap7 and PLCs send, and still accepts the legacy eight-byte form. The bundled server emits the
30
+ ten-byte form (#934).
31
+ * `parse_response` now fails on any nonzero S7 header error word, as native Snap7 does, instead of only when the error
32
+ class is nonzero. Read and upload responses with error class 0 and a nonzero error code were previously treated as
33
+ successes while the write path rejected them (#930).
34
+ * `parse_list_blocks_response` now requires exactly the seven four-byte block-type entries (28 bytes) that native Snap7
35
+ expects, with distinct, known type codes. Empty or partial tables and duplicate entries are rejected instead of being
36
+ reported as zero block counts (#939).
37
+ * `set_plc_datetime` and the session-password calls now accept the null acknowledgement (return code 0x0A, no data) that
38
+ real PLCs send for services that return no data, instead of failing with "Object does not exist". The bundled
39
+ server acknowledges these services the same way (#940).
40
+ * Compress now uses the PI service `_GARB` and copy RAM to ROM uses file system `EP` with `_MODU`, matching real
41
+ engineering tools and native Snap7, instead of the invented `_MSZL`. The bundled server recognises the new
42
+ requests (#941).
43
+ * Read-SZL requests now carry the `0xFF`/octet-string data header and continuation requests the 12-byte parameter
44
+ block (method `0x12`) that real engineering tools send; both previously used the header of a request without data
45
+ and an 8-byte parameter block (#942).
46
+ * `get_order_code` no longer keeps the trailing space padding of the order code on S7-1200/1500 CPUs, for example
47
+ `6ES7 212-1BE40-0XB0 ` is now `6ES7 212-1BE40-0XB0` (#949).
48
+
49
+ ### Documentation
50
+
51
+ * Add a "Tested and Verified Hardware" section to the PLC support matrix, listing the CPUs, firmware versions and
52
+ python-snap7 versions the real-PLC acceptance suite has passed on (S7-1200 CPU 1212C V4.7.3, S7-1500 CPU 1511F-1 PN
53
+ V2.9.7). (#947)
54
+
55
+ 3.2.1
56
+ -----
57
+
58
+ Bug-fix and packaging release, with a few small additions.
59
+
60
+ ### Packaging
61
+
62
+ * Include the full test suite (`tests/__init__.py`, `tests/conftest.py`, PLC setup
63
+ files), examples, docs, and `CHANGES.md` in the source distribution (#912, #913).
64
+ * Remove leftover HarpoS7 test fixtures and transpiler from the S7CommPlus
65
+ split (#914).
66
+
67
+ ### New features
68
+
69
+ * Add an `on_operation` callback to the synchronous and asynchronous clients,
70
+ invoked after each PLC operation with its name, duration, and whether it
71
+ raised, plus an example Prometheus metrics exporter (#843, #901).
72
+ * Add a safe, Gherkin-based real-PLC acceptance program with restored scratch
73
+ writes and sanitized JSON/JUnit reports (#840, #892, #908).
74
+
75
+ ### Bug fixes
76
+
77
+ * Match the classic Snap7 upload wire layout, collect every upload fragment, and
78
+ reject malformed, truncated, or mismatched S7/USERDATA responses (#903).
79
+ * Use the PLC-driven request/response sequence for block download and match
80
+ classic S7 wire vectors for list-blocks-of-type, set clock, get block info,
81
+ and password requests (#904).
82
+ * Fix the return type annotations of `snap7.util.get_byte` and `get_word`, which
83
+ return `int`, not `bytes`/`bytearray` (#910).
84
+
85
+ 3.2.0
86
+ -----
87
+
88
+ Feature and robustness release for the classic S7 protocol implementation.
89
+
90
+ ### Packaging
91
+
92
+ * Move S7CommPlus support to the standalone
93
+ [`s7commplus`](https://github.com/gijzelaerr/s7commplus) package. The `s7`
94
+ import remains available as an alias for the classic `snap7` package.
95
+
96
+ ### New features
97
+
98
+ * Add configurable request rate limiting to synchronous and asynchronous
99
+ clients, including fixed-interval and token-bucket modes (#823).
100
+ * Add synchronous and asynchronous APIs for forcing I/O bits, cancelling
101
+ forces, and reading the PLC force table (#796, #800).
102
+ * Add synchronous and asynchronous session password set/clear APIs for
103
+ password-protected PLCs (#792, #799).
104
+ * Support LOGO reconnection, heartbeat, rate-limiting, and connection callback
105
+ options while preserving explicit TSAPs (#875).
106
+ * Add an experimental serial PPI client for S7-200 PLCs, including V-memory,
107
+ system-memory, I/O, counter, and timer access (#824).
108
+
109
+ ### Bug fixes
110
+
111
+ * Parse structured and flat SZL 0x0011 records correctly when reading order
112
+ codes and firmware versions from S7-1500 and classic PLCs (#783, #789).
113
+ * Dispatch server callbacks and queue protocol events for client requests
114
+ instead of reporting only the server start event (#853, #856).
115
+ * Validate classic S7 TPKT bounds and COTP Class 0 headers in synchronous and
116
+ asynchronous clients (#874).
117
+ * Reject incomplete reads and mismatched or missing read/write
118
+ acknowledgements (#874).
119
+ * Size read/write chunks in whole elements and preserve ctypes write
120
+ datatypes; correct BIT lengths and timer/counter index addressing (#874).
121
+ * Validate `write_multi_vars()` inputs consistently and preserve each item's
122
+ declared datatype (#855, #874).
123
+ * Echo the calling and called TSAP values in server connection confirmations,
124
+ and restart the receive deadline after each complete TPKT header (#893).
125
+ * Return S7 item errors for reads from unregistered server areas or addresses
126
+ outside registered memory instead of returning fabricated data (#896).
127
+
128
+ 3.1.2
129
+ -----
130
+
131
+ Corrective bug fix and robustness release replacing the yanked 3.1.1 release.
132
+
133
+ ### Corrections
134
+
135
+ * Withdraw the vulnerability and CWE characterizations published with 3.1.1.
136
+ Independent review found that those descriptions overstated or incorrectly
137
+ described the affected code paths.
138
+
139
+ ### Robustness fixes
140
+
141
+ * Bound the server to 64 simultaneous clients by default, enforce the existing
142
+ `MaxClients` parameter, and allow `max_clients` configuration.
143
+ * Validate block-download targets and declared sizes before allocating transfer
144
+ state, cap accumulated data at the declared size and registered area's
145
+ capacity, and clean up abandoned upload/download state on disconnect.
146
+ * Correct block-download address parsing so the requested DB number is used
147
+ instead of silently falling back to DB1.
148
+ * Bound COTP request reassembly to 1 MiB and apply one absolute deadline across
149
+ all fragments of a request.
150
+ * Apply COTP TPDU-size validation consistently to sync and async clients.
151
+ * Add regression tests for invalid PDU negotiation, TPDU-size validation,
152
+ connection limits, request reassembly, and block-download limits.
153
+
154
+ 3.1.1 (yanked)
155
+ ----------------
156
+
157
+ This release was yanked because its security descriptions were inaccurate and
158
+ some of its input-hardening changes were incomplete. Use 3.1.2 instead.
159
+
160
+ ### Robustness changes
161
+
162
+ * Validate COTP TPDU-size encodings in the synchronous client.
163
+ * Normalize implausibly small negotiated PDU lengths and ensure read/write
164
+ chunk sizes remain positive.
165
+ * Stop finalizing downloads into unregistered server memory areas. This did not
166
+ bound the download accumulator and was completed in 3.1.2.
167
+
168
+ ### Bug fixes
169
+
170
+ * Fix `connection_type` not applied in TSAP composition during
171
+ `connect()` (#766)
172
+ * Fix auto-reconnect not triggered on multi-block read path (#787)
173
+ * Support multi-byte string encodings (GBK, UTF-8) in `get_string`,
174
+ `set_string`, `get_fstring`, `set_fstring` (#788)
175
+ * Thread encoding parameter through `read_tag` / `write_tag` /
176
+ `read_tags` (#786)
177
+ * Server: reassemble COTP-fragmented requests; include TPDU size
178
+ parameter in Connection Confirm so clients don't fall back to the
179
+ 128-byte ISO 8073 default (#804)
180
+ * Server: fix `INT` and `DINT` word lengths returning wrong byte count
181
+ in read requests (#804)
182
+
183
+ ### Thanks
184
+
185
+ * [@b1163646804](https://github.com/b1163646804) — multi-byte encoding
186
+ support and testing (#788)
187
+ * [@domelg](https://github.com/domelg) — server COTP fragmentation and
188
+ INT/DINT byte count bug reports (#804)
189
+
190
+ 3.1.0
191
+ -----
192
+
193
+ Feature and bug fix release for the pure Python S7 communication library.
194
+
195
+ ### New features
196
+
197
+ * **AsyncClient** for `asyncio` support (#593)
198
+ * **Unified Tag API**: `client.read_tag("DB1.DBD0:REAL")` with PLC4X /
199
+ Siemens STEP7 syntax (#697)
200
+ * **Dual-dialect tag parsing**: PLC4X and nodeS7 tag formats with
201
+ auto-detection (#701)
202
+ * **Multi-variable read optimizer** with parallel dispatch (experimental, #641)
203
+ * **S7 routing** for multi-subnet PLC access (experimental, #639)
204
+ * **Heartbeat monitoring** and auto-reconnect with exponential backoff (#635)
205
+ * **Structured logging** with PLC connection context (`snap7.log`, #688)
206
+ * **PROFINET DCP** network discovery (#634)
207
+ * **CLI tools** for PLC interaction (`pip install "python-snap7[cli]"`, #631)
208
+ * **Demo server** exposing real host metrics (#704)
209
+ * Typed DB access methods (`db_read_bool`, `db_read_int`, etc., #632)
210
+ * Symbolic addressing — read/write by tag name (experimental, #638)
211
+ * Diagnostic buffer reading (#690)
212
+ * Array read/write helpers (`db_read_array`, `db_write_array`, #693)
213
+ * Missing data type setters: `set_lint`, `set_ulint`, `set_ltime`, `set_ltod`, `set_ldt` (#693)
214
+ * Property-based testing with Hypothesis (#636)
215
+
216
+ ### Bug fixes
217
+
218
+ * Fix `AttributeError` from `__del__` during interpreter shutdown (#707)
219
+ * Fix server SZL 0x001C response to match real PLC format (#694)
220
+ * Fix `connection_type` in TSAP composition during connect (#766)
221
+ * Accept `memoryview` in setter and getter type annotations (#647)
222
+ * Zero-pad milliseconds in `get_time` (#716)
223
+ * Fix PI service PDU format for PLC control commands (#743)
224
+ * Fix `get_cpu_info` and `S7SZL.__str__` (#692)
225
+ * Fix partner S7 Communication Setup and bsend/brecv PDU format (#669)
226
+ * Fix `get_dtl` microsecond parsing (4-byte nanosecond field)
227
+ * Fix `set_date` unsigned short for day count
228
+ * Fix `set_tod` float precision loss
229
+ * Validate BMP range in `set_wstring`
230
+ * Fix async `get_cpu_info` SZL offsets (#702)
231
+ * Fix demo primary-IP guess with VPN/tunnel interfaces (#708)
232
+ * Fix mypy errors in server SZL list (#695)
233
+ * Robustness: 210+ S7 error codes, auto PDU splitting, stale packet retry (#580)
234
+
235
+ ### Improvements
236
+
237
+ * Set `TCP_NODELAY` and `SO_KEEPALIVE` on all sockets (#677)
238
+ * Export `get_ulint`, `get_lint`, `get_date_time_object` from `snap7.util` (#652)
239
+ * Documentation restructured: API Reference + Internals sections
240
+
241
+ ### Thanks
242
+
243
+ * [@hs2bws-hash](https://github.com/hs2bws-hash) — extensive real PLC testing of Partner BSend/BRecv (#668)
244
+ * [@QuakeString](https://github.com/QuakeString) — read optimizer inspiration via python-snap7-optimized fork
245
+
246
+ 3.0.0
247
+ -----
248
+
249
+ Major release: python-snap7 is now a pure Python S7 communication library.
250
+ This version completely breaks with the previous approach of wrapping the C snap7
251
+ shared library. The entire S7 protocol stack is now implemented in pure Python,
252
+ greatly improving portability and making it easier to install and extend.
253
+
254
+ * **Breaking**: The C snap7 library is no longer required or used
255
+ * Complete rewrite of the S7 protocol stack in pure Python
256
+ * Native Python implementation of TPKT (RFC 1006) and COTP (ISO 8073) layers
257
+ * Native S7 protocol PDU encoding/decoding
258
+ * Pure Python server implementation for testing and simulation
259
+ * No platform-specific binary dependencies — works on any platform that runs Python
260
+ * Improved error handling and connection management
261
+ * Full type annotations with mypy strict mode
262
+ * CLI interface for running an S7 server emulator (`pip install "python-snap7[cli]"`)
263
+
264
+ If you experience issues with 3.0, please report them on the
265
+ [issue tracker](https://github.com/gijzelaerr/python-snap7/issues) with a clear
266
+ description and the version you are using. As a workaround, pin to the last
267
+ pre-3.0 release:
268
+
269
+ $ pip install "python-snap7<3"
270
+
271
+ ### Thanks
272
+
273
+ Special thanks to the following people for testing, reporting issues, and providing
274
+ feedback during the 3.0 development:
275
+
276
+ * [@lupaulus](https://github.com/lupaulus) — extensive testing and bug reports
277
+ * [@spreeker](https://github.com/spreeker) — testing and feedback
278
+ * [@nikteliy](https://github.com/nikteliy) — review and feedback on the rewrite
279
+ * [@amorelettronico](https://github.com/amorelettronico) — testing
280
+ * [@razour08](https://github.com/razour08) — testing
281
+ * [@core-engineering](https://github.com/core-engineering) — bug reports (#553)
282
+ * [@AndreasScharf](https://github.com/AndreasScharf) — bug reports (#572)
283
+ * [@Robatronic](https://github.com/Robatronic) — bug reports (#574)
284
+ * [@hirotasoshu](https://github.com/hirotasoshu) — feedback (#545)
285
+ * [@PoitrasJ](https://github.com/PoitrasJ) — bug reports (#479)
286
+
287
+ 1.2
288
+ ---
289
+
290
+ * fix wheel tag for linux x86_64 by @nikteliy in https://github.com/gijzelaerr/python-snap7/pull/297
291
+ * Fixed typo area doesn't exist areas does by @Ofloo in https://github.com/gijzelaerr/python-snap7/pull/306
292
+ * add get_time and set_time in util by @Yingliangzhe in https://github.com/gijzelaerr/python-snap7/pull/308
293
+ * modification of TIME data type by @Yingliangzhe in https://github.com/gijzelaerr/python-snap7/pull/311
294
+ * added DATE_AND_TIME Value as Datetime object by @zsisamci in https://github.com/gijzelaerr/python-snap7/pull/312
295
+ * #273 by @nikteliy in https://github.com/gijzelaerr/python-snap7/pull/321
296
+ * Add byte type parsing to DB_Row API + set parsing case insensitive by @LoicGRENON in https://github.com/gijzelaerr/python-snap7/pull/315
297
+ * added missing types in WordLen by @zsisamci in https://github.com/gijzelaerr/python-snap7/pull/326
298
+ * Add support for read/write unsigned value from bytearray by @LoicGRENON in https://github.com/gijzelaerr/python-snap7/pull/316
299
+ * fixing ip string paramters to c function by @zsisamci in https://github.com/gijzelaerr/python-snap7/pull/329
300
+ * Add py.typed marker file by @mthuurne in https://github.com/gijzelaerr/python-snap7/pull/342
301
+ * require correct package name, fixes issue #344 by @gijzelaerr in https://github.com/gijzelaerr/python-snap7/pull/345
302
+ * Fix warnings by @nikteliy in https://github.com/gijzelaerr/python-snap7/pull/350
303
+ * Update license identifier by @Shortfinga in https://github.com/gijzelaerr/python-snap7/pull/349
304
+ * Update client db_write docs by @pwablito in https://github.com/gijzelaerr/python-snap7/pull/352
305
+ * Fix db_offset calculation error by @lubbbert in https://github.com/gijzelaerr/python-snap7/pull/351
306
+ * fix #355 by @swamper123 in https://github.com/gijzelaerr/python-snap7/pull/359
307
+ * fix #272 by @swamper123 in https://github.com/gijzelaerr/python-snap7/pull/360
308
+ * fix get_time for small values by @swamper123 in https://github.com/gijzelaerr/python-snap7/pull/358
309
+ * add more getter methods for utils by @swamper123 in https://github.com/gijzelaerr/python-snap7/pull/357
310
+ * Prepare for 1.2 by @gijzelaerr in https://github.com/gijzelaerr/python-snap7/pull/364
311
+
312
+ ### New Contributors
313
+
314
+ * @Ofloo made their first contribution in https://github.com/gijzelaerr/python-snap7/pull/306
315
+ * @zsisamci made their first contribution in https://github.com/gijzelaerr/python-snap7/pull/312
316
+ * @LoicGRENON made their first contribution in https://github.com/gijzelaerr/python-snap7/pull/315
317
+ * @mthuurne made their first contribution in https://github.com/gijzelaerr/python-snap7/pull/342
318
+ * @Shortfinga made their first contribution in https://github.com/gijzelaerr/python-snap7/pull/349
319
+ * @pwablito made their first contribution in https://github.com/gijzelaerr/python-snap7/pull/352
320
+ * @lubbbert made their first contribution in https://github.com/gijzelaerr/python-snap7/pull/351
321
+
322
+ **Full Changelog**: https://github.com/gijzelaerr/python-snap7/compare/1.1...1.2
323
+
324
+ 1.1
325
+ ---
326
+
327
+ * Make a binary wheel for all platforms (#232)
328
+ * Improve doc strings of all functions (#242)
329
+
330
+ Special thanks for this release to
331
+ * Fabian Beitler
332
+ * Nikteliy
333
+ * Lautaro Nahuel Dapino
334
+
335
+ 1.0
336
+ ---
337
+
338
+ * Drop python 2 support (#214)
339
+ * Feature request: ReadSZL() (#196)
340
+ * Keep argument format across the functions (#193)
341
+ * Drop Python2 Tests (#167)
342
+ * Support for S5TIME (#163)
343
+ * Add type annotations (#157)
344
+ * client.full_upload() return bytearray size 65536 (#127)
345
+ * Some client tests segfault on Linux (#26)
346
+ * Not all functions are implemented yet (#25)
347
+
348
+ special thanks to [Fabian Beitler](https://github.com/swamper123) and
349
+ [Nikteliy](https://github.com/nikteliy>) for their contributions to the 1.0 release!
350
+
351
+
352
+
353
+
354
+ 0.11
355
+ ----
356
+
357
+ * Update read_multi.py (#132)
358
+ * Added fixes to snap7/client.py read_area function to allow for Counter and Timer Reads (#121)
359
+ * Post to a public docker repository? (#119)
360
+ * Implementation of Cli_SetDateTime, Cli_GetDateTime enhancement (#114)
361
+
362
+
363
+ 0.10
364
+ ----
365
+
366
+ * Fix OSX travis build #99
367
+ * util.get_int() broken #101
368
+ * Compatibility issue with Python3 #109
369
+ * Logo 8 improvements bug #105
370
+
371
+
372
+ 0.7
373
+ ---
374
+
375
+ * util.get_int() broken (#65, #71)
376
+ * fix Add files via upload bug (#59)
377
+
378
+ Special thanks to Pelle van der Heide for solving issues
379
+
380
+
381
+ 0.6
382
+ ---
383
+
384
+ * Add __del__ to client, server and partner (#69)
385
+ * Add files via upload (#59)
386
+
387
+ Special thanks to xybsoft for solving issues
388
+
389
+ 0.5
390
+ ---
391
+
392
+ * adding some missing functions
393
+ * fixing Python3 support (issue #43)
394
+ * improving the documentation
395
+
396
+ 0.4
397
+ ---
398
+
399
+ More functions added:
400
+
401
+ * client.plc_stop
402
+ * client.plc_cold_start
403
+ * client.plc_hot_start
404
+ * client.read_multi_vars
405
+
406
+ 0.2.1
407
+ -----
408
+
409
+ Small fix, README.rst was not included in sdist
410
+
411
+
412
+ 0.2
413
+ ---
414
+
415
+ - Add support for Windows
416
+ - Add functions added in Snap7 1.1.0
417
+ - Add missing client functions
418
+ - fix some partner functions
419
+ - simplified API
420
+
421
+ 0.1
422
+ ---
423
+
424
+ - Initial release.
@@ -0,0 +1,9 @@
1
+ include README.rst
2
+ include CHANGES.md
3
+ include LICENSE
4
+ include tox.ini
5
+ graft tests
6
+ prune tests/fixtures
7
+ graft example
8
+ graft doc
9
+ global-exclude *.py[cod] __pycache__
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-snap7
3
- Version: 3.2.0
3
+ Version: 3.3.0
4
4
  Summary: Pure Python S7 communication library for Siemens PLCs
5
5
  Author-email: Gijs Molenaar <gijsmolenaar@gmail.com>
6
6
  License-Expression: MIT
@@ -24,6 +24,7 @@ License-File: LICENSE
24
24
  Provides-Extra: test
25
25
  Requires-Dist: pytest; extra == "test"
26
26
  Requires-Dist: pytest-asyncio; extra == "test"
27
+ Requires-Dist: pytest-bdd<10,>=8.1; extra == "test"
27
28
  Requires-Dist: pytest-cov; extra == "test"
28
29
  Requires-Dist: pytest-html; extra == "test"
29
30
  Requires-Dist: hypothesis; extra == "test"
@@ -74,6 +75,26 @@ using the classic S7 protocol. It supports S7-300 and S7-400 controllers, as
74
75
  well as S7-1200 and S7-1500 controllers with PUT/GET access enabled. It
75
76
  supports Python 3.10+ on Windows, Linux, and macOS without native dependencies.
76
77
 
78
+ S7-1200 and S7-1500
79
+ ===================
80
+
81
+ On S7-1200 and S7-1500 controllers, python-snap7 only works when PUT/GET access
82
+ is enabled in TIA Portal, and it cannot access optimized data blocks. PUT/GET
83
+ is unauthenticated and disabled by default, so leaving it disabled is the more
84
+ secure configuration.
85
+
86
+ If PUT/GET is disabled, or you need optimized data blocks or symbolic access,
87
+ use `s7commplus <https://github.com/gijzelaerr/s7commplus>`_ instead::
88
+
89
+ pip install s7commplus
90
+
91
+ s7commplus is a separate, younger project that implements S7CommPlus, the
92
+ protocol these controllers speak natively. Check the
93
+ `firmware versions validated so far <https://s7commplus.readthedocs.io/en/latest/connections.html>`_
94
+ before relying on it, and see the
95
+ `PLC support matrix <https://python-snap7.readthedocs.io/en/latest/plc-support.html>`_
96
+ for what python-snap7 supports on each controller family.
97
+
77
98
  Installation
78
99
  ============
79
100
 
@@ -101,3 +122,8 @@ Documentation
101
122
 
102
123
  Read the full documentation at
103
124
  `python-snap7.readthedocs.io <https://python-snap7.readthedocs.io/en/latest/>`_.
125
+
126
+ The safe volunteer hardware-test procedure is in
127
+ `Real-PLC acceptance testing <doc/real-plc-testing.rst>`_.
128
+ The CPUs and firmware versions it has passed on are listed under
129
+ `Tested and Verified Hardware <doc/plc-support.rst>`_.
@@ -22,6 +22,26 @@ using the classic S7 protocol. It supports S7-300 and S7-400 controllers, as
22
22
  well as S7-1200 and S7-1500 controllers with PUT/GET access enabled. It
23
23
  supports Python 3.10+ on Windows, Linux, and macOS without native dependencies.
24
24
 
25
+ S7-1200 and S7-1500
26
+ ===================
27
+
28
+ On S7-1200 and S7-1500 controllers, python-snap7 only works when PUT/GET access
29
+ is enabled in TIA Portal, and it cannot access optimized data blocks. PUT/GET
30
+ is unauthenticated and disabled by default, so leaving it disabled is the more
31
+ secure configuration.
32
+
33
+ If PUT/GET is disabled, or you need optimized data blocks or symbolic access,
34
+ use `s7commplus <https://github.com/gijzelaerr/s7commplus>`_ instead::
35
+
36
+ pip install s7commplus
37
+
38
+ s7commplus is a separate, younger project that implements S7CommPlus, the
39
+ protocol these controllers speak natively. Check the
40
+ `firmware versions validated so far <https://s7commplus.readthedocs.io/en/latest/connections.html>`_
41
+ before relying on it, and see the
42
+ `PLC support matrix <https://python-snap7.readthedocs.io/en/latest/plc-support.html>`_
43
+ for what python-snap7 supports on each controller family.
44
+
25
45
  Installation
26
46
  ============
27
47
 
@@ -49,3 +69,8 @@ Documentation
49
69
 
50
70
  Read the full documentation at
51
71
  `python-snap7.readthedocs.io <https://python-snap7.readthedocs.io/en/latest/>`_.
72
+
73
+ The safe volunteer hardware-test procedure is in
74
+ `Real-PLC acceptance testing <doc/real-plc-testing.rst>`_.
75
+ The CPUs and firmware versions it has passed on are listed under
76
+ `Tested and Verified Hardware <doc/plc-support.rst>`_.
@@ -0,0 +1,9 @@
1
+ Shared Client Internals
2
+ =======================
3
+
4
+ Pure-computation and compatibility methods shared by ``Client`` and
5
+ ``AsyncClient``. Applications normally access these methods through one of the
6
+ concrete clients.
7
+
8
+ .. automodule:: snap7.client_base
9
+ :members:
@@ -0,0 +1,45 @@
1
+ Client
2
+ ======
3
+
4
+ The ``s7`` package implements the classic S7 protocol for S7-300/400 PLCs and
5
+ PUT/GET access on S7-1200/1500.
6
+
7
+ Use ``Client`` for synchronous applications::
8
+
9
+ from s7 import Client
10
+
11
+ with Client() as client:
12
+ client.connect("192.168.1.10", 0, 1)
13
+ data = client.db_read(1, 0, 4)
14
+
15
+ Use ``AsyncClient`` when the surrounding application uses ``asyncio``::
16
+
17
+ import asyncio
18
+ from s7 import AsyncClient
19
+
20
+ async def main():
21
+ async with AsyncClient() as client:
22
+ await client.connect("192.168.1.10", 0, 1)
23
+ data = await client.db_read(1, 0, 4)
24
+
25
+ asyncio.run(main())
26
+
27
+ Both clients expose the same main PLC operations, including area and DB
28
+ access, block transfer, CPU information and control, clock access, force
29
+ operations, and session passwords. Methods that perform I/O are coroutines on
30
+ ``AsyncClient``. See :doc:`../advanced` for the less common operations.
31
+
32
+ s7.Client
33
+ ---------
34
+
35
+ .. automodule:: snap7.client
36
+ :members:
37
+ :inherited-members:
38
+
39
+ s7.AsyncClient
40
+ --------------
41
+
42
+ .. automodule:: snap7.async_client
43
+ :members:
44
+ :inherited-members:
45
+ :exclude-members: AsyncISOTCPConnection
@@ -0,0 +1,8 @@
1
+ Connection
2
+ ==========
3
+
4
+ The connection module implements the ISO on TCP transport layer (TPKT/COTP)
5
+ used for S7 communication.
6
+
7
+ .. automodule:: snap7.connection
8
+ :members:
@@ -0,0 +1,7 @@
1
+ Data Types
2
+ ==========
3
+
4
+ The datatypes module provides S7 data type definitions and address encoding.
5
+
6
+ .. automodule:: snap7.datatypes
7
+ :members:
@@ -0,0 +1,9 @@
1
+ Demo Server
2
+ ===========
3
+
4
+ Implementation of the optional live host-metrics demo used by ``s7 demo``.
5
+ Install ``python-snap7[demo]`` before running it. This module is intended for
6
+ examples and integration testing, not production monitoring.
7
+
8
+ .. automodule:: snap7.demo
9
+ :members:
@@ -0,0 +1,7 @@
1
+ Discovery
2
+ =========
3
+
4
+ .. automodule:: snap7.discovery
5
+ :members:
6
+ :undoc-members:
7
+ :show-inheritance:
@@ -0,0 +1,5 @@
1
+ Errors
2
+ ======
3
+
4
+ .. automodule:: snap7.error
5
+ :members:
@@ -0,0 +1,33 @@
1
+ Logging
2
+ =======
3
+
4
+ Structured logging with PLC connection context for multi-PLC environments.
5
+
6
+ The :class:`~snap7.log.PLCLoggerAdapter` automatically injects PLC host,
7
+ rack, and slot into every log message:
8
+
9
+ .. code-block:: python
10
+
11
+ import logging
12
+ logging.basicConfig(level=logging.DEBUG)
13
+
14
+ from s7 import Client
15
+ client = Client()
16
+ client.connect("192.168.1.10", 0, 1)
17
+ # Logs: [192.168.1.10 R0/S1] Connected to 192.168.1.10:102 ...
18
+
19
+ For JSON output (ELK, Datadog, Loki):
20
+
21
+ .. code-block:: python
22
+
23
+ from s7.log import JSONFormatter
24
+
25
+ handler = logging.StreamHandler()
26
+ handler.setFormatter(JSONFormatter())
27
+ logging.getLogger("snap7").addHandler(handler)
28
+
29
+ API reference
30
+ -------------
31
+
32
+ .. automodule:: snap7.log
33
+ :members:
@@ -0,0 +1,5 @@
1
+ Logo
2
+ ====
3
+
4
+ .. autoclass:: snap7.logo.Logo
5
+ :members: