Skip to main content

v0.19.0 Release Notes

EnerOS v0.19.0

Release Date: May 11, 2025 Codename: IEC61850 Git Tag: v0.19.0 Support Status: Stable Total Crates: 54 (4 new) Test Cases: 7480+ (560 new)

Version Overview

EnerOS v0.19.0 “IEC61850” is the core release for EnerOS in the “Substation Automation” direction. The primary goal is to introduce IEC 61850 standard support, including the MMS (Manufacturing Message Specification) protocol stack, IED (Intelligent Electronic Device) model mapping, GOOSE (Generic Object Oriented Substation Event) subscription, and SCL (Substation Configuration Language) configuration file parsing, enabling EnerOS to serve as a substation-layer master station directly interoperating with IEC 61850-compliant intelligent electronic devices.

IEC 61850 is the international standard for substation automation. Compared to traditional IEC 60870-5-104, it adopts an object-oriented information model, abstracting substation devices into Logical Nodes, Logical Devices, and Data Objects, communicating via MMS protocol for client-server communication, GOOSE protocol for fast peer-to-peer communication between devices, and SMV protocol for sample value transmission. IEC 61850 has become the de facto standard for new intelligent substations, with new substations from State Grid and China Southern Power Grid requiring support.

This version introduces four new crates: eneros-iec61850 (IEC 61850 core), eneros-iec61850-mms (MMS protocol stack), eneros-iec61850-goose (GOOSE subscription), and eneros-iec61850-scl (SCL parsing). The design philosophy is “model-native, protocol-native”—IEC 61850’s information model is expressed as strong types in Rust, and SCL configuration files are parsed and directly mapped to EnerOS topology nodes, avoiding the inefficiency and error-proneness of manual point table configuration.

Key Metrics

Metricv0.18.0 (IEC 104 only)v0.19.0 (IEC 61850)Improvement
IED connections102420482x
Data points500K2M4x
GOOSE subscription latencyN/A4msRealtime
Model configuration automationManual point tableSCL automaticSignificant
Protocol coverage104104+61850Full scenario

New Features

1. IEC 61850 Support

Introduced the eneros-iec61850 crate as the unified entry point for the IEC 61850 subsystem, managing IED connections, model mapping, data collection, and control. The IEC 61850 subsystem is deeply integrated with the EnerOS topology engine—SCL configuration files are parsed to automatically build grid topology without manual point table maintenance.

IEC 61850 Client

use eneros_iec61850::{Iec61850Client, ClientConfig};

let mut client = Iec61850Client::new(ClientConfig {
    max_connections: 2048,
    mms_port: 102,
    goose_enabled: true,
    smv_enabled: false,
    time_sync: true,
    auto_discovery: true,
})?;

// Connect to IED
client.connect_ied("ied-1", "10.20.30.5:102").await?;

// Auto-discover IED model
let device_model = client.discover_model("ied-1").await?;
println!("Logical device count: {}", device_model.logical_devices.len());

client.start().await?;

IEC 61850 vs IEC 104 Comparison

DimensionIEC 60870-5-104IEC 61850
Information modelPoint tableObject-oriented
ConfigurationManual point tableSCL automatic
Peer communicationNot supportedGOOSE
Sample value transmissionNot supportedSMV
Model semanticsWeakStrong
Use caseDispatch master stationWithin substation

2. MMS Protocol Stack

Introduced the eneros-iec61850-mms crate, implementing the MMS (Manufacturing Message Specification) protocol stack as the core protocol for IEC 61850 client-server communication. MMS is based on TCP/IP, carrying IEC 61850 read, write, report, and control operations.

MMS Communication Model

use eneros_iec61850_mms::{MmsClient, MmsRequest, ReadResult};

let mms = MmsClient::new("ied-1", "10.20.30.5:102").await?;

// Read data object
let result: ReadResult = mms.read("LD0/LLN0.Health.stVal").await?;
println!("IED health status: {:?}", result.value);

// Read multiple data objects
let results = mms.read_multiple(&[
    "LD0/LLN0.Health.stVal",
    "LD0/PTUV.phsA.cVal.mag.f",
    "LD0/PTUV.phsB.cVal.mag.f",
    "LD0/PTUV.phsC.cVal.mag.f",
]).await?;

// Write control object (with select)
mms.select("LD0/XCBR1.Pos.Oper").await?;
mms.operate("LD0/XCBR1.Pos.Oper", Value::Bool(true)).await?;

// Subscribe to reports
mms.enable_report("rcb_01").await?;

MMS Data Types

TypeDescriptionExample
BooleanBooleantrue/false
IntegerInteger1024
FloatFloat220.5
StringString”Healthy”
TimestampTimestamp2025-05-11T10:00:00Z
QualityQualityValidity::Good
ArrayArray[1.0, 2.0, 3.0]
StructStructureComposite data

Report Control Block (RCB)

use eneros_iec61850_mms::{ReportControlBlock, TriggerOption};

// Configure report control block
let rcb = ReportControlBlock::new("rcb_01")
    .dataset("LD0/LLN0.dsStatData")
    .trigger_options(TriggerOption::DATA_CHANGED | TriggerOption::QUALITY_CHANGED)
    .integrity_period(Duration::seconds(5))
    .buffered(true)
    .buf_time(Duration::milliseconds(0));

mms.configure_rcb(&rcb).await?;

// Receive reports
mms.on_report(|report| {
    for entry in &report.entries {
        println!("{}: {:?} @ {:?}", entry.path, entry.value, entry.timestamp);
    }
});

3. IED Model Mapping

IEC 61850’s information model (logical nodes, logical devices, data objects) is automatically mapped to EnerOS topology nodes and data points, allowing IED data to directly integrate into EnerOS’s unified model without manual conversion.

Information Model Structure

use eneros_iec61850::{IedModel, LogicalDevice, LogicalNode, DataObject};

// IED model hierarchy
let ied = IedModel::new("ied-1")
    .logical_device(LogicalDevice::new("LD0")
        .logical_node(LogicalNode::new("LLN0")  // Logical Node Zero
            .data_object(DataObject::new("Health").with_data_set("dsHealth")))
        .logical_node(LogicalNode::new("PTUV")   // Voltage transformer
            .data_object(DataObject::new("phsA").with_data_attribute("cVal.mag.f"))
            .data_object(DataObject::new("phsB").with_data_attribute("cVal.mag.f"))
            .data_object(DataObject::new("phsC").with_data_attribute("cVal.mag.f")))
        .logical_node(LogicalNode::new("XCBR1")  // Breaker
            .data_object(DataObject::new("Pos").with_data_attribute("stVal"))));

Model Mapping to EnerOS Topology

use eneros_iec61850::mapping::TopologyMapper;

// Map IED model to EnerOS topology nodes
let mapper = TopologyMapper::new(&network, &client);

// Automatic mapping
let mapping = mapper.map_ied("ied-1", &ied_model).await?;

// Mapping result
println!("IED ied-1 mapped {} logical nodes to topology", mapping.node_count);
// LD0/PTUV -> topology node "Bus PT"
// LD0/XCBR1 -> topology node "Breaker 1"

Logical Node Type Mapping

IEC 61850 Logical NodeMeaningEnerOS Mapping
LLN0Logical Node ZeroIED health status
PTUVVoltage transformerBus voltage point
XCBRBreakerBreaker device
XSWIDisconnectorDisconnector device
MMXUMeasurement unitComprehensive measurement point
PTOCOvercurrent protectionProtection device
PTOVOvervoltage protectionProtection device
RBRFBusbar differential protectionProtection device

4. GOOSE Subscription

Introduced the eneros-iec61850-goose crate, implementing GOOSE protocol subscription and parsing. GOOSE is IEC 61850’s peer communication protocol, based on multicast Ethernet, used for fast event notification between devices with typical latency below 4ms, and is a key protocol for substation protection coordination.

GOOSE Subscription

use eneros_iec61850_goose::{GooseSubscriber, GooseConfig};

let subscriber = GooseSubscriber::new(GooseConfig {
    interface: "eth0",
    multicast_groups: vec!["01:0c:cd:01:00:01".parse()?],
    filter: GooseFilter::by_app_id(vec![0x0001, 0x0002]),
})?;

// Subscribe to GOOSE messages
subscriber.subscribe(|message| {
    println!("GOOSE from: {}", message.source);
    println!("App ID: 0x{:04x}", message.app_id);
    println!("StNum: {}", message.st_num);
    println!("SqNum: {}", message.sq_num);
    
    for entry in &message.dataset {
        println!("  {}: {:?}", entry.path, entry.value);
    }
})?;

subscriber.start().await?;

GOOSE Message Structure

FieldDescriptionLength
App IDApplication identifier2 bytes
StNumState number (+1 per state change)4 bytes
SqNumSequence number (+1 per retransmission of same state)4 bytes
TimeEvent timestamp8 bytes
DatasetDatasetVariable

GOOSE Performance Metrics

MetricValueDescription
End-to-end latency< 4msBetween devices
Republish interval1ms-60sConfigurable
Heartbeat interval60sDefault
State change triggerImmediateHighest priority
Dataset sizeUp to 256 entriesSufficient

5. SCL Configuration File Parsing

Introduced the eneros-iec61850-scl crate, parsing IEC 61850 SCL (Substation Configuration Language) configuration files to automatically extract substation structure, IED configurations, and communication parameters without manual point table configuration.

SCL Parsing

use eneros_iec61850_scl::{SclParser, SclFile};

// Parse SCL file
let scl = SclParser::parse_file("/config/substation.scd")?;

// Extract substation structure
let substation = scl.substation("SUB1")?;
println!("Voltage level count: {}", substation.voltage_levels.len());

for vl in &substation.voltage_levels {
    println!("Voltage level: {} kV", vl.nominal_voltage);
    for bay in &vl.bays {
        println!("  Bay: {}", bay.name);
        for equipment in &bay.equipments {
            println!("    Equipment: {} ({:?})", equipment.name, equipment.kind);
        }
    }
}

// Extract IED configuration
for ied in scl.ieds() {
    println!("IED: {} ({})", ied.name, ied.manufacturer);
    println!("  IP: {}", ied.communication_address()?);
    println!("  Logical device count: {}", ied.logical_devices.len());
}

SCL File Types

ExtensionTypeDescription
.icdIED Capability DescriptionSingle IED configuration
.scdSubstation Configuration DescriptionFull station configuration
.cidConfigured IED DescriptionIED runtime configuration
.ssdSystem Specification DescriptionPrimary system specification
.sedSystem Exchange DescriptionInter-project exchange

Automatic Topology Building

use eneros_iec61850_scl::topology::TopologyBuilder;

// Automatically build topology from SCL
let builder = TopologyBuilder::from_scl(&scl)?;
let network = builder.build().await?;

println!("Automatically built topology:");
println!("  Node count: {}", network.node_count());
println!("  Edge count: {}", network.edge_count());
println!("  IED count: {}", network.ied_count());

// Automatically configure SCADA connections
for ied in scl.ieds() {
    let addr = ied.communication_address()?;
    client.connect_ied(&ied.name, &addr).await?;
}

Improvements

  • Topology Engine: Supports automatic topology building from SCL, reducing manual configuration by 90%
  • Time Series Storage: Supports high-frequency IEC 61850 data writes, throughput improved 3x
  • Digital Twin: Twin directly subscribes to IEC 61850 data, improving state fidelity
  • Dashboard: New IEC 61850 monitoring panel, displaying IED tree structure and GOOSE communication status

Bug Fixes

  • Fixed eneros-iec61850-mms buffer overflow on large dataset reads (#1908)
  • Fixed eneros-iec61850-goose packet loss under high load (#1914)
  • Fixed eneros-iec61850-scl namespace conflict during parsing (#1920)
  • Fixed eneros-iec61850 report subscription loss after IED reconnection (#1926)

Breaking Changes

  • Gateway::add_iec61850: Migrated to Iec61850Client::connect_ied
  • Network::from_scl: Return type changed to Result<Network>, requires ?
  • ReportControlBlock::new: New required dataset parameter

Performance Improvements

  • IED connections increased from 1024 to 2048 (2x improvement)
  • Data points increased from 500K to 2M (4x improvement)
  • GOOSE subscription latency stable within 4ms
  • SCL parsing time reduced from minutes to seconds

Contributors

This version was jointly completed by 24 contributors with 418 commits. Special thanks to:

  • @iec61850-arch: IEC 61850 subsystem architecture
  • @mms-implementer: MMS protocol stack Rust implementation
  • @goose-master: GOOSE subscription and multicast handling
  • @scl-parser: SCL configuration file parser

Upgrade Guide

Upgrading from v0.18.0

1. Update Dependencies

# Cargo.toml
[dependencies]
eneros-iec61850 = { version = "0.19" }
eneros-iec61850-mms = { version = "0.19" }
eneros-iec61850-goose = { version = "0.19" }
eneros-iec61850-scl = { version = "0.19" }

2. Load SCL Configuration

use eneros_iec61850_scl::SclParser;
use eneros_iec61850_scl::topology::TopologyBuilder;

// Parse SCL and automatically build topology
let scl = SclParser::parse_file("/config/substation.scd")?;
let network = TopologyBuilder::from_scl(&scl)?.build().await?;

3. Enable IEC 61850

# eneros.toml
[iec61850]
enabled = true
mms_port = 102
goose_interface = "eth0"
goose_enabled = true
time_sync = true

4. Mixed Protocol Deployment

Production environments typically need to support both IEC 61850 (new substations) and IEC 60870-5-104 (legacy substations). EnerOS supports mixed protocol deployment:

// Start both SCADA master station (IEC 104) and IEC 61850 client simultaneously
let scada = ScadaMaster::new(scada_config)?;
let iec61850 = Iec61850Client::new(iec61850_config)?;

scada.start().await?;
iec61850.start().await?;

// Both data sources flow into the unified EnerOS pipeline
pipeline.subscribe_all().for_each(|event| {
    // Unified processing
}).await?;

5. GOOSE Deployment Notes

GOOSE is based on Layer 2 multicast Ethernet. Deployment requires ensuring network devices support IGMP Snooping and proper multicast group configuration. Cross-subnet GOOSE requires GMRP or static multicast configuration. See the operations manual “IEC 61850 Network Configuration” chapter for details.