pydnp3-stepfunc 1.6.0.3__cp310-cp310-manylinux1_x86_64.whl

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.
Binary file
@@ -0,0 +1,238 @@
1
+ Metadata-Version: 2.4
2
+ Name: pydnp3-stepfunc
3
+ Version: 1.6.0.3
4
+ Summary: Python bindings for the stepfunc/dnp3 Rust library via cffi
5
+ Author: f0rw4rd
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/f0rw4rd/dnp3-python
8
+ Project-URL: Repository, https://github.com/f0rw4rd/dnp3-python
9
+ Project-URL: Issues, https://github.com/f0rw4rd/dnp3-python/issues
10
+ Keywords: dnp3,scada,ics,industrial-control-systems,modbus,protocol,master,outstation,rtu,power-systems
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
+ Classifier: Topic :: System :: Networking
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: Implementation :: CPython
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ License-File: LICENSE
28
+ Requires-Dist: cffi>=1.15.0
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest>=7.0; extra == "dev"
31
+ Requires-Dist: pytest-timeout>=2.0; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # dnp3-python
35
+
36
+ Python bindings for the [stepfunc/dnp3](https://github.com/stepfunc/dnp3) Rust library via cffi.
37
+
38
+ [![Tests](https://github.com/f0rw4rd/dnp3-python/actions/workflows/tests.yml/badge.svg)](https://github.com/f0rw4rd/dnp3-python/actions/workflows/tests.yml)
39
+
40
+ This library provides a Pythonic API for DNP3 (Distributed Network Protocol 3) master
41
+ and outstation operations, built on the production-quality stepfunc/dnp3 implementation.
42
+ It supports TCP, TLS, serial, and UDP transports with full Secure Authentication support.
43
+
44
+ ## Features
45
+
46
+ - **Master station** - Integrity polls, class-based reads, specific group/variation reads
47
+ - **Control operations** - Select-Before-Operate (SBO), Direct Operate, analog outputs
48
+ - **Device attributes** - Read Group 0 device attribute strings
49
+ - **Outstation server** - Create test outstations with configurable databases
50
+ - **Time synchronization** - LAN and non-LAN time sync modes
51
+ - **Restart commands** - Cold and warm restart with delay reporting
52
+ - **Multiple transports** - TCP, TLS, serial, UDP channel creation
53
+ - **Logging** - Configurable log levels, text/JSON output, custom callbacks
54
+ - **Thread-safe** - All handlers use locking for concurrent access
55
+
56
+ ## Installation
57
+
58
+ ### Prerequisites
59
+
60
+ You need the compiled stepfunc/dnp3 C FFI library (`libdnp3_ffi.so` and `dnp3.h`).
61
+
62
+ ```bash
63
+ # Clone and build the Rust library
64
+ git clone https://github.com/stepfunc/dnp3.git stepfunc-dnp3
65
+ cd stepfunc-dnp3
66
+ cargo build --release -p dnp3-ffi
67
+
68
+ # Generate C bindings
69
+ cargo build --release -p dnp3-bindings
70
+ ```
71
+
72
+ ### Install dnp3-python
73
+
74
+ ```bash
75
+ # Install from local checkout
76
+ pip install -e .
77
+
78
+ # Or with dev dependencies
79
+ pip install -e ".[dev]"
80
+ ```
81
+
82
+ The library locates `dnp3.h` and `libdnp3_ffi.so` automatically from a sibling
83
+ `stepfunc-dnp3/` directory. You can also set environment variables:
84
+
85
+ ```bash
86
+ export DNP3_HEADER_PATH=/path/to/dnp3.h
87
+ export DNP3_LIB_PATH=/path/to/libdnp3_ffi.so
88
+ ```
89
+
90
+ ## Quick Start
91
+
92
+ ### Master - Read Data from Outstation
93
+
94
+ ```python
95
+ from dnp3 import Runtime, MasterChannelConfig, ReadHandler
96
+ from dnp3.channel import create_tcp_channel
97
+ from dnp3.logging import configure_logging, LogLevel
98
+
99
+ configure_logging(LogLevel.INFO)
100
+
101
+ with Runtime() as runtime:
102
+ handler = ReadHandler()
103
+ channel = create_tcp_channel(
104
+ runtime,
105
+ endpoints=["127.0.0.1:20000"],
106
+ config=MasterChannelConfig(address=1),
107
+ )
108
+ assoc = channel.add_association(address=1024, read_handler=handler)
109
+ channel.enable()
110
+
111
+ # Integrity poll (all classes)
112
+ channel.read(assoc)
113
+
114
+ for bi in handler.binary_inputs:
115
+ print(f"BI {bi.index}: {bi.value} (flags={bi.flags.value:#04x})")
116
+ for ai in handler.analog_inputs:
117
+ print(f"AI {ai.index}: {ai.value}")
118
+
119
+ channel.destroy()
120
+ ```
121
+
122
+ ### Master - Control Operations
123
+
124
+ ```python
125
+ from dnp3 import OpType, CommandMode
126
+
127
+ # Select-Before-Operate
128
+ channel.select_before_operate(assoc, index=3, op_type=OpType.LATCH_ON)
129
+
130
+ # Direct Operate
131
+ channel.direct_operate(assoc, index=5, op_type=OpType.LATCH_OFF)
132
+
133
+ # Analog output
134
+ channel.operate(
135
+ assoc,
136
+ mode=CommandMode.DIRECT_OPERATE,
137
+ analog_double_commands=[(0, 42.5)],
138
+ )
139
+ ```
140
+
141
+ ### Outstation Server
142
+
143
+ ```python
144
+ from dnp3 import Runtime
145
+ from dnp3.outstation import OutstationServer, OutstationConfig
146
+
147
+ with Runtime() as runtime:
148
+ server = OutstationServer(runtime, address="0.0.0.0:20000")
149
+ config = OutstationConfig(outstation_address=10, master_address=1)
150
+ outstation = server.add_outstation(config=config)
151
+ server.bind()
152
+
153
+ # Server is now accepting master connections...
154
+ input("Press Enter to stop")
155
+ server.destroy()
156
+ ```
157
+
158
+ ### Examples
159
+
160
+ See the [examples/](examples/) directory for complete working scripts:
161
+
162
+ - [**master_poll.py**](examples/master_poll.py) - Connect and read data points
163
+ - [**master_control.py**](examples/master_control.py) - SBO and direct operate
164
+ - [**master_attributes.py**](examples/master_attributes.py) - Read device attributes (Group 0)
165
+ - [**outstation_server.py**](examples/outstation_server.py) - Test outstation with sample data
166
+
167
+ ## API Summary
168
+
169
+ ### Core Classes
170
+
171
+ | Class | Description |
172
+ |-------|-------------|
173
+ | `Runtime` | Manages the Tokio async runtime (context manager) |
174
+ | `MasterChannel` | Master station channel with read/control methods |
175
+ | `MasterChannelConfig` | Channel configuration (address, decode level, buffer sizes) |
176
+ | `AssociationConfig` | Association settings (unsolicited, integrity, timeouts) |
177
+ | `ReadHandler` | Collects data from read operations |
178
+ | `OutstationServer` | TCP outstation server for testing |
179
+
180
+ ### Channel Factories
181
+
182
+ | Function | Description |
183
+ |----------|-------------|
184
+ | `create_tcp_channel()` | TCP master channel |
185
+ | `create_tls_channel()` | TLS-encrypted master channel |
186
+ | `create_serial_channel()` | Serial port master channel |
187
+ | `create_udp_channel()` | UDP master channel |
188
+
189
+ ### Data Types
190
+
191
+ | Type | Description |
192
+ |------|-------------|
193
+ | `BinaryInput` | Binary input point (index, value, flags, timestamp) |
194
+ | `AnalogInput` | Analog input point |
195
+ | `Counter` | Counter point |
196
+ | `BinaryOutputStatus` | Binary output status |
197
+ | `AnalogOutputStatus` | Analog output status |
198
+ | `Group12Var1` | Control Relay Output Block (CROB) |
199
+ | `Variation` | DNP3 group/variation enum |
200
+
201
+ ### MasterChannel Methods
202
+
203
+ | Method | Description |
204
+ |--------|-------------|
205
+ | `read()` | One-shot read (by class or variation) |
206
+ | `read_attributes()` | Read device attributes (Group 0) |
207
+ | `add_poll()` | Add periodic poll |
208
+ | `select_before_operate()` | SBO binary output control |
209
+ | `direct_operate()` | Direct operate binary output |
210
+ | `operate()` | Generic control (CROB + analog) |
211
+ | `synchronize_time()` | Time sync (LAN/non-LAN) |
212
+ | `cold_restart()` / `warm_restart()` | Restart commands |
213
+ | `check_link_status()` | Link status check |
214
+
215
+ ## Building from Source
216
+
217
+ ```bash
218
+ # 1. Build the Rust library (in a sibling directory)
219
+ git clone https://github.com/stepfunc/dnp3.git ../stepfunc-dnp3
220
+ cd ../stepfunc-dnp3
221
+ cargo build --release -p dnp3-ffi
222
+
223
+ # 2. Install this package
224
+ cd ../dnp3-python
225
+ pip install -e ".[dev]"
226
+
227
+ # 3. Run tests
228
+ pytest tests/
229
+ ```
230
+
231
+ ## License
232
+
233
+ This Python wrapper is MIT licensed. See [LICENSE](LICENSE).
234
+
235
+ The underlying stepfunc/dnp3 library uses a non-commercial license
236
+ (evaluation, research, and training use only). See the
237
+ [stepfunc/dnp3 LICENSE](https://github.com/stepfunc/dnp3/blob/main/LICENSE.txt)
238
+ for details.
@@ -0,0 +1,17 @@
1
+ dnp3/__init__.py,sha256=7RhCkjj7AAhTa-sXS-KqfXxwNinOAzK2a9u-Hoc32LI,2903
2
+ dnp3/_build_ffi.py,sha256=XKhduO48wQHzAWWxiDGMsYTKGX6fQbODecSbE772oSM,5237
3
+ dnp3/_ffi.py,sha256=8I6Ng1HUgYRmKPrDsY7kAB5D81kJpGv3UZ5Vl29T6Hw,1755
4
+ dnp3/channel.py,sha256=wwyg_ZC4uXD3YJ1HXWpI1kW4ZlbLS2-LOc5lcJ7wIq4,7227
5
+ dnp3/handler.py,sha256=ruGao_Toc-EWqcq1XwbUoz6U24T0BwsVwmheGUraaXQ,17225
6
+ dnp3/logging.py,sha256=a8Jset4GQH3Ks60qNuW7KenhdolT_33udYMLwF4bhX0,2432
7
+ dnp3/master.py,sha256=ggz6sCsXaE1ggVGCrxYAfu5wUTeS8Yzu7lGer-hJGYQ,17773
8
+ dnp3/outstation.py,sha256=pT9OPfm3Zewq05exKnHB0Q2YgckIEfe6He7D8KX4WB0,14977
9
+ dnp3/runtime.py,sha256=ik_f8KKJXsl_we_V5_dhbRoO7p7CFqvwOI5HQ-ZxwSk,1611
10
+ dnp3/types.py,sha256=nJJKplJ62Ij5Njvo6dU-IoP_k-fz5_Oo9odikxjAnAE,11721
11
+ dnp3/vendor/dnp3.h,sha256=UfORDVjFHp9hRXw-nOrc3b2hFYCyaaCIwMs4EueEUnQ,371525
12
+ dnp3/vendor/libdnp3_ffi.so,sha256=JS-a5U3VWn0EDHbT5dUSqpfk7hE_aB8uP7n5-oppcNw,7101512
13
+ pydnp3_stepfunc-1.6.0.3.dist-info/licenses/LICENSE,sha256=rDANftwBo2YLfaPsY4ZKCcHHdQFfpgL1B8GfqE4XIws,1064
14
+ pydnp3_stepfunc-1.6.0.3.dist-info/METADATA,sha256=Tr2ReNKP7oNpRcyhib_4RkgpeX4MvQZ9XQMKZVluZhc,7820
15
+ pydnp3_stepfunc-1.6.0.3.dist-info/WHEEL,sha256=dIWhZP8noP6mB-YKST8g3F1ArFuppNVE7wIphKMromA,104
16
+ pydnp3_stepfunc-1.6.0.3.dist-info/top_level.txt,sha256=Wfb2qiOz-crxcPBaLWFPAzTAt1-9gW6EAitSqdYhIao,5
17
+ pydnp3_stepfunc-1.6.0.3.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: cp310-cp310-linux_x86_64
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 f0rw4rd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ dnp3