Sparkplug B (基于 MQTT 的 IIoT 标准)
Sparkplug B 是 Eclipse Tahu / Cirrus Link 定义的 IIoT 消息标准。它在 MQTT 代理之上叠加了固定的主题结构 + Protobuf 负载,让不同厂商的设备也能互相解读。
Edge 从两个方向使用它 —— 以下两者是不同的功能,请不要混淆。
| 方向 | 是什么 | 记录在哪里 |
|---|---|---|
| 接收(驱动) | 订阅代理上的 Sparkplug 主题,缓存 metric,通过标签读取 | 本文档前半部分 |
| 发送(发布) | Edge 将采集到的值以 Sparkplug B 发布出去 | 下方「发送」 |
注册表单输入值
| 输入项 | 填写内容 | 示例 |
|---|---|---|
| IP 地址 | MQTT broker | 192.168.10.50 |
| 端口 | MQTT broker port | 1883 (明文) / 8883 (TLS,后续支持) |
| Group ID (group-id) | Sparkplug Group —— 工厂/事业所单位 | FactoryA, Plant01 |
| Edge Node ID (edge-node-id) | 单个节点或 +(所有节点) | +(默认), edge-01 |
| Keep Alive (keep-alive) | MQTT keep-alive 秒数 | 60(默认) |
| Connect Timeout (connect-timeout) | MQTT 连接超时 ms | 5000(默认) |
请确认发送侧(Eclipse Tahu / Ignition / Cirrus Link MQTT Engine 等)以何种 group / edge ID 发送 NBIRTH,并输入相同的值。设为 edge-node-id=+ 时,会一次性订阅该 group 内的所有节点。
标签的 PLC 地址表示法
Sparkplug 的 metric 标识符只使用 group 之后的部分(group 由驱动选项分离处理)。
| 表示法 | 含义 |
|---|---|
edge1/Temperature | Edge node edge1 的 node-level metric Temperature |
edge1/motor1/RPM | Edge node edge1 下 device motor1 的 metric RPM |
edge1/dev2/Status | 例如:设备状态 boolean |
Sparkplug 发送侧在 NBIRTH/DBIRTH 时会同时发布 metric 名称与 alias(数字)。之后的 NDATA/DDATA 只发送 alias,以减小负载大小。由于 PlantPulse 驱动会自动维护 alias↔名称的映射表,用户只需始终以名称方式输入即可。
数据类型自动识别
Sparkplug B Payload 会为每个 metric 明确指定 datatype(Int8/16/32/64、UInt8/16/32/64、Float、Double、Boolean、String、DateTime、Bytes 等)。驱动会根据 wire 上的 datatype 转换为合适的类型后以 String 形式缓存,因此标签的 data_type 请按以下方式匹配。
| Sparkplug datatype | 推荐 data_type |
|---|---|
| Int8 / Int16 / Int32 / UInt8 / UInt16 / UInt32 | Integer |
| Int64 / UInt64 / DateTime | Long |
| Float | Float |
| Double | Double |
| Boolean | Boolean |
| String / Text / UUID | String |
写入 (NCMD / DCMD)
PlantPulse 的 write 会自动分流到 NCMD/DCMD。
edge1/SetPoint(segment 2)→ NCMD publish(node 级命令)edge1/dev1/SetPoint(segment 3+)→ DCMD publish(device 级命令)
当前阶段所有命令值都以 String datatype 发布。发送侧(Tahu / Ignition)知道 metric 的 datatype,通常会自动转换。
发送 — Edge 以 Sparkplug B 发布
Edge 将采集到的值以**标准 Sparkplug B(Protobuf)**格式导出。方向与前半部分的「接收」相反。
发布目标是 Edge 自身的 MQTT 设置(mqtt.server.host,默认 127.0.0.1:1883)。这不是向 Platform 发送数据的功能。
请这样理解方向 —— Edge 将数据发布到自己所在的代理上后,订阅该代理的一方(SCADA · MES · 上层 IIoT 平台)会接收数据。 上传到 Platform 的值是与此完全独立的路径。
主题格式
spBv1.0/{groupId}/{type}/{edgeNodeId}[/{deviceId}]
| 位置 | 填入内容 |
|---|---|
groupId | sparkplug.group.id —— 留空则使用站点 id |
edgeNodeId | sparkplug.edge.node.id —— 留空则使用 Edge id |
deviceId | OPC 连接 id(opc_id)—— 一个连接即一个设备 |
配置
| 键 | 默认值 | 说明 |
|---|---|---|
sparkplug.enable | true | 开启发布 |
mqtt.server.host · .port | 127.0.0.1 · 1883 | 发布目标代理 —— 直接使用 Edge 的 MQTT 设置 |
mqtt.server.user · .password | — | 代理凭据 |
sparkplug.group.id | 站点 id | 主题中的 group |
sparkplug.edge.node.id | Edge id | 主题中的 node |
sparkplug.device.strategy | per-opc | 一个 OPC 连接 = 一个设备 |
sparkplug.qos | 0 | MQTT QoS |
sparkplug.alias.enable | true | 以 alias 减小负载 |
sparkplug.cmd.enable | false | 接收命令(NCMD/DCMD) |
sparkplug.bdseq.path | /data1/pp-data/sparkplugb/bdseq | 用于保存 bdSeq 的文件 |
device.strategy 目前只有 per-opc 一种配置注释中虽然也写有 single,但尚未实现。目前仅以 per-opc 方式运行。
metric 名称就是标签 id
🔴 填入 metric 名称位置的是 tag_id —— 不是标签名称(tag_name),也不是层级路径。
tag_name 会作为 metric 的属性附带传递。
| Edge 中的内容 | Sparkplug 属性 |
|---|---|
| 描述 | documentation |
| 标签名称 | displayName —— 与标签 id 相同时省略 |
| 单位 | engUnit |
导致消费方出错的关键点是 tag_id。修改画面上显示的名称是安全的,但修改标签 id 会导致接收方的映射断开。
生命周期 —— 连接与断开时
- 连接代理时会将
NDEATH设为 will —— 即使 Edge 突然宕机,代理也会代为通知 - 发布
NBIRTH - 依次发布所有设备的
DBIRTH - 此后数值以
DDATA方式流动
只有**NBIRTH 与全部 DBIRTH 都「结束之后」**,最初的 BIRTH 才会标记为完成 —— 若中途失败则保持未完成状态。
bdSeq 会保存在文件中(路径见上表)。因此重启 Edge 后,消费方会先收到上一会话的 NDEATH(旧的 bdSeq),随后随着递增的 bdSeq 发出新的 NBIRTH,接着所有 DBIRTH 也会随之发出。若文件不存在或无法读取,则从头开始。
alias —— 重新连接后编号会变化
若为 alias.enable=true(默认),则遵循标准行为 —— BIRTH 时同时携带名称与 alias,之后 DDATA 只发送 alias。负载会更小。
alias 编号是按会话分配的 1, 2, 3 …。重新连接后同一标签可能获得不同编号。 若沿用旧映射,数值会附着到错误的标签上 —— 画面看起来正常,但数值是错的。
接收命令 — cmd.enable
NCMD · DCMD 的接收已实现,默认关闭(sparkplug.cmd.enable=false)。由于这是逐步开放的功能,默认值为关闭。
开启命令主题后,任何能连接到代理的一方都可以向 Edge 发送命令。 该命令是否会最终影响设备写入,取决于具体部署与配置,请在开启前一并确认代理访问控制与写入权限。
Platform 界面中的「Sparkplug 主题」是另一回事
Platform 控制台的 UNS 界面中也会显示 Sparkplug 式的主题。这只是展示名称生成方式的预览,与本文档中的发布功能是相互独立的。
参考链接
- Eclipse Tahu —
<https://eclipse.dev/tahu/> - Sparkplug Spec v3.0 —
<https://sparkplug.eclipse.org/specification/> - Cirrus Link MQTT Engine —
<https://www.cirrus-link.com/mqtt-engine/>