Skip to main content

Satori

SunSpec Alliance      DER Security

py20305

The IEEE 2030.5 / CSIP client of Project Satori — an open-source project led by the SunSpec Alliance, DER Security, and industry consortium members.

CI Tests Coverage PyPI Python License Project Satori

An open IEEE 2030.5 client for distributed energy resources, with CSIP-AUS support. It speaks the utility's protocol so your device doesn't have to.

Point it at an IEEE 2030.5 server and it registers, discovers what the server exposes, runs the DERControl schedule it is given, applies the resulting setpoints to a device, and posts telemetry back.

Install

pip install py20305

The base install is the protocol client. Extras add what you may not need: sunspec for Modbus devices, api for the HTTP management API, mqtt for traffic forwarding, or all.

Running it as a service

pip install "py20305[cli,sunspec]"
py20305 --config client.yaml --check   # validate, print your LFDI
py20305 --config client.yaml           # run

One YAML or JSON file describes the server, the certificate and the devices. It retries the connection while the server is down, registers itself only if the server does not already know it, and stops cleanly on SIGTERM. See Running a client and examples/client.example.yaml.

Running it in a container

docker build -t py20305 .
docker run -d -v "$PWD/config:/etc/py20305:ro" py20305

The image carries the client and nothing else -- configuration and certificates are mounted, never baked in. It runs unprivileged and stops in order on SIGTERM. See Running in a container and examples/docker-compose.yml.

Embedding it: talking to a server in five minutes

IEEE 2030.5 is mutual TLS throughout, and the server identifies your client by its certificate. Your LFDI — the identifier the utility registers — is derived from it:

from pathlib import Path
from py20305.security import compute_lfdi

print(compute_lfdi(Path("certs/client.pem").read_text()))

Give that to whoever runs the server, then:

python examples/quickstart.py \
  --url https://server.example.com:8443 \
  --cert certs/client.pem --key certs/client.key --ca certs/ca.pem

That drives the print connector, which needs no hardware — it logs the controls it would have applied. So you can exercise the whole discovery, event and telemetry path against a real server before an inverter is wired up.

Swap in SunSpecDeviceConfig when you have one. Full walkthrough in the quickstart.

What's in it

Protocol client Resource discovery, registration, mTLS transport, retry with backoff, redirect probing, server timebase
Finding a server DNS-SD query over mDNS or xmDNS when no server URL is configured, as IEEE 2030.5 §6.9.2 asks of a client; optional announcement of this client so an operator can find it on their own network
Event engine DERControl five-state machine, supersession across programs, randomized start and duration, Response acknowledgments
Pricing IEEE 2030.5 Pricing function set, off by default: discovers the tariff tree and relays each active interval's price to connectors as it changes; relay-only, so the client does not act on price, the connector decides
Telemetry DERStatus, DERCapability, DERSettings, DERAvailability, metered readings as MirrorUsagePoints, started and rediscovered for you by the runner
Connectors SunSpec Modbus over TCP, RTU and TLS; a no-hardware print connector; your own by subclass or factory
Subscriptions Subscribe/notify as an alternative to polling, with a notification listener
Runner A CLI, config file, connection retry and signal-handled shutdown
Management API Optional HTTP API for observing and nudging a running client
Forwarding Optional MQTT publication of every captured exchange

Standards

IEEE 2030.5-2018 and 2030.5-2023. Both XSDs ship with the package and validation runs against them. The generated bindings track 2023; a server_2018_compat flag adjusts behavior for servers still on 2018.

CSIP-AUS, including DOE (dynamic operating envelope) limits.

The client maps one certificate identity to one end device. It registers and drives that device, and does not fan a server-side EndDevice out across several local ones.

Certification

py20305 is not SunSpec CSIP certified, and using it does not make a product certified. Certification is a property of the product -- the assembled client device or system, tested as a whole -- not of a library inside it.

If you are building a client product that needs SunSpec CSIP certification, follow the SunSpec Alliance's certification process: IEEE 2030.5 / CSIP certification.

Project Satori

Any certified DER. Any utility program. Satori — “awakening” — is an open-source initiative to make any certified DER a compliant participant in utility DER programs: point it at the Modbus port of a UL 1741 SB device — inverter, battery, or EV — and it joins a program without a firmware rewrite. The bundle builds on SunSpec-certified implementations contributed by DER Security, and this repository is its IEEE 2030.5 half:

Project Role
PySunSpec2 SunSpec Modbus reference library, used in more than 80% of inverter-based products shipped globally
py20305 (this repository) IEEE 2030.5 client stack with CSIP and CSIP-AUS support, and a SunSpec Modbus bridge
Satori Scout Phone app that finds DER on a network: a SunSpec Modbus sweep of the local subnet, and IEEE 2030.5 discovery over mDNS. A reference implementation rather than an open-source component

Project website: https://open-satori.org

Documentation

https://dersecurity.github.io/py20305/

Development

pip install -e ".[dev]"
pytest tests -q                 # unit tests, no network
ruff check src tests examples scripts
mypy
mkdocs serve                    # docs at http://127.0.0.1:8000

There is also an end-to-end suite that runs this client against envoy, the open-source CSIP-AUS utility server from the Australian National University — the implementation ANU's certification program runs on. It needs Docker:

python scripts/e2e_server.py up
pytest tests/e2e -v
python scripts/e2e_server.py down

The unit suite proves this client does what we believe the standard requires. That one proves the belief survives contact with an implementation nobody here wrote. See Testing.

See CONTRIBUTING.md.

License

Apache-2.0. See LICENSE and NOTICE.

Metadata

Release files for py20305 0.13.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for py20305 0.13.0
File Size Uploaded
py20305-0.13.0.tar.gz 930.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for py20305 0.13.0
File Interpreter ABI Platform
py20305-0.13.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.6 MB

Release files / py20305-0.13.0.tar.gz

Download URL py20305-0.13.0.tar.gz
Size 930.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0367a9acc389d6090006fcf2f25001f04266ffb2fa7794fee5b0598ca389e35f
BLAKE2b-256 checksum
How to use checksums
0804b5a7111e5ff6ad78aad606b7c0b62944934b21a6462806280eb6ed707528
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release files / py20305-0.13.0-py3-none-any.whl

Download URL py20305-0.13.0-py3-none-any.whl
Size 643.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b3b012b628d7750a970240331625891a516b5588cae36afecb49271bcb70104c
BLAKE2b-256 checksum
How to use checksums
772fe754d99b6acd3539412dba26243c799ac950faf70fc89960616b67b76314
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.13.0 This release

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.9.0

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page