核心目标:建立对 IEC 61850 Report 机制的完整理论认知,理解报告控制块(RCB)的属性全集、触发模型与缓冲语义,能读懂标准条文并指导工程实践。
前置依赖:主系列 Part 2(信息模型:LD/LN/DO/DA/DataSet)、Part 3 §3.2.5(Report 机制基础)。
本专题定位:主系列 Part 3 已讲清"Report 是什么、怎么交互",本专题回答"为什么这样设计、属性全集如何、缓冲区状态机如何运转、出了问题怎么从原理层面定位"。
1.1 为什么需要 Report:C/S 模型的推送补丁
1.1.1 轮询的三大痛点
IEC 61850 的站控层通信基于 MMS 的 Client/Server 模型。最朴素的数据获取方式是轮询(Polling) :Client 周期性地向 Server 发起 Read 请求,拉取关心的数据对象当前值。这种方式在概念上简单,但在电力监控场景下存在三大痛点:
- 延迟不可控 :事件发生到下一次轮询之间存在随机间隔。若轮询周期为
T,事件平均感知延迟为T/2,最坏情况为T。对于保护跳闸这类事件,秒级延迟是不可接受的。 - 带宽浪费严重:绝大多数轮询返回的是"未变化"的冗余数据。假设一个 IED 有 500 个数据点,每秒轮询一次,即使只有 1 个点变化,仍有 499 个点的报文是无效负载。
- Server 负载高 :每次
Read请求都需要 Server 解析对象引用、查找数据树、编码响应。高频轮询会显著占用 IED 的 CPU 资源,挤压保护逻辑的执行预算。
1.1.2 Report 的设计哲学
Report 机制是 IEC 61850 为 C/S 模型打的"推送补丁":事件驱动 + 服务端主动推送。Server 监视数据对象的变化,当满足预设的触发条件时,主动构造 Report 报文推送给已订阅的 Client。
#mermaid-svg-Q1xh2t2JI0dUK8GM{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Q1xh2t2JI0dUK8GM .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Q1xh2t2JI0dUK8GM .error-icon{fill:#552222;}#mermaid-svg-Q1xh2t2JI0dUK8GM .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Q1xh2t2JI0dUK8GM .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Q1xh2t2JI0dUK8GM .marker.cross{stroke:#333333;}#mermaid-svg-Q1xh2t2JI0dUK8GM svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Q1xh2t2JI0dUK8GM p{margin:0;}#mermaid-svg-Q1xh2t2JI0dUK8GM .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Q1xh2t2JI0dUK8GM .cluster-label text{fill:#333;}#mermaid-svg-Q1xh2t2JI0dUK8GM .cluster-label span{color:#333;}#mermaid-svg-Q1xh2t2JI0dUK8GM .cluster-label span p{background-color:transparent;}#mermaid-svg-Q1xh2t2JI0dUK8GM .label text,#mermaid-svg-Q1xh2t2JI0dUK8GM span{fill:#333;color:#333;}#mermaid-svg-Q1xh2t2JI0dUK8GM .node rect,#mermaid-svg-Q1xh2t2JI0dUK8GM .node circle,#mermaid-svg-Q1xh2t2JI0dUK8GM .node ellipse,#mermaid-svg-Q1xh2t2JI0dUK8GM .node polygon,#mermaid-svg-Q1xh2t2JI0dUK8GM .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Q1xh2t2JI0dUK8GM .rough-node .label text,#mermaid-svg-Q1xh2t2JI0dUK8GM .node .label text,#mermaid-svg-Q1xh2t2JI0dUK8GM .image-shape .label,#mermaid-svg-Q1xh2t2JI0dUK8GM .icon-shape .label{text-anchor:middle;}#mermaid-svg-Q1xh2t2JI0dUK8GM .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Q1xh2t2JI0dUK8GM .rough-node .label,#mermaid-svg-Q1xh2t2JI0dUK8GM .node .label,#mermaid-svg-Q1xh2t2JI0dUK8GM .image-shape .label,#mermaid-svg-Q1xh2t2JI0dUK8GM .icon-shape .label{text-align:center;}#mermaid-svg-Q1xh2t2JI0dUK8GM .node.clickable{cursor:pointer;}#mermaid-svg-Q1xh2t2JI0dUK8GM .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Q1xh2t2JI0dUK8GM .arrowheadPath{fill:#333333;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Q1xh2t2JI0dUK8GM .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q1xh2t2JI0dUK8GM .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Q1xh2t2JI0dUK8GM .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q1xh2t2JI0dUK8GM .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Q1xh2t2JI0dUK8GM .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Q1xh2t2JI0dUK8GM .cluster text{fill:#333;}#mermaid-svg-Q1xh2t2JI0dUK8GM .cluster span{color:#333;}#mermaid-svg-Q1xh2t2JI0dUK8GM div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Q1xh2t2JI0dUK8GM .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Q1xh2t2JI0dUK8GM rect.text{fill:none;stroke-width:0;}#mermaid-svg-Q1xh2t2JI0dUK8GM .icon-shape,#mermaid-svg-Q1xh2t2JI0dUK8GM .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q1xh2t2JI0dUK8GM .icon-shape p,#mermaid-svg-Q1xh2t2JI0dUK8GM .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Q1xh2t2JI0dUK8GM .icon-shape .label rect,#mermaid-svg-Q1xh2t2JI0dUK8GM .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q1xh2t2JI0dUK8GM .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Q1xh2t2JI0dUK8GM .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Q1xh2t2JI0dUK8GM :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 报告模式(Report)
事件持续产生
Client 一次订阅
Server 监视触发条件
满足条件时推送 Report
(仅含变化的数据)
轮询模式(Polling)
Client 周期发起 Read
Server 返回全部数据
(含大量未变化值)
Client 过滤变化
1.1.3 Report 在服务映射中的位置
Report 是 ACSI(Abstract Communication Service Interface,IEC 61850-7-2)定义的抽象服务,通过 SCSM(Specific Communication Service Mapping,IEC 61850-8-1)映射到 MMS 的 informationReport 服务:
ACSI 层(IEC 61850-7-2)
└─ Report 服务(抽象定义)
↓ SCSM 映射
MMS 层(IEC 61850-8-1)
└─ informationReport 服务
↓ BER 编码
MMS PDU(ConfirmedRequestPDU,opcode = informationReport)
关键区别 :普通的
Read/Write是 Client 发起的请求-响应模式;而informationReport是 Server 主动发起的,Client 不需要为每条报告单独发请求。这是 Report 能实现"推送"语义的根本所在。
1.1.4 轮询 vs Report 的量化对比
以一个监控 200 个数据点的场景为例,假设事件发生频率为 1 次/秒:
| 指标 | 轮询(T=1s) | Report(事件触发) |
|---|---|---|
| 事件平均感知延迟 | 500ms | < 50ms(含 bufTime) |
| 每秒报文数(Client↔Server) | 2(1 请求 + 1 响应) | 1(仅推送) |
| 每秒有效数据负载 | 200 点 × 全量编码 | 1 点 × 增量编码 |
| Server CPU 占用 | 高(持续处理 Read) | 低(仅事件时编码) |
| 网络带宽占用 | 高(固定) | 低(按需) |
结论:在事件驱动的监控场景中,Report 在延迟、带宽、负载三个维度全面优于轮询。轮询仅适合"必须周期获取全量快照"的少数场景(如完整性校验),而 Report 是主力机制。
1.2 报告控制块(RCB)属性全集
Report 机制的核心管理对象是报告控制块(Report Control Block, RCB)。RCB 是一个特殊的逻辑节点对象,承载了 Report 行为的全部可配置参数。Client 通过读写 RCB 的属性来订阅、配置、控制报告流。
1.2.1 RCB 的两类实例:BRCB 与 URCB
IEC 61850 定义了两类 RCB,对应两种报告语义:
| 类型 | 全称 | FC | 命名前缀 | 缓冲语义 | 典型场景 |
|---|---|---|---|---|---|
| BRCB | Buffered Report Control Block | BR |
BR |
事件入缓冲区,ACK 前保留,断线可补发 | 保护事件、告警(不可丢失) |
| URCB | Unbuffered Report Control Block | RP |
RP |
不缓冲,发送即丢弃,断线丢失 | 测量值周期上报(可容忍丢包) |
命名规则:RCB 挂载在 LD 的 LLN0 下,ObjectReference 格式为:
- URCB:
LD/LLN0.RP.<name>(如PROT/LLN0.RP.urcbStat)- BRCB:
LD/LLN0.BR.<name>(如PROT/LLN0.BR.brcbTrip)注意 FC 与命名前缀的对应:URCB 用
RP,BRCB 用BR。这是区分两类 RCB 的关键标识。
1.2.2 RCB 属性速查表
下表汇总了 IEC 61850-7-2 定义、IEC 61850-8-1 映射的 RCB 全部属性。标注 M 表示该类 RCB 必须支持,--- 表示不适用。
| 属性 | 全称 | BRCB | URCB | 含义 | 数据类型 |
|---|---|---|---|---|---|
| RptID | Report Identifier | M | M | 报告标识,区分不同报告流 | VisibleString |
| RptEna | Report Enable | M | M | 使能标志,true=开始上报 | BOOLEAN |
| Resv | Reserved | M | M | 保留标志,客户端独占 | BOOLEAN |
| DatSet | DataSet Reference | M | M | 关联的数据集引用 | ObjectReference |
| ConfRev | Configuration Revision | M | M | 配置版本号,DatSet 变更时递增 | INT32U |
| OptFlds | Option Fields | M | M | 报告包含的可选字段位图 | PACKED LIST |
| BufTm | Buffer Time | M | --- | 缓冲聚合时间(ms) | INT32U |
| SqNum | Sequence Number | M | M | 序列号 | INT8U/INT16U |
| TrgOps | Trigger Options | M | M | 触发条件位图 | PACKED LIST |
| IntgPd | Integrity Period | M | M | 完整性周期(ms) | INT32U |
| GI | General Interrogation | M | M | 总召唤标志 | BOOLEAN |
| PurgeBuf | Purge Buffer | M | --- | 清除缓冲区 | BOOLEAN |
| EntryID | Entry Identifier | M | --- | 缓冲区条目标识 | OCTET STRING |
| TimeofEntry | Time of Entry | M | --- | 条目入缓冲区时间 | UtcTime |
| Owner | Owner | --- | M | 当前占用者标识 | OCTET STRING |
1.2.3 BRCB vs URCB 属性差异图
#mermaid-svg-j0KSVM3bfijQTn2H{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-j0KSVM3bfijQTn2H .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-j0KSVM3bfijQTn2H .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-j0KSVM3bfijQTn2H .error-icon{fill:#552222;}#mermaid-svg-j0KSVM3bfijQTn2H .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-j0KSVM3bfijQTn2H .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-j0KSVM3bfijQTn2H .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-j0KSVM3bfijQTn2H .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-j0KSVM3bfijQTn2H .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-j0KSVM3bfijQTn2H .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-j0KSVM3bfijQTn2H .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-j0KSVM3bfijQTn2H .marker{fill:#333333;stroke:#333333;}#mermaid-svg-j0KSVM3bfijQTn2H .marker.cross{stroke:#333333;}#mermaid-svg-j0KSVM3bfijQTn2H svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-j0KSVM3bfijQTn2H p{margin:0;}#mermaid-svg-j0KSVM3bfijQTn2H .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-j0KSVM3bfijQTn2H .cluster-label text{fill:#333;}#mermaid-svg-j0KSVM3bfijQTn2H .cluster-label span{color:#333;}#mermaid-svg-j0KSVM3bfijQTn2H .cluster-label span p{background-color:transparent;}#mermaid-svg-j0KSVM3bfijQTn2H .label text,#mermaid-svg-j0KSVM3bfijQTn2H span{fill:#333;color:#333;}#mermaid-svg-j0KSVM3bfijQTn2H .node rect,#mermaid-svg-j0KSVM3bfijQTn2H .node circle,#mermaid-svg-j0KSVM3bfijQTn2H .node ellipse,#mermaid-svg-j0KSVM3bfijQTn2H .node polygon,#mermaid-svg-j0KSVM3bfijQTn2H .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-j0KSVM3bfijQTn2H .rough-node .label text,#mermaid-svg-j0KSVM3bfijQTn2H .node .label text,#mermaid-svg-j0KSVM3bfijQTn2H .image-shape .label,#mermaid-svg-j0KSVM3bfijQTn2H .icon-shape .label{text-anchor:middle;}#mermaid-svg-j0KSVM3bfijQTn2H .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-j0KSVM3bfijQTn2H .rough-node .label,#mermaid-svg-j0KSVM3bfijQTn2H .node .label,#mermaid-svg-j0KSVM3bfijQTn2H .image-shape .label,#mermaid-svg-j0KSVM3bfijQTn2H .icon-shape .label{text-align:center;}#mermaid-svg-j0KSVM3bfijQTn2H .node.clickable{cursor:pointer;}#mermaid-svg-j0KSVM3bfijQTn2H .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-j0KSVM3bfijQTn2H .arrowheadPath{fill:#333333;}#mermaid-svg-j0KSVM3bfijQTn2H .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-j0KSVM3bfijQTn2H .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-j0KSVM3bfijQTn2H .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j0KSVM3bfijQTn2H .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-j0KSVM3bfijQTn2H .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j0KSVM3bfijQTn2H .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-j0KSVM3bfijQTn2H .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-j0KSVM3bfijQTn2H .cluster text{fill:#333;}#mermaid-svg-j0KSVM3bfijQTn2H .cluster span{color:#333;}#mermaid-svg-j0KSVM3bfijQTn2H div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-j0KSVM3bfijQTn2H .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-j0KSVM3bfijQTn2H rect.text{fill:none;stroke-width:0;}#mermaid-svg-j0KSVM3bfijQTn2H .icon-shape,#mermaid-svg-j0KSVM3bfijQTn2H .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j0KSVM3bfijQTn2H .icon-shape p,#mermaid-svg-j0KSVM3bfijQTn2H .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-j0KSVM3bfijQTn2H .icon-shape .label rect,#mermaid-svg-j0KSVM3bfijQTn2H .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j0KSVM3bfijQTn2H .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-j0KSVM3bfijQTn2H .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-j0KSVM3bfijQTn2H :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} URCB 独有(独占语义)
Owner
当前占用者标识
BRCB 独有(缓冲语义)
BufTm
缓冲聚合时间
PurgeBuf
清除缓冲区
EntryID
条目标识
TimeofEntry
入缓冲时间
共有属性(BRCB + URCB)
RptID / RptEna / Resv
DatSet / ConfRev / OptFlds
SqNum / TrgOps / IntgPd / GI
1.2.4 关键属性语义详解
RptID(报告标识)
- 字符串类型,用于在 Client 端区分来自不同 RCB 的报告流。
- 典型取值为 RCB 的 ObjectReference(如
PROT/LLN0.BR.brcbTrip),但标准不强制。 - 一个 Client 可同时订阅多个 RCB,回调中靠
RptID分发。
RptEna(使能标志)
false(默认):RCB 处于禁用态,不产生任何报告。true:RCB 使能,开始监视触发条件并上报。- Client 订阅的核心动作就是
Write RptEna = true;取消订阅则Write RptEna = false。
Resv(保留标志)
- 用于实现 Client 独占。
Resv = true表示该 RCB 被某个 Client 保留,其他 Client 修改其属性会被拒绝。 - BRCB 中
Resv控制配置修改权;URCB 中Resv与Owner共同实现独占。
DatSet(数据集引用)
- 指向 RCB 关联的 DataSet(数据集)。Report 上报的内容就是 DatSet 成员的值。
- 引用格式:
LD/LLN0.dsName(如PROT/LLN0.dsTrip)。 - DatSet 变更(成员增删、顺序变化)会导致
ConfRev递增。
ConfRev(配置版本)
- 32 位无符号整数。每当 DatSet 成员发生变化时,Server 自动将
ConfRev加 1。 - Client 收到报告时应检查
ConfRev是否与订阅时一致,不一致说明配置已变更,需重新订阅。 - 详见 §1.6。
OptFlds(可选字段)
- 位图类型,控制 Report 报文中包含哪些可选字段(sqNum、timeStamp、reasonForInclusion 等)。
- 详见 §1.4。
BufTm(缓冲时间)
- 仅 BRCB 有。单位毫秒。
- 作用:事件触发后不立即发送,而是在
BufTm时间窗口内聚合多个事件,窗口结束时一并发送。 - 设计意图:高频事件场景下减少报文数量。例如断路器分合过程中位置抖动,
BufTm可聚合为单条报告。 - 取
0表示不聚合,事件立即发送。
SqNum(序列号)
- 报告的顺序编号,用于 Client 检测丢包与乱序。
- BRCB:SqNum 在缓冲区内严格递增,Client ACK 后 Server 可清理对应条目。
- URCB:SqNum 每条报告独立递增,无 ACK 机制。
- 标准允许 INT8U(0-255)或 INT16U(0-65535),由实现决定。溢出后回绕到 0。
TrgOps(触发条件)
- 位图类型,定义哪些条件触发报告。详见 §1.3。
IntgPd(完整性周期)
- 单位毫秒。周期性全量上报 DatSet 所有成员当前值,与触发条件独立。
- 取
0表示禁用完整性周期。 - 典型值:测量值场景 1000-5000ms,状态量场景 60000ms。
GI(总召唤)
- 布尔标志。Client 写
GI = true触发一次性的全量上报(DatSet 全部成员当前值)。 - 与
IntgPd的区别:GI是一次性手动触发,IntgPd是周期性自动触发。 - GI 触发的报告中,所有成员的 reason-for-inclusion 都标记为"integrity"。
PurgeBuf(清除缓冲区)
- 仅 BRCB 有 。Client 写
PurgeBuf = true清空缓冲区中尚未发送/未 ACK 的条目。 - 使用场景:Client 重连后不想要历史积压事件,主动清空。
- 风险:清空后缓冲区内的事件永久丢失,需谨慎使用。
EntryID(条目标识)
- 仅 BRCB 有。8 字节 OCTET STRING,唯一标识缓冲区中的每个条目。
- 核心用途:Client 断线重连后,基于最后收到的
EntryID请求 Server 从该点续传。 - 详见 §1.5。
TimeofEntry(入缓冲时间)
- 仅 BRCB 有。事件入缓冲区的 UTC 时间戳,精度到毫秒。
- 与报告发送时间不同:事件可能在缓冲区中等待一段时间(受 BufTm 或网络断开影响)才被发送。
Owner(占用者)
- 仅 URCB 有。OCTET STRING,记录当前独占该 URCB 的 Client 标识(通常是 Client 的 IP + 端口或会话 ID)。
- URCB 是单订阅者模型,同一时刻只能有一个 Client 持有 Owner。
- BRCB 支持多订阅者,故无 Owner 属性。
1.3 触发模型深度解析
触发模型决定了"什么情况下 Server 会产生一条报告"。IEC 61850-7-2 §14.5 定义了四种触发条件,它们之间是逻辑或关系:任一条件满足即触发。
1.3.1 四种触发条件
| 触发条件 | 名称 | 控制位 | 语义 | 典型场景 |
|---|---|---|---|---|
| dchg | Data Change | TrgOps.dchg |
数据值发生变化 | 断路器位置变化、保护动作 |
| qchg | Quality Change | TrgOps.qchg |
数据品质位变化 | 数据从 good 变 invalid |
| dupd | Data Update | TrgOps.dupd |
数据被更新(值可能未变) | 周期性状态刷新、设定值写入 |
| IntgPd | Integrity | IntgPd > 0 |
周期性全量上报 | 测量值定期刷新、心跳监视 |
注意 :前三种(dchg/qchg/dupd)由
TrgOps位图控制,是事件触发的;第四种(IntgPd)由IntgPd属性的值控制(非零即启用),是周期触发的,与TrgOps位图独立。
1.3.2 TrgOps 位图编码
TrgOps 是一个位图(BIT STRING),标准定义的位如下:
| Bit | 名称 | 含义 |
|---|---|---|
| bit 0 | reserved | 保留 |
| bit 1 | dchg | 数据变化触发 |
| bit 2 | qchg | 品质变化触发 |
| bit 3 | dupd | 数据更新触发 |
| bit 4 | period | 完整性周期触发(对应 IntgPd) |
常见组合:
dchg + qchg(0b00110 = 6):保护事件、状态变化(最常用)dchg + qchg + dupd(0b01110 = 14):故障录波、全量捕获period(0b10000 = 16):纯周期上报,无事件触发dchg + qchg + period(0b10110 = 22):事件 + 周期心跳(推荐配置)
陷阱 :TrgOps.period与IntgPd的关系容易混淆。period位控制"是否启用完整性周期上报",而IntgPd的值决定"周期多长"。两者必须同时配置才生效:period=true且IntgPd > 0。若只设IntgPd而period=false,不会产生周期报告。
1.3.3 触发决策流程
当 Server 端某个 DA 的值或品质发生变化时,触发决策流程如下:
#mermaid-svg-5kKFGrzXVQSTMEBO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5kKFGrzXVQSTMEBO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5kKFGrzXVQSTMEBO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5kKFGrzXVQSTMEBO .error-icon{fill:#552222;}#mermaid-svg-5kKFGrzXVQSTMEBO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5kKFGrzXVQSTMEBO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5kKFGrzXVQSTMEBO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5kKFGrzXVQSTMEBO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5kKFGrzXVQSTMEBO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5kKFGrzXVQSTMEBO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5kKFGrzXVQSTMEBO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5kKFGrzXVQSTMEBO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5kKFGrzXVQSTMEBO .marker.cross{stroke:#333333;}#mermaid-svg-5kKFGrzXVQSTMEBO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5kKFGrzXVQSTMEBO p{margin:0;}#mermaid-svg-5kKFGrzXVQSTMEBO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5kKFGrzXVQSTMEBO .cluster-label text{fill:#333;}#mermaid-svg-5kKFGrzXVQSTMEBO .cluster-label span{color:#333;}#mermaid-svg-5kKFGrzXVQSTMEBO .cluster-label span p{background-color:transparent;}#mermaid-svg-5kKFGrzXVQSTMEBO .label text,#mermaid-svg-5kKFGrzXVQSTMEBO span{fill:#333;color:#333;}#mermaid-svg-5kKFGrzXVQSTMEBO .node rect,#mermaid-svg-5kKFGrzXVQSTMEBO .node circle,#mermaid-svg-5kKFGrzXVQSTMEBO .node ellipse,#mermaid-svg-5kKFGrzXVQSTMEBO .node polygon,#mermaid-svg-5kKFGrzXVQSTMEBO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5kKFGrzXVQSTMEBO .rough-node .label text,#mermaid-svg-5kKFGrzXVQSTMEBO .node .label text,#mermaid-svg-5kKFGrzXVQSTMEBO .image-shape .label,#mermaid-svg-5kKFGrzXVQSTMEBO .icon-shape .label{text-anchor:middle;}#mermaid-svg-5kKFGrzXVQSTMEBO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5kKFGrzXVQSTMEBO .rough-node .label,#mermaid-svg-5kKFGrzXVQSTMEBO .node .label,#mermaid-svg-5kKFGrzXVQSTMEBO .image-shape .label,#mermaid-svg-5kKFGrzXVQSTMEBO .icon-shape .label{text-align:center;}#mermaid-svg-5kKFGrzXVQSTMEBO .node.clickable{cursor:pointer;}#mermaid-svg-5kKFGrzXVQSTMEBO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5kKFGrzXVQSTMEBO .arrowheadPath{fill:#333333;}#mermaid-svg-5kKFGrzXVQSTMEBO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5kKFGrzXVQSTMEBO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5kKFGrzXVQSTMEBO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5kKFGrzXVQSTMEBO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5kKFGrzXVQSTMEBO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5kKFGrzXVQSTMEBO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5kKFGrzXVQSTMEBO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5kKFGrzXVQSTMEBO .cluster text{fill:#333;}#mermaid-svg-5kKFGrzXVQSTMEBO .cluster span{color:#333;}#mermaid-svg-5kKFGrzXVQSTMEBO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5kKFGrzXVQSTMEBO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5kKFGrzXVQSTMEBO rect.text{fill:none;stroke-width:0;}#mermaid-svg-5kKFGrzXVQSTMEBO .icon-shape,#mermaid-svg-5kKFGrzXVQSTMEBO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5kKFGrzXVQSTMEBO .icon-shape p,#mermaid-svg-5kKFGrzXVQSTMEBO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5kKFGrzXVQSTMEBO .icon-shape .label rect,#mermaid-svg-5kKFGrzXVQSTMEBO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5kKFGrzXVQSTMEBO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5kKFGrzXVQSTMEBO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5kKFGrzXVQSTMEBO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否
是
否
是
是
否
DA 值/品质发生变化
RCB 是否使能?
RptEna == true
变化类型是否匹配
TrgOps 位图?
是 BRCB 且
BufTm > 0?
加入当前 BufTm 窗口
等待聚合
事件入缓冲区
分配 EntryID + SqNum
立即构造并发送 Report
BufTm 到期时
聚合发送 Report
丢弃,不触发
1.3.4 GI(总召唤)
GI 是一种特殊的触发方式,由 Client 主动发起:
- Client 写
RCB.GI = true。 - Server 收到后,立即构造一条报告,包含 DatSet 全部成员的当前值。
- GI 报告中所有成员的 reason-for-inclusion 标记为"integrity"(与 IntgPd 触发的报告相同)。
- GI 是一次性的,写一次触发一条报告;不会持续。
典型应用:Client 上线后立即调用 GI,获取 IED 当前全量状态,之后依赖事件触发接收增量变化。
1.3.5 dchg 与 dupd 的微妙区别
dchg 和 dupd 都涉及"数据变化",但语义不同,容易混淆:
| 对比项 | dchg(Data Change) | dupd(Data Update) |
|---|---|---|
| 触发条件 | 值实际发生变化 | 值被写入/更新(无论是否变化) |
| 默认触发位 | 离散量(BOOLEAN/ENUM)默认 dchg | 模拟量(MV/ASG)默认 dupd |
| 典型 CDC | SPC/DPC/ENC/ACT | MV/ASG/WYE |
| 应用场景 | 开关变位、保护动作 | 设定值修改、测量值刷新 |
CDC 与默认触发位的对应关系(IEC 61850-7-3):
| CDC 类别 | 默认 dchg | 默认 qchg | 默认 dupd |
|---|---|---|---|
| SPC(单点控制) | ✓ | ✓ | --- |
| DPC(双点控制) | ✓ | ✓ | --- |
| ENC(枚举控制) | ✓ | ✓ | --- |
| ACT(保护动作) | ✓ | ✓ | --- |
| MV(测量值) | --- | ✓ | ✓ |
| ASG(模拟设定) | --- | --- | ✓ |
| WYE(三相量) | --- | ✓ | ✓ |
实践建议:
- 状态量(开关、保护动作)用
dchg,确保只在真正变位时上报。- 模拟量(测量值、设定值)用
dupd,因为模拟量"变化"的判定需要死区,而dupd不做值比较,每次更新都触发。若需死区控制,应在 DA 的db(deadband)属性或 Server 端逻辑中实现。qchg几乎总是应该启用,因为品质变化(如通信中断导致 invalid)是重要的运维信号。
1.4 OptFlds(可选字段)详解
Report 报文的结构分为"必选部分"和"可选部分"。必选部分包括 RptID、DatSet 引用、Inclusion-bitstring、listOfAccessResult;可选部分由 OptFlds 位图控制。Client 可根据应用需求选择包含哪些可选字段。
1.4.1 OptFlds 位图定义
| Bit | 字段 | 含义 | 报文体积影响 |
|---|---|---|---|
| 0 | sqNum | 序列号 | +1~2 字节 |
| 1 | timeStamp | 报告时间戳 | +8 字节(UTCTime) |
| 2 | reasonForInclusion | 每个成员的触发原因 | +N 字节(N=成员数) |
| 3 | dataSetName | 数据集名称 | +10~30 字节 |
| 4 | dataRef | 每个成员的对象引用 | +N×20 字节 |
| 5 | bufferOverflow | 缓冲区溢出标志 | +1 字节 |
| 6 | entryID | 缓冲区条目标识 | +8 字节 |
| 7 | confRev | 配置版本号 | +4 字节 |
1.4.2 OptFlds 组合场景表
不同应用场景对报告内容的需求不同,推荐配置如下:
| 应用场景 | 推荐 OptFlds | 理由 |
|---|---|---|
| 监控后台 | sqNum + timeStamp + dataRef + dataSetName | 需要时间戳和对象引用用于画面刷新,dataRef 帮助定位数据点 |
| 事件记录系统 | sqNum + timeStamp + reasonForInclusion + entryID | 需要触发原因用于事件分类,entryID 用于断线续传 |
| 故障录波 | 全字段 | 录波需要完整上下文,不吝啬带宽 |
| 网关转发 | sqNum + timeStamp + reasonCode | 转发到其他协议(如 IEC 104)需要触发原因做映射 |
| 轻量遥测 | sqNum + timeStamp | 仅需值和时间,最小化报文 |
1.4.3 OptFlds 对报文体积的影响估算
以一个 20 成员的 DatSet 为例,估算不同 OptFlds 配置下的报告体积:
| OptFlds 配置 | 固定开销 | 每成员开销 | 20 成员总开销 | 估算总字节数 |
|---|---|---|---|---|
| 最小(无可选字段) | ~30B | ~10B | 200B | ~230B |
| sqNum + timeStamp | ~38B | ~10B | 200B | ~238B |
| + dataRef | ~38B | ~30B | 600B | ~638B |
| + reasonForInclusion | ~38B | ~32B | 640B | ~678B |
| 全字段 | ~50B | ~35B | 700B | ~750B |
结论 :
dataRef是体积增长的主要因素(每成员增加约 20 字节的对象引用字符串)。对于大 DatSet(>50 成员),应谨慎启用dataRef,可改用dataSetName+ 成员索引的方式在 Client 端还原引用。
1.5 缓冲报告的状态机
BRCB 的核心价值在于缓冲区机制:事件入缓冲区后,即使 Client 暂时断开,事件也不会丢失,网络恢复后可补发。理解缓冲区的状态机是掌握 BRCB 的关键。
1.5.1 BRCB 缓冲区生命周期
#mermaid-svg-aPfNQ933TSuZBWyt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aPfNQ933TSuZBWyt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aPfNQ933TSuZBWyt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aPfNQ933TSuZBWyt .error-icon{fill:#552222;}#mermaid-svg-aPfNQ933TSuZBWyt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aPfNQ933TSuZBWyt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aPfNQ933TSuZBWyt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aPfNQ933TSuZBWyt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aPfNQ933TSuZBWyt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aPfNQ933TSuZBWyt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aPfNQ933TSuZBWyt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aPfNQ933TSuZBWyt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aPfNQ933TSuZBWyt .marker.cross{stroke:#333333;}#mermaid-svg-aPfNQ933TSuZBWyt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aPfNQ933TSuZBWyt p{margin:0;}#mermaid-svg-aPfNQ933TSuZBWyt defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-aPfNQ933TSuZBWyt g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-aPfNQ933TSuZBWyt g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-aPfNQ933TSuZBWyt g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-aPfNQ933TSuZBWyt g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-aPfNQ933TSuZBWyt g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-aPfNQ933TSuZBWyt .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-aPfNQ933TSuZBWyt .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-aPfNQ933TSuZBWyt .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-aPfNQ933TSuZBWyt .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-aPfNQ933TSuZBWyt .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-aPfNQ933TSuZBWyt .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-aPfNQ933TSuZBWyt .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-aPfNQ933TSuZBWyt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aPfNQ933TSuZBWyt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aPfNQ933TSuZBWyt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aPfNQ933TSuZBWyt .edgeLabel .label text{fill:#333;}#mermaid-svg-aPfNQ933TSuZBWyt .label div .edgeLabel{color:#333;}#mermaid-svg-aPfNQ933TSuZBWyt .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-aPfNQ933TSuZBWyt .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-aPfNQ933TSuZBWyt .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-aPfNQ933TSuZBWyt .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-aPfNQ933TSuZBWyt .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-aPfNQ933TSuZBWyt .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aPfNQ933TSuZBWyt .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aPfNQ933TSuZBWyt #statediagram-barbEnd{fill:#333333;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aPfNQ933TSuZBWyt .cluster-label,#mermaid-svg-aPfNQ933TSuZBWyt .nodeLabel{color:#131300;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-aPfNQ933TSuZBWyt .note-edge{stroke-dasharray:5;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-note text{fill:black;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram-note .nodeLabel{color:black;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagram .edgeLabel{color:red;}#mermaid-svg-aPfNQ933TSuZBWyt #dependencyStart,#mermaid-svg-aPfNQ933TSuZBWyt #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-aPfNQ933TSuZBWyt .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aPfNQ933TSuZBWyt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} RptEna = false
Client 写 RptEna = true
Client 写 RptEna = false
禁用态
使能态
事件触发
BufTm 到期 或 立即发送
报告已发送
收到 Client ACK
新事件到达(未 ACK 的保留)
缓冲区满
空闲
缓冲中
发送中
等待ACK
溢出
覆盖最旧条目
设置_bufOvfl_标志
1.5.2 状态详解
禁用态(RptEna = false)
- RCB 不监视任何触发条件,不产生报告。
- 缓冲区为空(若之前有数据,使能时是否清空取决于实现,标准未强制)。
- Client 通过
Write RptEna = true切换到使能态。
使能态 - 空闲
- RCB 正在监视触发条件,但缓冲区中无待发送事件。
- IntgPd 计时器运行中,到期时触发完整性报告。
使能态 - 缓冲中
- 事件已入缓冲区,分配了 EntryID 和 SqNum。
- 若
BufTm > 0,等待 BufTm 窗口聚合更多事件。 - 若
BufTm = 0,立即转入发送中。
使能态 - 发送中
- Server 构造 Report 报文并通过 MMS
informationReport发送。 - 报告发送后,条目仍保留在缓冲区,等待 Client ACK。
使能态 - 等待ACK
- 报告已发送,等待 Client 的确认。
- Client 通过写
RCB.AckRcv(或等价机制)确认已收到的 SqNum。 - 收到 ACK 后,Server 可清理缓冲区中 SqNum ≤ ACK 值的条目。
溢出
- 缓冲区容量达到上限(由实现决定,libiec61850 默认 100 条,可编译期调整)。
- 行为:覆盖最旧的未 ACK 条目,并设置
bufOvfl标志。 - 后续报告中
OptFlds.bufferOverflow = true,通知 Client 发生过溢出。
1.5.3 SqNum 的循环与溢出处理
SqNum 的取值范围由实现决定:
- INT8U(0-255):适用于低频事件场景,缓冲区容量通常 ≤ 256。
- INT16U(0-65535):适用于高频事件场景,缓冲区容量可更大。
SqNum 递增到上限后回绕到 0:
SqNum 序列:... 253 → 254 → 255 → 0 → 1 → 2 ...
Client 端处理:检测 SqNum 连续性时需考虑回绕。例如收到 255 后期望 0,若收到 1 则说明丢失了 0 号报告。推荐的检测算法:
expected = (last_sqnum + 1) % MAX_SQNUM if received_sqnum != expected: gap = (received_sqnum - expected + MAX_SQNUM) % MAX_SQNUM 报告丢失 gap 个报告
1.5.4 EntryID 与断线续传
EntryID 是 BRCB 缓冲区中每个条目的唯一标识(8 字节 OCTET STRING)。它的核心价值在于支持断线续传:
- Client 订阅 BRCB,正常接收报告,记录每条报告的
EntryID。 - 网络断开,Client 与 Server 失去连接。
- Server 端事件继续产生,入缓冲区(缓冲区未满则保留)。
- 网络恢复,Client 重连。
- Client 写
RCB.EntryID = <最后收到的 EntryID>,请求 Server 从该点之后补发。 - Server 查找缓冲区,将 EntryID 之后的所有条目依次补发给 Client。
Server (BRCB) Client Server (BRCB) Client #mermaid-svg-qtL31ZoSfcYeiNT7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qtL31ZoSfcYeiNT7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qtL31ZoSfcYeiNT7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qtL31ZoSfcYeiNT7 .error-icon{fill:#552222;}#mermaid-svg-qtL31ZoSfcYeiNT7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qtL31ZoSfcYeiNT7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qtL31ZoSfcYeiNT7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qtL31ZoSfcYeiNT7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qtL31ZoSfcYeiNT7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qtL31ZoSfcYeiNT7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qtL31ZoSfcYeiNT7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qtL31ZoSfcYeiNT7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qtL31ZoSfcYeiNT7 .marker.cross{stroke:#333333;}#mermaid-svg-qtL31ZoSfcYeiNT7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qtL31ZoSfcYeiNT7 p{margin:0;}#mermaid-svg-qtL31ZoSfcYeiNT7 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qtL31ZoSfcYeiNT7 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-qtL31ZoSfcYeiNT7 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qtL31ZoSfcYeiNT7 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-qtL31ZoSfcYeiNT7 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-qtL31ZoSfcYeiNT7 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-qtL31ZoSfcYeiNT7 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-qtL31ZoSfcYeiNT7 .sequenceNumber{fill:white;}#mermaid-svg-qtL31ZoSfcYeiNT7 #sequencenumber{fill:#333;}#mermaid-svg-qtL31ZoSfcYeiNT7 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-qtL31ZoSfcYeiNT7 .messageText{fill:#333;stroke:none;}#mermaid-svg-qtL31ZoSfcYeiNT7 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qtL31ZoSfcYeiNT7 .labelText,#mermaid-svg-qtL31ZoSfcYeiNT7 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-qtL31ZoSfcYeiNT7 .loopText,#mermaid-svg-qtL31ZoSfcYeiNT7 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-qtL31ZoSfcYeiNT7 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-qtL31ZoSfcYeiNT7 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-qtL31ZoSfcYeiNT7 .noteText,#mermaid-svg-qtL31ZoSfcYeiNT7 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-qtL31ZoSfcYeiNT7 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qtL31ZoSfcYeiNT7 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qtL31ZoSfcYeiNT7 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-qtL31ZoSfcYeiNT7 .actorPopupMenu{position:absolute;}#mermaid-svg-qtL31ZoSfcYeiNT7 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-qtL31ZoSfcYeiNT7 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-qtL31ZoSfcYeiNT7 .actor-man circle,#mermaid-svg-qtL31ZoSfcYeiNT7 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-qtL31ZoSfcYeiNT7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 正常订阅阶段 记录最后 EntryID=0x02 网络断开 事件继续入缓冲区EntryID=0x03, 0x04, 0x05 网络恢复 完整收到所有积压事件 Write RptEna = trueReport (EntryID=0x01, SqNum=1)Report (EntryID=0x02, SqNum=2)Write RptEna = true(重新使能)Write EntryID = 0x02(请求续传点)Report (EntryID=0x03, SqNum=3)Report (EntryID=0x04, SqNum=4)Report (EntryID=0x05, SqNum=5)
关键点:EntryID 续传依赖缓冲区中条目未被覆盖。若断线期间事件过多导致缓冲区溢出,最旧的条目会被覆盖,此时 Client 请求的 EntryID 可能已不存在,Server 会返回错误或从当前最旧条目开始补发(具体行为由实现决定)。
1.5.5 PurgeBuf 的使用场景与风险
PurgeBuf(仅 BRCB)用于主动清空缓冲区:
- 使用场景 :
- Client 重连后不关心历史积压事件,只要实时数据 → 清空后重新开始。
- 测试场景下重置缓冲区状态。
- 风险 :
- 清空操作不可逆,缓冲区内所有未发送/未 ACK 的事件永久丢失。
- 若多个 Client 订阅同一 BRCB,PurgeBuf 会影响所有订阅者。
- 建议:生产环境慎用,仅在明确不需要历史数据时使用。更安全的做法是基于 EntryID 续传。
1.5.6 缓冲区溢出(BufferOverflow)
当事件产生速率超过 Client ACK 速率,或缓冲区过小时,会发生溢出。溢出的语义与处理:
- 溢出行为:环形缓冲区覆盖最旧的未 ACK 条目,新事件继续入队。
- 标志通知 :溢出发生后,下一条报告的
OptFlds.bufferOverflow位置 1(前提是 OptFlds 中启用了该位)。 - Client 感知 :Client 收到
bufOvfl = true的报告时,应:- 记录溢出事件,产生告警。
- 检查 SqNum 跳变,估算丢失的报告数量。
- 决定是否触发 GI 重新获取全量状态(弥补丢失数据)。
- 评估是否需要增大缓冲区或拆分高频数据到独立 RCB。
预防措施:
- 高频事件(如测量值抖动)不应与低频关键事件(如保护跳闸)共用同一 BRCB,否则高频事件可能挤占缓冲区导致关键事件被覆盖。
- 监控 ACK 延迟,确保 Client 处理报告的速度跟得上 Server 产生事件的速度。
1.6 ConfRev(配置版本)机制
1.6.1 为什么需要 ConfRev
ConfRev(Configuration Revision)是 RCB 的配置版本号,用于解决"DatSet 变更导致 Client 误读"的问题。
考虑以下场景:
- Client 订阅了
brcbTrip,关联dsTrip(成员:PTOC1.Op.general、XCBR1.Pos.stVal)。 - Client 在本地维护了"Inclusion-bitstring 第 0 位 = PTOC1.Op.general,第 1 位 = XCBR1.Pos.stVal"的映射。
- 运维人员修改 SCL,在
dsTrip头部插入了一个新成员PTOC1.Str.general。 - 现在 Inclusion-bitstring 的第 0 位变成了
PTOC1.Str.general,第 1 位变成了PTOC1.Op.general。 - 若 Client 不感知此变更,仍按旧映射解读,就会把保护启动信号误认为跳闸信号------严重的安全事故。
ConfRev 就是为防止这类问题而设计的:每次 DatSet 成员变更,ConfRev 递增,Client 检测到变化后强制重新同步配置。
1.6.2 ConfRev 递增规则
Server 在以下情况下将 ConfRev 加 1:
| 变更类型 | ConfRev 是否递增 | 说明 |
|---|---|---|
| DatSet 增加成员 | ✓ | 成员列表变化 |
| DatSet 删除成员 | ✓ | 成员列表变化 |
| DatSet 成员顺序变化 | ✓ | Inclusion-bitstring 位映射变化 |
| DatSet 成员引用不变但值变化 | ✗ | 值变化由报告本身承载 |
| RCB 的 TrgOps/OptFlds 变化 | ✗ | 这些是 RCB 自身属性,非 DatSet 配置 |
| RCB 的 IntgPd/BufTm 变化 | ✗ | 同上 |
注意:ConfRev 只反映 DatSet 成员列表的变更,不反映 RCB 自身参数的变更。后者由 Client 主动管理(修改前需 disable,修改后 enable)。
1.6.3 Client 检测 ConfRev 变化的处理流程
#mermaid-svg-NDulo8mpR2Eltxyv{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NDulo8mpR2Eltxyv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NDulo8mpR2Eltxyv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NDulo8mpR2Eltxyv .error-icon{fill:#552222;}#mermaid-svg-NDulo8mpR2Eltxyv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NDulo8mpR2Eltxyv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NDulo8mpR2Eltxyv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NDulo8mpR2Eltxyv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NDulo8mpR2Eltxyv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NDulo8mpR2Eltxyv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NDulo8mpR2Eltxyv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NDulo8mpR2Eltxyv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NDulo8mpR2Eltxyv .marker.cross{stroke:#333333;}#mermaid-svg-NDulo8mpR2Eltxyv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NDulo8mpR2Eltxyv p{margin:0;}#mermaid-svg-NDulo8mpR2Eltxyv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-NDulo8mpR2Eltxyv .cluster-label text{fill:#333;}#mermaid-svg-NDulo8mpR2Eltxyv .cluster-label span{color:#333;}#mermaid-svg-NDulo8mpR2Eltxyv .cluster-label span p{background-color:transparent;}#mermaid-svg-NDulo8mpR2Eltxyv .label text,#mermaid-svg-NDulo8mpR2Eltxyv span{fill:#333;color:#333;}#mermaid-svg-NDulo8mpR2Eltxyv .node rect,#mermaid-svg-NDulo8mpR2Eltxyv .node circle,#mermaid-svg-NDulo8mpR2Eltxyv .node ellipse,#mermaid-svg-NDulo8mpR2Eltxyv .node polygon,#mermaid-svg-NDulo8mpR2Eltxyv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NDulo8mpR2Eltxyv .rough-node .label text,#mermaid-svg-NDulo8mpR2Eltxyv .node .label text,#mermaid-svg-NDulo8mpR2Eltxyv .image-shape .label,#mermaid-svg-NDulo8mpR2Eltxyv .icon-shape .label{text-anchor:middle;}#mermaid-svg-NDulo8mpR2Eltxyv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NDulo8mpR2Eltxyv .rough-node .label,#mermaid-svg-NDulo8mpR2Eltxyv .node .label,#mermaid-svg-NDulo8mpR2Eltxyv .image-shape .label,#mermaid-svg-NDulo8mpR2Eltxyv .icon-shape .label{text-align:center;}#mermaid-svg-NDulo8mpR2Eltxyv .node.clickable{cursor:pointer;}#mermaid-svg-NDulo8mpR2Eltxyv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NDulo8mpR2Eltxyv .arrowheadPath{fill:#333333;}#mermaid-svg-NDulo8mpR2Eltxyv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NDulo8mpR2Eltxyv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NDulo8mpR2Eltxyv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NDulo8mpR2Eltxyv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NDulo8mpR2Eltxyv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NDulo8mpR2Eltxyv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NDulo8mpR2Eltxyv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NDulo8mpR2Eltxyv .cluster text{fill:#333;}#mermaid-svg-NDulo8mpR2Eltxyv .cluster span{color:#333;}#mermaid-svg-NDulo8mpR2Eltxyv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NDulo8mpR2Eltxyv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NDulo8mpR2Eltxyv rect.text{fill:none;stroke-width:0;}#mermaid-svg-NDulo8mpR2Eltxyv .icon-shape,#mermaid-svg-NDulo8mpR2Eltxyv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NDulo8mpR2Eltxyv .icon-shape p,#mermaid-svg-NDulo8mpR2Eltxyv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NDulo8mpR2Eltxyv .icon-shape .label rect,#mermaid-svg-NDulo8mpR2Eltxyv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NDulo8mpR2Eltxyv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NDulo8mpR2Eltxyv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NDulo8mpR2Eltxyv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
Client 收到 Report
report.conf_rev ==
本地记录的 conf_rev?
正常处理报告
ConfRev 变更!
本地映射可能失效
Write RptEna = false
禁用 RCB
重新读取 DatSet 成员列表
更新本地 Inclusion-bitstring 映射
更新本地 conf_rev
Write RptEna = true
重新使能
Write GI = true
触发总召唤获取全量状态
1.6.4 ConfRev 不一致时的告警与重订阅
当 Client 检测到 ConfRev 变化时,推荐的处理流程:
- 告警:记录"RCB 配置变更"事件,通知运维人员。
- 禁用 RCB :
Write RptEna = false,停止报告流。 - 重新读取配置 :
- 读取
RCB.ConfRev获取最新版本号。 - 读取
RCB.DatSet获取关联的数据集引用。 - 调用
GetDataSetDirectory读取 DatSet 成员列表。 - 更新本地的"Inclusion-bitstring 位 ↔ 成员引用"映射表。
- 读取
- 更新本地 ConfRev:将本地记录同步为最新值。
- 重新使能 :
Write RptEna = true。 - 触发 GI :
Write GI = true,获取全量当前值,弥补配置变更期间可能遗漏的数据。
最佳实践:健壮的 Client 应在每条报告回调中检查 ConfRev,将其作为报告处理的"前置校验"。忽略 ConfRev 检查是导致现场误报/漏报的常见根因。
1.7 小结
本专题从理论层面完整剖析了 IEC 61850 Report 机制的核心------报告控制块(RCB):
- Report 的价值:以事件驱动 + 服务端推送,解决轮询模式的延迟、带宽、负载三大痛点。
- RCB 属性全集:BRCB 与 URCB 两类实例,15 个属性,理解每个属性的语义是配置与排障的基础。
- 触发模型:dchg/qchg/dupd/IntgPd 四种触发条件的或关系,TrgOps 位图编码,dchg 与 dupd 的 CDC 对应。
- OptFlds:8 个可选字段的位图控制,不同场景的推荐组合与体积估算。
- 缓冲区状态机:BRCB 的禁用/使能/缓冲/发送/等待ACK/溢出六态流转,SqNum 回绕,EntryID 断线续传,PurgeBuf 风险,溢出处理。
- ConfRev 机制:DatSet 变更的版本保护,Client 检测不一致时的重订阅流程。
下期预告
IEC 61850 报告系列(二):Report 报文逐字段剖析 将从理论走向报文:
- Report 在 MMS 协议栈中的位置与
informationReport的 ASN.1 定义 - 真实 Report 报文的十六进制逐字段标注
- Inclusion-bitstring 机制与 listOfAccessResult 的对齐
- Wireshark 抓取与分析 Report 的实战流程
- 四种触发场景的报文对比与异常报文识别
参考标准
- IEC 61850-7-2 §14: Report 服务与 RCB 属性定义
- IEC 61850-7-2 §14.5: 触发条件(TrgOps)定义
- IEC 61850-8-1: SCSM 映射到 MMS
informationReport- IEC 61850-7-3: CDC 与默认触发位的对应关系
交叉引用
- 主系列 Part 3 §3.2.5:Report 机制基础(本专题的深化基础)
- 主系列 Part 4 §4.4:ReportControl 配置(专题 3 将工程化展开)
- 专题 3:SCL 中的 ReportControl 配置------工程化设计
- 专题 4:基于 pyiec61850-ng 的代码实现