Skip to main content

open61850

IEC 61850 for Python, under the Apache 2.0 licence: an MMS client (reports, report control blocks, controls), GOOSE and Sampled Values codecs, Sampled Values publication with a real-time engine, an SCL reader and a Linux capture for the process bus. The library is pure Python (standard library only, Python 3.10 or later); the optional real-time engine is in Rust.

It was written for a test and diagnostic platform of a digital substation process bus, and checked there against real IEDs (a Schneider VMC7 and an ABB SSC600). The other open-source IEC 61850 stack, libiec61850, is GPL; open61850 is an alternative for projects that cannot take a GPL dependency.

Status: alpha. The MMS client side and SV publication are what exist and what has been tested; there is no MMS server yet. Until 1.0, minor versions may change the API.

Installation

pip install open61850
pip install "open61850[rt]"    # adds the real-time SV engine (Linux wheels, x86_64 and aarch64)

What is in it

Module Content
open61850.mms MMS client over TCP: association (Session, Presentation, ACSE, Initiate) with the negotiated limits honoured, reads and writes, GetNameList, type and data set descriptions, several requests in flight matched by invokeID, reports delivered to callbacks, typed errors
open61850.mms.report IEC 61850 report decoding driven by the report's own OptFlds and inclusion bit string (segmentation, reason codes, data references)
open61850.mms.rcb Report control blocks: status, free instance, reservation (edition 1 and 2 BRCBs, URCBs), enabling with checked writes, release
open61850.mms.control Controls: direct and select-before-operate, normal and enhanced security (waits for the CommandTermination, reports the LastApplError AddCause)
open61850.goose GOOSE PDUs and frames (IEC 61850-8-1)
open61850.sv Sampled Values PDUs and frames (IEC 61850-9-2, IEC 61869-9), INT32 + quality samples
open61850.sv_publisher SV publication: streams, waveforms aligned on the UNIX epoch, periodic faults, 6I3U / 4I4U data sets, frame templates, Publisher (native real-time engine or a Python thread)
open61850.ethernet Ethernet II and 802.1Q framing with the APPID header
open61850.data MMS Data values and their BER encoding
open61850.quality Quality and TimeQuality in readable form
open61850.scl SCL files: IEDs, addresses, logical devices, report control blocks and data sets
open61850.capture GOOSE and SV capture on Linux from an AF_PACKET TPACKET_V3 ring, kernel timestamps, 802.1Q tags restored, no libpcap
open61850.ber ASN.1 BER primitives

Only open61850.mms, open61850.capture and the Publisher of open61850.sv_publisher do I/O. The public names of each module are those of its __all__.

Examples

Read a value and list the logical devices:

from open61850.mms import MmsClient, ObjectName, OBJECT_CLASS_DOMAIN

with MmsClient.connect("192.0.2.10") as client:
    print(client.association.max_outstanding_calling)   # requests the IED accepts at once
    print(client.get_name_list(OBJECT_CLASS_DOMAIN))
    print(client.read(ObjectName("LLN0$ST$Mod$stVal", "IED01_LD0")))

Subscribe to a buffered report control block:

import queue
from open61850.mms import MmsClient, ObjectName, decode_report, is_report, rcb

reports = queue.Queue()
with MmsClient.connect("192.0.2.10", on_information_report=reports.put) as client:
    instances = [ObjectName(f"LLN0$BR$CB_MEAS{i:02d}", "IED01_LD0") for i in range(1, 4)]
    free = rcb.find_free(client, instances)
    rcb.enable(client, free.rcb)            # default RcbSettings: dchg, qchg, integrity, GI
    try:
        while True:
            message = reports.get()
            if is_report(message):
                report = decode_report(message)
                print(report.rpt_id, report.seq_num, [(e.index, e.value) for e in report.entries])
    finally:
        rcb.disable(client, free.rcb)       # also releases the reservation

Operate a breaker (the control model is read from the IED):

from open61850.mms import MmsClient, ObjectName, operate

with MmsClient.connect("192.0.2.10") as client:
    result = operate(client, ObjectName("CBCSWI1$CO$Pos", "IED01_BayLD"), False)   # False = open
    print(result)   # control model, ctlNum, CommandTermination, duration

A refusal raises ControlError with the AddCause of the IED.

Decode GOOSE and SV frames captured on the process bus (Linux, root):

from open61850 import goose, sv
from open61850.capture import PacketCapture

