OPCUA的监控项、订阅、和通知MonitoredItem
每个监控项均指明了要监控的项⽬(item)和⽤来发送通知的订阅。
item可以是⼀个节点的属性(node attribute)。
MonitorItem可以监控⼀个属性,⼀个变量或者⼀个事件
可以通过MonitorItem定义的过滤器(fiter),来决定是否产⽣⼀个通知
Queue attribute定义了可以被缓存的通知数量,可以通过配置策略决定丢弃新消息还是最⽼的消息团建活动的意义
Triggering model
MonitoredItem服务允许某item只有在关联Item被触发时才会被触发
这是通过在触发对象和被触发对象间建⽴连接来实现的
Notification
描述了数据变化和事件的数据结构,通知会被打包为NotificationMessage并传送给Client。
订阅会以客户定义的发布间隔周期性的发送NotificationMessage。
Subscription
订阅⽤来向客户端报告通知,其⾏为可以被总结如下:
订阅包含⼀组由客户端分配的监控项。监控项可以⽣成通知,这些通知,由订阅发送给客户端
订阅拥有⼀个发布间隔,订阅的发布间隔定义了订阅执⾏的循环率。每次执⾏,订阅均试图发送⼀条
NotificationMessages,NotificationMessages中包含了还没有报告给客户端的通知
订阅以回应发布请求的⽅式向客户端发送NotificationMessages。发布请求通常以接收顺序存储到Session中,当有通知需要发送时,在每次发布循环时,会从队列中取出相应的请求,并发送通知到客户端,如果没有待发送通知,请求则不会从队列中被删除
在循环的开始,如果已经存在待发送通知但还没有发布请求,服务器将会进⼊等待状态,⼀旦接收到发布请求,则⽴即向客户端发送通知,⽆需等待另外⼀次循环
订阅有⼀个存活计数器,保存了没有发送通知的周期循环次数,当循环次数达到⽤户在创建订阅时配
置的预置,则会发送⼀条存活消息到客户端,同时从队列中取出⼀条发布请求,⽤于表⽰该订阅仍然处于存活状态。存活NotificationMessage中不包含通知,但包含下⼀条消息的序列号
订阅是否发布通知可以由客户端在创建时指定,也可以后续通过SetPublishMode服务设置,设置为Fasle时,订阅将停⽌向客户端推送通知,但是订阅会继续执⾏,且持续发送存活消息
订阅包含⼀个寿命计数器,保存了在没有发布请求时经历的循环次数,当达到阈值时,会删除这个订阅以及与订阅相关的监控项。在删除订阅时,会发送⼀条StateChangeNotification消息,并携带状态码Bad_Timeout
Session维护了已发送通知的转发队列,只有当客户端确认消息接收后,才会从队列宗移除,服务器应当保存有两倍于发送请求数量的消息,这种能⼒可以由服务器的profile定义,如果转发队列满,则删除最旧的消息。当订阅被转移到另外的ssion时,转发队列同时也需要迁移过去
序列号是⼀个UINT32,并从1开始向前滚动。
当订阅创建后,在第⼀个周期结束时,会向client发送⼀条消息,⽤于通知客户端订阅可⽤。如果有通知要发送,则发送NotificationMessage,如果没有,则发送存活消息,并设置序列号为1,这是唯⼀不需要等待到keep alive阈值的场景。
客户端接受消息要⽐发布周期更加频繁,因⼀个发布周期可能包含有多条消息,但客户端可以设置服务器不缓存发布通知来减轻压⼒,但会增加响应的延时。
在订阅的声明周期中,序列号不会被重置,也即在40亿消息中不会出现重复的消息ID。
消息序列号还可以⽤于消息重发。
订阅被设计为独⽴于具体的通信协议,短暂的连接丢失不会导致丢失数据和事件。在设计时,要确保该特性得以正确实现,也即能够处理较长时间的通讯中断和有计划断链。如果服务器⽀持该特性,服务器的缓存区将会设计的⽐较⼤。
HasEventSource
HasEventSource引⽤类型是⼀个具体的引⽤类型,并可以直接被使⽤,是HierarchicalReferences的⼦类。
这个引⽤类型的语义是将event source(事件源)以⼀种层次化的、⾮循环的⽅式关联起来。该类型以及该类型的所有⼦类是打算⽤来帮助发现服务器能够产⽣的事件。但对于服务器来说,并不需要强制的建⽴从事件源(EventSource,产⽣事件)到事件通知器的关系,例如rver对象,其隐含的表⽰是所有事件源的通知器。
该关系的起点是⼀个事件订阅的源(⼀个对象,该对象的EventNotifer属性的SubscribeToEvent位有效)。
该关系的终点可以是任意NodeClass节点,只要该节点能够通过订阅产⽣事件通知,并传递给关系源端。
另外,从”A“点开始,沿着HasEventSource或其⼦关系不能再回到A点,但是允许存在多条路径都指向节点“B“。
电信委托书HasNotifier
HasNotifier引⽤也是⼀个可以被直接使⽤的关系。
HasNotifier引⽤的语义是将作为通知器的节点与其他通知器对象节点关联起来。该引⽤的⽬的是建⽴事件通知对象(event notifying object)的层次化结构,⽽且HasNotifer是HasEventSource的⼦类。
该引⽤的起点需要是能够作为事件订阅源的对象或视图,终点同样。事件订阅源是指EventNotifier属性中“SubscribeToEvents”⽣效的对象。如果HasNotifier引⽤的终点产⽣了⼀个事件,那么该引⽤的起点同样可以提供这个事件。也即通过HasNotifier引⽤,可以建⽴起事件通知的层次。
Alarm
漫山遍野告警是AcknowledgeConditions的特殊化,相⽐Condition告警增加了活动状态,以及搁置和抑制状态。
告警如果处于活动状态(Active)则表明条件所表⽰的状况正在发⽣,如果Active=Fal则表明处于正常状态
有些告警会引⼊Active状态的⼦状态,⼊high level state与critical high state
搁置状态(Shelved)可以由操作员通过OPC UA⽅法设置,抑制状态(Suppresd)由服务器出于内部原因设置,告警服务器通常会实现抑制、搁置和停⽌服务特性,以避免操作员被告警风暴淹没,⽽能够专注于真正严重的告警
搁置、抑制和停⽌服务状态与Disable状态不同,它们表明告警仍然⽣效,并继续通过订阅分发⾄客户端
下图描述了典型的告警时间线:
在值达到Alarm Limit时,产⽣了告警
在Ack Delay期间,告警处于Unacknowledged状态,也即在此时间段内,操作员没有感知到告警,因此未进⾏操作
当操作员感知到告警,并确认后,告警进⼊了Acknowledged状态,此时操作员需要时间确认这个告警并作出反应,此时处于Operator Respon Delay
之后采取⾏动,进⼊到Process Delay状态,到操作⽣效为⽌
之后产⽣效果,值向下,并在经过告警死区之后消除并转⼊Normal状态
如果不进⾏操作,则值继续上升并产⽣后果碧根果的功效与作用
Condition Instance
Condition通常会有状态和⼦状态,因此在AddressSpace中保存Condition的实例是有意义的。如果Server选择暴露condition,那么condition 通常是作为对象的⼀部分存在的,也即对象“拥有”这个条件。
如:
⼀个温度传感器内置了⾼温告警,则这个告警在地址空间中会以温度传感器实例的部件(hasComponent)关系的形式作为温度传感器的⼀部分,且这个告警是LimitAlarmType的实例。
有些时候可以选择不在地址空间中暴露condition,这样就没有办法修改condition的状态。
蜂蜜保存方法告警和状态的审计是系统中⾮常重要的安全功能,当⽤户调⽤⽅法更改Condition的状态时,会产⽣AuditConditionAcknowledgeEventType 类型的事件。
HasCondition Reference
该引⽤的语义是关联ConditionSource和它的Condition,每个ConditionSource都应该是HasEventSource或其⼦引⽤的⽬标节点。HasCondition关系可以⽤在VariabeType或者ObjectType之上,也可以⽤于它们的实例声明,HasCondition的⽬标节点则可以是ConditionType类型或者实例。
如果在类型中(ObjectType/VariableType)中有HasCondition关系,其实例也要继承
如果类型中引⽤的是ConditionType,其类型实例也要指向该ConditionType
如果类型上不允许配置HasCondition,则可以在实例上增加
AddressSpace Sample
总结来说:支支吾吾
HasNotifer维护了⼀个通知器的层次,⽬的端产⽣的事件在源端可读,由此可以在不同的通知器层次有针对性的读取事件(如只读Area1或者只读Tank Farm)
HasEventSource⽤于指明事件⽣成的源,只有HasEventSource及其⼦类型所指向的⽬标节点上可以由HasCondition关系
HasCondition关系表明了能够具体⽣成的Condition/告警
通常的ConditionType对象是作为对象的⼀部分存在的,这⾥的MyAlarmTypeA实际上是从ConditionType继承⽽来
某些服务器中,HasCondition的target节点可以是ConditionType
另外,在类型中定义的ConditionType是可以在实例中得到继承的,如下图所⽰:
⼏个问题
Event、Condition和Alarm是什么关系
EventType是ConditionType的⽗类
ConditionType是AlarmType的⽗类
Event、Condition和Alarm是其实例
鞭辟入里是什么意思Event最为泛化,主要是定义了事件的基本属性
Condition则拥有状态
Alarm则拥有更多可被设置的状态
HasEventSource、HasNotifier有什么区别
HasEventSource指明了事件产⽣的源
HasNotifier是HasEventSource的⼦类
HasNotifer组织的是⼀张通知器的⽹,关系的⽬标节点所产⽣的事件在源端也可以看到,可供⽤户定义⾃⼰查看事件的范围Condition只能加到HasEventSource的⽬标节点上
GeneratesEvent、AlwaysGenerateEvent引⽤有什么区别
GeneratesEvent表明ObjectType,VariableType可能产⽣事件,以及Method在调⽤时可能产⽣事件
AlwaysGenerateEvent的起点只能是Method,且在每次调⽤时必然产⽣事件
GeneratesEvent和AlwaysGenerateEvent的终点只能是表⽰EventType及其⼦类
参考资料
《OPC统⼀架构From马克》2.10,4.9,5.7章节
世界上最大的熊
《OPC UA Part 3 - Address Space Model Relea 1.04 Specification》4.6, 7.15, 7.16, 7.17, 7.18章节
《OPC UA Part 4 - Services Relea 1.04 Specification》5.12, 5.13章节
《OPC UA Part 9 - Alarms and Conditions Relea 1.04 Specification》第4章,第5章,第6章,附录B.2节