前言
前面已经介绍了报告的服务端和客户端,采用的是最直接最简单的方法,目的是让大家对报告有个基本的认识,然而报告还是有一些复杂的地方,这里会做一次详细的介绍。补充一下,报告主要用于遥信和遥测。
报告控制块(在CID中)
基本模型
属性 | 说明 |
---|---|
rptID | 报告控制块标识符,可选。如果该标识符未用,或值为空串采用默认 |
buffered | 缓存标志,为true代表缓存报告控制块,反之为非缓存 |
name | 报告控制块名称 |
bufTime | 缓存时间,单位毫秒,仅当buffered=true时有效 |
datSet | 对应的数据集名称 |
confRev | 本报告控制块配置修订版本号 |
intgPd | 完整性周期,单位毫秒,仅当触发条件period="true"时有效 |
trgOps | 报告触发项 |
OptFields | 报告选项域 |
RptEnabled | 报告使能,两个属性:max表示最大的实例数量,desc描述 |
indexed | 默认为“真”,则报告控制块实例名称按照提供的名称取名,名称编号从01 到99 |
报告选项域
属性 | 说明 |
---|---|
seqNum | 顺序编号 |
reasonCode | 原因码,代表触发的条件 |
timeStamp | 报告时标 |
bufOvfl | 缓存溢出标志,仅对于BRCB有效 |
dataSet | 数据集 |
entryID | 条目标识符,仅对于BRCB有效 |
dataRef | 数据引用 |
configRef | 配置版本 |
报告触发选项
属性 | 说明 | 默认值 |
---|---|---|
dchg | 数据变化触发 | false |
qchg | 质量变化触发 | false |
dupd | 数据更新触发 | false |
period | 完整性触发 | false |
gi | 总召唤 | true |
服务端
最简单的报告
为了清楚的认识报告,我们从最简单的报告开始,熟悉报告的机制及报文。最简单的报告首先我们采用最简单的数据集,就一个数据、关闭所有选项域,只采用完整性的周期报告。
数据集最简单
打开testIED.cid,编辑数据集
如下图这样,只选择要给基恩的整数类型即可
简单的控制块
报告控制块只设置周期性触发,选项域不设置,(设置方法前文已经距离)设置完如下:
<ReportControl name="testReportCB" buffered="false" confRev="1" datSet="testDataSet" intgPd="10000" desc="测试用的报告控制块">
<TrgOps period="true"/>
<OptFields/>
<RptEnabled max="3"/>
</ReportControl>
简单的周期性触发运行
1、继续使用之前的代码编译运行,启动服务端;
2、启动客户端工具,此次使用由大连云行开发的sim860工具(完全免费),该工具可以支持MMS和CMS的服务端及客户端,工具在https://gitee.com/yunxingtianxia/yx-tools下载;
3、如果我们启动的是MMS版本的服务端,则使用sim860-client-mms配合测试,如果是CMS版本,则使用sim860-client-cms配合测试;
4、使用sim860使能(使用sim860的mms版本和cms版的操作是相同的)
由于是周期性报告,所以使能后10秒后就会有报告发送,报文如下:
MMS报文
CMS报文
报文初步分析
无论是CMS还是MMS,最简单的报告都发送了 rptID、报告选项域、报告数据在数据集中的位置、报告数据值,这四部分是报告的必发内容,而其他内容则由报告选项域决定。
逐步放开选项域
先打开选项域中的dataSet吧,打开CID文件,在报告控制块中修改如下:
<OptFields dataSet="true"/>
重启服务端,重新使能,抓取报文
MMS报文
CMS报文
看到这里大家应该就明白了选项域的作用了,可以尝试打开其他选项域进行观察。但是需要注意的是bufOvfl 和entryID两个选项域仅对缓存报告控制块有用。
报告控制块实例都包含了哪些属性
我们把报告控制块改成缓存报告控制块再查查看
将CID中报告控制块的buffered="false"改成buffered=“true”,再重启服务端,因为模型有变化,模拟工具也需要关闭连接重连来重新获取模型
可以看到缓存报告比非缓存报告多了PurgeBuf、EntryID、TimeofEntry三个属性,而少了Resv
还有尚未看到的属性,这个取决于services的设置
勾选后保存实际文件内容如下:
<Services nameLength="64">
<ReportSettings owner="true" resvTms="true"/>
</Services>
重启服务端,工具重新获取模型
图中增加了,ResvTms和Owner,非缓存的这里就不试了。
缓存报告控制块与非缓存报告控制块共有的属性,这里无需解释了,对照模型的属性即可,下面分缓存报告控制块与非缓存报告控制块分别进行介绍特殊的属性。
非缓存报告
非缓存报告相对简单一些,从字面就可以理解报告不会进行缓存,基本原则是尽可能快的将报告送达,如果因为某些原因无法送达报告就会丢失。
特殊的属性是Resv,他是一个布尔型,1表示占用,0表示未占用。
通常使能非缓存报告控制块需要先查看Resv是否是占用状态,如果已经占用就不做使能的操作了。
如果是未占用则先发起占用再使能或者直接发起使能自动占用。
如果设置了Owner,使能后,该属性会记录使能方的IP地址。
缓存报告
从字面理解,缓存报告会将生成的报告进行缓存,从服务端启动开始,缓存的动作就开始了。当客户端使能后,服务端会立即补发缓存中的报告,所以当因为某些原因断联,待恢复后重新使能,会补发,这样报告就不会丢失。当然缓存空间有限,并不能做到绝对的不丢失。
缓存时间Buffer time
文本内容如下:
<ReportControl bufTime="5000" buffered="true" confRev="1" datSet="testDataSet" desc="测试用的报告控制块" intgPd="10000" name="testReportCB">
<TrgOps period="true"/>
<OptFields dataSet="true"/>
<RptEnabled max="3"/>
</ReportControl>
这个缓存时间是针对dchg、qchg、dupd三种触发方式,当事件发生触发报告,不会立即发送,而是等待缓存时间到达后发送,如下图,在BufTm内发生的事件会一起缓存,时间到达一起发送。还有一种情况是缓存溢出立即发送。
如果在缓存的bufTm时间内,对同一个数据触发了两次事件,那么第二次触发会立即发送bufTm内缓存的报告,并且重新开始BufTm计时;
resvTms保留时间
当缓存报告控制块实例在未使能的情况下resvTms为0,使能后则大于0,YX-PIS协议栈默认60秒,也可由客户端来Set这个值(后面会介绍如何Set),其作用就是如果使能的客户端因为某些原因,例如断网取消了使能,服务端会为该客户端保留resvTms秒,这期间其他客户端无法使能,只有该客户端可以成功使能,当超时后,任意客户端都可以使能。
报告的其他触发
数据变化触发
首先报告控制块需要设置数据变化触发
<TrgOps dchg="true" />
其次更新的数据支持数据变化触发
参考数据更新的文章,更新数据即可触发数据变化的报告。
数据更新触发
和数据变化触发的设置类似,首先控制块要设置dupd=“true”,而DA要设置data update为true,
数据更新与数据变化的区别,如果数据原值是5,调用update设置新值为6,则为数据更新和数据变化,如果设置新值为5,则仅为数据更新。
质量变化触发
于数据变化一直,首先控制块要设置qchg=“true”,而DA要设置quality change为true,通常只有q值会设置quality change为true。
indexed的作用
indexed默认为true,也就是默认报告控制块实例是报告控制块名成加上实例号的,01到99,那么如果只有一个实例,可以不用这个序号,那么就要把indexed设置为false,这种情况,报告控制块只有一个实例,实例名称等于报告控制块名称。即使设置max大于1也无效。不过这种情况很少使用,推荐不设置indexed而采用默认值true。
报告的SET操作
前面我们已经通过工具读取了报告控制块实例的属性,而这些属性也都可以进行写入操作,前面的GI写入就是一种,但是并不是所有的属性都可以写入,需要进行Services的设置,如下图,只有设置为Dyn的属性才能在客户端进行设置操作。
其他属性,例如:rptEna、entryID、ConfRev、GI、PurgeBuf、Resv、ResvTms都是无需设置,直接可Set的,只不过有些是在使能状态下可Set,有些只能在未使能状态下Set,这些可以查阅标准,或者自行实验。
总召唤
总召唤是指由客户端希望立即获取报告全部数据而发起的一次请求,请求的本质是设置报告控制块实例中gi的属性为true即可。
总召唤的前提是报告已经使能,并且发起总召唤的客户端就是使能该实例的客户端。
服务端在收到写入GI的操作后,就会立即发送完整的报告给客户端,发送完成后将GI设置为false。
或者在报告监控中发起总召唤,本质上是一样的动作。
清理缓存
和总召唤操作类似,将PurgeBuf设置为1即可,服务端就会将所有缓存清理;
指定补发缓存ID
Set操作中将EntryID设置为缓存中存在的EntryID,重新使能就会从这条开始补发,如果设置的ID不存在会不成功。
其他事项
1、如果在缓存的bufTm时间内,对同一个数据触发了两次事件,那么第二次触发会立即发送bufTm内缓存的报告,并且重新开始BufTm计时;
客户端
自动使能
前文已经介绍了自动使能的方法,但是会发现使能的是第一个实例,如果要使能第二个或往后的实例该如何设置?
首先ClientLN是由服务端预分配的,RptEnabled 元素中列表ClientLN 的 Index(位置)作为本客户端的使能编号(第一个编号为1),例如:
<RptEnabled max="3">
<ClientLN iedName="TestClientIED1" ldInst="LD0" lnClass="IHMI" lnInst="0"/>
<ClientLN iedName="TestClientIED2" ldInst="LD0" lnClass="IHMI" lnInst="0"/>
</RptEnabled>
意思是第一个实例分配各TestClientIED1,第二个实例分配个TestClientIED2,那么对于客户端而言,自身的设备名是TestClientIED2则会使能第二个实例。
上述的预分配情况在现实的项目中几乎没有实际使用的,所以对YX-PIS协议栈来说,更多的是用于客户端的设置,只放一条,这样放的位置与实际想使能的实例号很可能不符,这种情况该怎么办?
在mms-cfg目录或者cms-cfg目录下有个client.ini文件,其中有实例号的设置
[report]
instance=1 #仅针对自动使能有效
这里设置后则优先按照这个设置的实例号进行使能。
客户端报告相关API
YX-PIS提供的报告相关的接口如下:
IEC61850_GetBRCBValues
IEC61850_GetURCBValues
IEC61850_SetBRCBValues
IEC61850_SetURCBValues
IEC61850_ReportEnable
IEC61850_ReportGI
在头文件中或者API手册中均对上述接口有详细的说明,请参考。
客户端报告相关的回调
前文已经介绍了update回调,其实报告相关的报告不止这一个,有基于FCDA的回调,以及整个报告的回调,用法有一定难度这里暂不做介绍。
对于自动使能成功后也有一个回调,便于客户端你判断使能是否成功。原型如下,可以查阅手册了解使用方法。
typedef void (IEC61850_ReportAutoEnableSuccessCallback)(voiduserData,const char* rptCBReference, Boolean isBuffered);
总结
细说报告就介绍到这里,本文并不能100%介绍报告的细节,并且标准也是在不断的更新的,这里只能介绍日常项目会用到的部分,如有问题欢迎留言,感谢阅读。