with PacketCapture("eth1") as cap:
    while True:
        frame = cap.recv()
        if frame is None:
            continue
        if (decoded := goose.decode_goose_frame(frame.data)) is not None:
            eth, pdu = decoded
            print(frame.timestamp, pdu.gocb_ref, pdu.st_num, pdu.sq_num)
        elif (decoded := sv.decode_sv_frame(frame.data)) is not None:
            eth, pdu = decoded
            print(frame.timestamp, [(a.sv_id, a.smp_cnt) for a in pdu.asdus])

Publish Sampled Values, as a merging unit or a simulator would (Linux, root):

from open61850.sv import Publisher, SvStream, Fault, three_phase

stream = SvStream(
    sv_id="MU01_SV1", app_id=0x4000, dst_mac="01:0c:cd:04:00:01", src_mac="02:00:00:00:00:01",
    waves=three_phase(i_peak=10, v_peak=100, i_lag_deg=30),               # 6I3U: Ia Ib Ic Ires In Ih Va Vb Vc
    fault=Fault(three_phase(i_peak=10, v_peak=100, ia_peak=50, va_peak=20), cycle_s=4),  # every 4 s, for 2 s
    conf_rev=1, smp_synch=2, vlan_id=100, vlan_priority=4,
)
with Publisher("eth1", rate=4800, asdus_per_frame=2, rt_priority=50) as pub:
    pub.add(stream)
    pub.start()          # at the next second: smpCnt 0 goes out on the second
    ...

Waveforms are functions of UNIX time, so several streams, processes or machines on the same clock stay in phase. With open61850[rt] the frames are sent by the Rust engine: absolute CLOCK_REALTIME deadlines, one sendmmsg per period for all streams, optional SCHED_FIFO priority and CPU pinning. Without it, a Python thread sends the same frames, with only the precision of time.sleep (tests, low rates). Measured on loopback on a Xeon server, 3 streams at 4800 samples/s, SCHED_FIFO 50: every sample sent, delay after the nominal sample time median 6 µs, 99th percentile 14 µs, maximum 46 µs over 10 s.

Command line

open61850-mms 192.0.2.10 association
open61850-mms 192.0.2.10 domains
open61850-mms 192.0.2.10 rcbs --status
open61850-mms 192.0.2.10 read 'IED01_LD0/LLN0$DC$NamPlt'
open61850-mms 192.0.2.10 dataset 'IED01_LD0/LLN0$DS_MEAS'
open61850-mms 192.0.2.10 subscribe 'IED01_LD0/LLN0$BR$CB_MEAS'
open61850-mms 192.0.2.10 operate 'IED01_BayLD/CBCSWI1$CO$Pos' open

subscribe takes a block or a group name without its instance number, picks a free instance, prints the decoded reports and releases the block on Ctrl-C.

Scope and limits

  • No MMS server; GOOSE is encoded and decoded, but publishing it (retransmission scheme) is up to the application.
  • SV publication sends sinusoids and periodic faults; arbitrary sample sources (replay, live measurements) are to come.
  • Not implemented: file services, log control blocks and journals, setting groups, IEC 62351 security.
  • The association proposes fixed calling/called AP titles and selectors by default (AssociationParameters changes them).
  • Tested against two IED families so far; reports of other IEDs are welcome.

Development

python -m pip install pytest
python -m pytest

The tests need no network. The AF_PACKET capture tests run on Linux as root (sudo python -m pytest tests/test_capture.py); on another OS, docker run --rm --privileged -v "$PWD":/src -w /src python:3.13-slim sh -c "pip install pytest && python -m pytest".

Maintainer notes (what the IED captures taught, design decisions) are in AGENTS.md.

License

Copyright 2026 Florent Carli

Licensed under the Apache License, Version 2.0. See LICENSE for the full text.

Release files for open61850 0.2.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 open61850 0.2.0
File Size Uploaded
open61850-0.2.0.tar.gz 81.2 kB Details

Built distribution (wheel)

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

Total release size: 150.7 kB

Release files / open61850-0.2.0.tar.gz

Download URL open61850-0.2.0.tar.gz
Size 81.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3be67db78dc481d7c86b2a3884a93702204d751c6658dfd1ec4205d33fb231a0
BLAKE2b-256 checksum
How to use checksums
7384d6ea9915df8ddd4946fbce0897f5460c46b75cc39eda36c899da0becaf41
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 Sep 25, 2026.

Transparency log

Release files / open61850-0.2.0-py3-none-any.whl

Download URL open61850-0.2.0-py3-none-any.whl
Size 69.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab03521ae0c476b28d64d79163e43000dbf2df3ad6f39d195180299baab2157b
BLAKE2b-256 checksum
How to use checksums
3d9b3c6e258e94040fabf2615e06af91b9719572ca9260ae4d2069213d12f1e1
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 Sep 25, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

This release

0.2.0 This release

2 release files

0.1.1

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