Pure Python DNP3 implementation (IEEE 1815-2012)
Project description
dnp3py
A pure Python implementation of the DNP3 (IEEE 1815-2012) protocol.
Features
- Pure Python - No C/C++ dependencies, works anywhere Python runs
- Level 2 Subset - RTU-class functionality for SCADA applications
- Async I/O - Built on asyncio for efficient network communication
- Type Safe - Full type annotations with strict mypy compliance
- Well Tested - Comprehensive test suite with 98%+ code coverage
Installation
pip install dnp3py
Or with pixi:
pixi add dnp3py
Quick Start
Outstation (Server)
import asyncio
from dnp3.database import Database, BinaryInputConfig, AnalogInputConfig
from dnp3.outstation import Outstation
from dnp3.transport_io import TcpServer
async def main():
# Create database with points
database = Database()
database.add_binary_input(0, BinaryInputConfig())
database.add_analog_input(0, AnalogInputConfig())
# Update values
database.update_binary_input(0, value=True)
database.update_analog_input(0, value=25.5)
# Create outstation
outstation = Outstation(database=database)
# Start TCP server
server = TcpServer(host="0.0.0.0", port=20000)
await server.start()
# Handle connections...
asyncio.run(main())
Master (Client)
import asyncio
from dnp3.master import Master, DefaultSOEHandler
from dnp3.transport_io import TcpClientChannel
async def main():
# Create master with event handler
handler = DefaultSOEHandler()
master = Master(handler=handler)
# Connect to outstation
channel = TcpClientChannel(host="localhost", port=20000)
await channel.open()
# Perform integrity poll
request = master.build_integrity_poll()
# Send request, receive response...
asyncio.run(main())
Supported Features
Function Codes
- READ, WRITE
- SELECT, OPERATE, DIRECT_OPERATE
- COLD_RESTART, WARM_RESTART
- ENABLE_UNSOLICITED, DISABLE_UNSOLICITED
- DELAY_MEASURE
Object Groups
| Group | Description |
|---|---|
| 1, 2 | Binary Input (static, event) |
| 10, 11, 12 | Binary Output (static, event, CROB) |
| 20, 21, 22 | Counter (static, frozen, event) |
| 30, 32 | Analog Input (static, event) |
| 40, 41, 42 | Analog Output (static, command, event) |
| 50, 51, 52 | Time objects |
| 60 | Class data |
Development
Setup
# Clone repository
git clone https://github.com/craig8/dnp3py.git
cd dnp3py
# Install with pixi
pixi install
pixi run dev-install
# Set up pre-commit hooks (enforces quality checks before commits)
pixi run pre-commit-install
# Run tests
pixi run test
# Run with coverage
pixi run test-cov
# Lint and type check
pixi run check
# Test with specific Python version
pixi run -e py310 test
pixi run -e py312 test
# Test all Python versions (via nox)
pixi run nox
Project Structure
dnp3py/
├── src/dnp3/
│ ├── core/ # CRC, types, enums, flags
│ ├── datalink/ # Data link layer (frames, parsing)
│ ├── transport/ # Transport layer (segmentation)
│ ├── application/ # Application layer (messages)
│ ├── objects/ # DNP3 object definitions
│ ├── database/ # Point database and events
│ ├── outstation/ # Outstation implementation
│ ├── master/ # Master implementation
│ └── transport_io/ # TCP/simulator channels
└── tests/
├── unit/ # Unit tests
└── integration/ # Integration tests
License
MIT License - see LICENSE for details.
Acknowledgments
This implementation follows the IEEE 1815-2012 standard for DNP3.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dnp3py-0.1.0.tar.gz.
File metadata
- Download URL: dnp3py-0.1.0.tar.gz
- Upload date:
- Size: 168.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4425e4842d0aded1aed75385f4897f03ff3b31940b2b3e1b721c05c24fcab206
|
|
| MD5 |
a954b408b30c16e7f7cc9e1d77ad435c
|
|
| BLAKE2b-256 |
67f64e13ee3d5555dd2790a236f75d1cdf1023bc65c3520be60deac0e5508803
|
Provenance
The following attestation bundles were made for dnp3py-0.1.0.tar.gz:
Publisher:
release.yml on craig8/dnp3py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dnp3py-0.1.0.tar.gz -
Subject digest:
4425e4842d0aded1aed75385f4897f03ff3b31940b2b3e1b721c05c24fcab206 - Sigstore transparency entry: 773976499
- Sigstore integration time:
-
Permalink:
craig8/dnp3py@848c926a640702dfe9867b49336e796baab05eca -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/craig8
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@848c926a640702dfe9867b49336e796baab05eca -
Trigger Event:
push
-
Statement type:
File details
Details for the file dnp3py-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dnp3py-0.1.0-py3-none-any.whl
- Upload date:
- Size: 96.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
79904755e6ecc1ebc05372a64686047574ee7063132863e77d0d647451ae2fa9
|
|
| MD5 |
17a29649e145e69887854d293865c6fa
|
|
| BLAKE2b-256 |
ee52df8083bdb0d33386e1e688d487812fc3ec8fda661e0cec03a458810ded31
|
Provenance
The following attestation bundles were made for dnp3py-0.1.0-py3-none-any.whl:
Publisher:
release.yml on craig8/dnp3py
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dnp3py-0.1.0-py3-none-any.whl -
Subject digest:
79904755e6ecc1ebc05372a64686047574ee7063132863e77d0d647451ae2fa9 - Sigstore transparency entry: 773976502
- Sigstore integration time:
-
Permalink:
craig8/dnp3py@848c926a640702dfe9867b49336e796baab05eca -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/craig8
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@848c926a640702dfe9867b49336e796baab05eca -
Trigger Event:
push
-
Statement type: