跳到主内容

v0.36.0 版本说明

EnerOS v0.36.0

发布日期:2026-05-02
版本代号:IoT
Git Tag:v0.36.0
支持状态:稳定(Stable)
Crate 总数:84(新增 6 个)
测试用例数:10700+(新增 700)

概述

EnerOS v0.36.0「IoT」是物联网泛在接入专题版本,将 EnerOS 的设备接入能力从传统 IEC 61850/SCADA 扩展到物联网协议体系,实现「源网荷储」全要素泛在接入。本版本使 EnerOS 能够接入百万级物联网设备,支撑智能配电网、分布式新能源、用户侧储能、电动汽车充电桩等新型设备的即插即用接入。

IoT 版本的核心设计哲学是「协议无关 + 设备影子」——上层应用不直接对接各种异构通信协议,而是通过统一的设备模型与设备影子进行交互。设备影子作为物理设备在内核中的数字代理,解耦了设备的在线状态与应用的访问需求:设备离线时,应用仍可读取影子中的最后已知状态;设备上线后,影子自动同步并追加离线期间的数据。

本版本引入五大核心能力:MQTT 协议支持OPC UA 协议支持设备影子引擎批量设备管理设备接入网关。所有能力均通过 eneros-ioteneros-iot-mqtteneros-iot-opcuaeneros-iot-shadoweneros-iot-batch 五个新 crate 实现。

关键数据

指标数值说明
MQTT 并发连接10 万单节点
OPC UA 设备接入5 万单节点
设备影子更新延迟2ms单设备
批量配置下发1 万台/秒并行
新增 Crate6IoT 相关
新增测试700+含 150 个端到端

新特性

1. MQTT 协议支持

新增 eneros-iot-mqtt crate,提供高性能 MQTT 5.0 broker 与客户端,支持百万级设备并发接入。MQTT 是物联网领域事实标准,广泛应用于智能电表、充电桩、分布式光伏等设备。

MQTT Broker 配置

use eneros_iot_mqtt::{MqttBroker, BrokerConfig, AuthConfig};

let broker = MqttBroker::new(BrokerConfig {
    listen: "0.0.0.0:1883".parse()?,
    listen_tls: Some("0.0.0.0:8883".parse()?),
    max_connections: 100_000,
    max_packet_size: 256 * 1024,
    auth: AuthConfig::Certificate {
        ca: "/etc/eneros/ca.pem",
        require_client_cert: true,
    },
    session_persistence: true,
    retained_messages: 100_000,
}).await?;

// 启动 broker
broker.start().await?;

设备接入与数据流转

use eneros_iot_mqtt::{DeviceClient, TopicPattern};

// 设备侧:发布遥测数据
let client = DeviceClient::connect("mqtts://broker.eneros.io:8883").await?;
client.publish(
    TopicPattern::telemetry("meter-001"),
    json!({
        "voltage": 220.3,
        "current": 15.2,
        "power": 3.35,
        "timestamp": now_iso8601(),
    }),
    QoS::AtLeastOnce,
).await?;

// 平台侧:订阅设备数据流
let mut stream = broker.subscribe(TopicPattern::telemetry("+")).await?;
while let Some(msg) = stream.next().await {
    let device_id = msg.topic.extract_device_id()?;
    let telemetry: Telemetry = serde_json::from_slice(&msg.payload)?;
    // 自动写入时序引擎
    timeseries.write(device_id, telemetry).await?;
}

MQTT Topic 设计

Topic 模式用途QoS示例
devices/{id}/telemetry遥测数据上报1devices/meter-001/telemetry
devices/{id}/command命令下发2devices/meter-001/command
devices/{id}/event事件上报1devices/meter-001/event
devices/{id}/shadow影子更新1devices/meter-001/shadow
devices/{id}/status在线状态1devices/meter-001/status
broadcast/{topic}广播消息0broadcast/ota-notice

性能基准

指标数值说明
并发连接10 万单节点
消息吞吐50 万/秒QoS 1
消息延迟 P993ms同节点
内存占用1.2 GB10 万连接
TLS 握手8ms证书认证

