跳到主要内容

报警与条件 (Acknowledge / Confirm / Refresh / Shelve)

概述

OPC UA Part 9 (Alarms & Conditions) 在 ConditionType / AlarmConditionType 上定义了固定 NodeId 的标准 Method。SDK 把这 7+3 个 Method 封装为形参清晰的 C# 方法, 让上层报警面板不用手拼 Variant[] 入参。

固定 NodeId (Part 9 / Part 6 标准空间 0):

MethodNodeId入参
Acknowledgei=9111(eventId : ByteString, comment : LocalizedText)
Confirmi=9113(eventId : ByteString, comment : LocalizedText)
AddCommenti=9029(eventId : ByteString, comment : LocalizedText)
Enablei=2803
Disablei=2805
ConditionRefreshi=3875(subscriptionId : IntegerId)
ConditionRefresh2i=12912(subscriptionId, monitoredItemId)
OneShotShelvei=9211
TimedShelvei=9213(shelvingTime : Duration ms)
Unshelvei=9215

API

方法类别读写说明
ua.Acknowledge(conditionId, eventId, comment)报警用户已知
ua.Confirm(conditionId, eventId, comment)报警现场已处理
ua.AddComment(conditionId, eventId, comment)报警加备注
ua.EnableCondition(conditionId)报警启用
ua.DisableCondition(conditionId)报警禁用
ua.ConditionRefresh(subscriptionId)报警让服务端补发当前所有激活报警
ua.ConditionRefresh2(subscriptionId, miId)报警仅指定 MI 的补发
ua.OneShotShelve(shelvingStateId)报警一次性屏蔽 (下次激活自动恢复)
ua.TimedShelve(shelvingStateId, ms)报警限时屏蔽 N 毫秒
ua.Unshelve(shelvingStateId)报警取消屏蔽

返回 StatusCode, 失败 不抛异常, 上层自决重试。

代码示例

using DarraOpcUa_Client;

using var ua = new DarraOpcUa("opc.tcp://server:4840");
ua.Connect();

// 1) 订阅报警事件
using var sub = ua.CreateSubscription(500);
using var ev = sub.SubscribeEvents("i=2253"); // ServerObject

ev.EventArrived += (s, e) =>
{
// 抽 EventId / ConditionId (从 EventFieldList)
byte[] eventId = e.GetField("EventId").AsByteString;
string conditionId = e.GetField("ConditionId").AsString;

// a. 让服务端补发当前所有激活报警 (面板首次打开时)
ua.ConditionRefresh(sub.SubscriptionId);

// b. 用户点 "确认"
var rc = ua.Acknowledge(conditionId, eventId, "操作员已知");
if (rc != StatusCode.Good) MessageBox.Show($"Acknowledge 失败: {rc}");

// c. 现场处理后点 "确认完成"
ua.Confirm(conditionId, eventId, "现场已处理");

// d. 临时屏蔽 30 秒
string shelvingId = conditionId + ".ShelvingState";
ua.TimedShelve(shelvingId, 30_000.0);
};

// 2) 加备注 (不影响 Ack/Confirm 状态)
ua.AddComment(conditionId, eventId, "等待夜班巡检");

// 3) 启用 / 禁用整条 Condition (维护期间)
ua.DisableCondition("ns=2;s=Tank.HighLevel");
// ... 维护完
ua.EnableCondition("ns=2;s=Tank.HighLevel");

错误处理

StatusCode含义
Good (0x00000000)成功
BadEventIdUnknownEventId 不匹配当前 Condition
BadConditionAlreadyEnabled已启用
BadConditionAlreadyDisabled已禁用
BadConditionAlreadyShelved已屏蔽
BadConditionNotShelved未屏蔽, 无法 Unshelve

最佳实践

  • 首次订阅后必调 ConditionRefresh — 不然只能收到新事件, 不见已激活的旧报警
  • Acknowledge 后再 Confirm — 两步流程, 不要跳 Confirm
  • TimedShelve 单位 ms — 不是秒, 30 秒 = 30000 ms
  • comment 用中文LocalizedText.Text 自动 UTF-8
  • 不要在 EventArrived 里同步 Ack — 用 ConcurrentQueue 推队列, 后台线程处理

跨语言对照

C#PythonJavaC++RustC
AcknowledgeacknowledgeacknowledgeAcknowledgeacknowledgeDarraUa_Condition_Acknowledge
ConfirmconfirmconfirmConfirmconfirmDarraUa_Condition_Confirm
ConditionRefreshcondition_refreshconditionRefreshConditionRefreshcondition_refreshDarraUa_Condition_Refresh
TimedShelvetimed_shelvetimedShelveTimedShelvetimed_shelveDarraUa_Condition_TimedShelve

下一步