2. OPC UA 协议支持

新增 eneros-iot-opcua crate,提供 OPC UA 客户端与服务端,接入工业控制系统(DCS/PLC/RTU)。OPC UA 是工业自动化领域主流协议,支持信息模型与安全机制。

OPC UA 客户端

use eneros_iot_opcua::{OpcUaClient, ClientConfig, SecurityPolicy};

let client = OpcUaClient::new(ClientConfig {
    endpoint: "opc.tcp://10.20.30.40:4840",
    security: SecurityPolicy::Basic256Sha256,
    auth: AuthMode::UserName {
        username: "eneros",
        password: "********",
    },
    subscription_interval: Duration::milliseconds(100),
}).await?;

// 连接并浏览地址空间
let namespace = client.get_namespace("urn:PLC:Substation1").await?;
let nodes = client.browse(&namespace.root()).await?;

// 订阅节点数据变化
let subscription = client.subscribe(vec![
    "ns=2;s=Bus1.Voltage",
    "ns=2;s=Line3.Current",
    "ns=2;s=CircuitBreaker42.Status",
]).await?;

let mut stream = subscription.data_changes();
while let Some(change) = stream.next().await {
    println!("节点 {} 变更: {:?}", change.node_id, change.value);
    timeseries.write(change.node_id, change.value).await?;
}

OPC UA 信息模型映射

OPC UA 概念EnerOS 概念映射方式
Node设备/测点自动注册
Object设备实例映射为 Equipment
Variable遥测数据映射为 TimeseriesPoint
Method控制命令映射为 Command
Event事件告警映射为 Event

3. 设备影子引擎

新增 eneros-iot-shadow crate,为每个设备维护一个数字影子,包含期望状态(desired)、上报状态(reported)与最后已知状态(last_known)。

影子数据结构

use eneros_iot_shadow::{DeviceShadow, ShadowState};

let shadow = shadow_store.get_or_create("meter-001").await?;

// 设备上报状态
shadow.update_reported(json!({
    "voltage": 220.3,
    "current": 15.2,
    "power_factor": 0.95,
    "status": "online",
})).await?;

// 应用设置期望状态
shadow.update_desired(json!({
    "switch": "on",
    "brightness": 80,
})).await?;

// 获取当前影子状态
let state: ShadowState = shadow.state().await?;
println!("期望状态: {:?}", state.desired);
println!("上报状态: {:?}", state.reported);
println!("差异: {:?}", state.delta);  // desired 与 reported 的差异

影子更新流程

// 设备上线后自动同步差异
shadow.on_device_online(|device_id| {
    let delta = shadow.delta().await?;
    if !delta.is_empty() {
        // 向设备下发期望状态
        mqtt_client.publish(
            TopicPattern::command(device_id),
            delta,
            QoS::AtLeastOnce,
        ).await?;
    }
}).await?;

// 设备离线时保留最后状态
shadow.on_device_offline(|device_id| {
    shadow.freeze_last_known().await?;
}).await?;

影子版本与冲突

字段类型说明
versionu64单调递增版本号
timestampDateTime最后更新时间
desiredJSON期望状态
reportedJSON上报状态
last_knownJSON最后已知状态
metadataMap各字段更新时间

4. 批量设备管理

新增 eneros-iot-batch crate,支持大规模设备的批量注册、批量配置、批量升级、批量控制。

批量注册

use eneros_iot_batch::{BatchManager, BatchOperation};

let manager = BatchManager::new(&ctx);

// 批量注册设备(CSV 导入)
let job = manager.batch_register()
    .source("devices.csv")
    .template(DeviceTemplate::new("smart-meter-v3"))
    .parallelism(32)
    .on_progress(|p| println!("注册进度: {:.1}%", p.percentage))
    .execute().await?;

println!("成功: {}, 失败: {}", job.success, job.failure);

批量配置下发

// 批量配置 1 万台设备
let rollout = manager.batch_config()
    .target(DeviceFilter::model("smart-meter-v3"))
    .config(ConfigPatch {
        collection_interval: Duration::seconds(15),
        reporting_endpoint: "mqtts://broker.eneros.io:8883",
        firmware_version: "3.2.1",
    })
    .strategy(RolloutStrategy::Wave {
        wave_size: 500,
        wave_interval: Duration::minutes(5),
        failure_threshold: 0.02,  // 2% 失败率暂停
    })
    .execute().await?;

批量操作类型

操作说明并发度耗时(1 万台)
注册批量注册设备325 分钟
配置批量下发配置1610 分钟
升级批量 OTA 升级830 分钟
控制批量控制命令6430 秒
查询批量状态查询12810 秒

5. 设备接入网关

新增 eneros-iot crate(IoT 核心),提供统一的设备接入网关,支持多协议并存与协议转换。

多协议接入

use eneros_iot::{DeviceGateway, ProtocolAdapter};

let gateway = DeviceGateway::new(&ctx);

// 注册协议适配器
gateway.register_adapter(ProtocolAdapter::mqtt(mqtt_config))?;
gateway.register_adapter(ProtocolAdapter::opcua(opcua_config))?;
gateway.register_adapter(ProtocolAdapter::modbus(modbus_config))?;
gateway.register_adapter(ProtocolAdapter::iec104(iec104_config))?;

// 统一设备模型
gateway.on_device_data(|data| {
    // 无论来自哪种协议,统一为 EnerOS 设备模型
    let device_id = data.device_id;
    let telemetry = data.to_telemetry();
    timeseries.write(device_id, telemetry).await?;
    shadow_store.update_reported(device_id, data.payload).await?;
}).await?;

gateway.start().await?;

协议适配对比

协议适用设备数据模型安全机制
MQTT智能电表、充电桩Topic + JSONTLS + 证书
OPC UAPLC、DCS信息模型安全策略
ModbusRTU、传感器寄存器映射网段隔离
IEC 104传统 RTU遥测遥信应用层认证
CoAP低功耗设备RESTfulDTLS

设备发现

// 自动发现局域网内设备
let discovered = gateway.discover()
    .protocol(Protocol::Mqtt)
    .subnet("10.20.30.0/24")
    .timeout(Duration::seconds(10))
    .execute().await?;

for device in &discovered {
    println!("发现设备: {} ({:?}) @ {}",
        device.id, device.protocol, device.address);
    // 自动注册到设备注册表
    gateway.auto_register(device).await?;
}

改进

  • 时序引擎:新增 IoT 数据专用写入路径,小批量写入吞吐提升 3 倍
  • 拓扑引擎:支持从 IoT 设备自动构建低压配电网拓扑
  • Agent 运行时:新增 IoTAgent 类型,专门处理设备交互
  • 安全网关:IoT 设备接入强制设备证书认证
  • 可观测性:IoT 设备指标接入中心监控

Bug 修复

  • 修复 eneros-iot-mqtt 在大量客户端同时连接时 broker 崩溃的问题(#3603)
  • 修复 eneros-iot-opcua 订阅在服务端重启后未自动恢复的问题(#3610)
  • 修复 eneros-iot-shadow 并发更新时版本号冲突的问题(#3616)
  • 修复 eneros-iot-batch 批量操作在中途失败时未回滚的问题(#3622)
  • 修复 eneros-iot 多协议并发时资源竞争导致数据丢失的问题(#3628)

破坏性变更

  • DeviceShadow::update:拆分为 update_reportedupdate_desired
  • DeviceGateway::register_adapter:返回 Result<()>,需处理冲突
  • BatchManager:所有方法改为异步(async

升级指南

  1. 更新 Cargo.toml 中的 eneros 依赖至 0.36.0
  2. 运行 eneros iot init 初始化 IoT 网关
  3. eneros.toml 中配置 MQTT/OPC UA 协议参数
  4. 运行 eneros iot import devices.csv 批量导入设备

致谢

感谢 35 位贡献者提交的 520+ 个 commit,以及物联网协议社区提供的兼容性测试。