报警与条件
概述
OPC UA Part 9 在 ConditionType / AlarmConditionType 上定义了固定 NodeId 的标准 Method。SDK 封装为形参清晰的 Rust 方法。
| Method | NodeId | 入参 |
|---|---|---|
| Acknowledge | i=9111 | (event_id: &[u8], comment: &str) |
| Confirm | i=9113 | (event_id, comment) |
| AddComment | i=9029 | (event_id, comment) |
| Enable | i=2803 | — |
| Disable | i=2805 | — |
| ConditionRefresh | i=3875 | (sub_id) |
| ConditionRefresh2 | i=12912 | (sub_id, mi_id) |
| OneShotShelve | i=9211 | — |
| TimedShelve | i=9213 | (shelving_time_ms) |
| Unshelve | i=9215 | — |
API
| 方法 | 类别 | 读写 | 说明 |
|---|---|---|---|
| ua.acknowledge(condition_id, event_id, comment) | 报警 | 写 | 用户已知 |
| ua.confirm(condition_id, event_id, comment) | 报警 | 写 | 现场已处理 |
| ua.add_comment(condition_id, event_id, comment) | 报警 | 写 | 加备注 |
| ua.enable_condition(condition_id) | 报警 | 写 | 启用 |
| ua.disable_condition(condition_id) | 报警 | 写 | 禁用 |
| ua.condition_refresh(sub_id) | 报警 | 写 | 补发激活报警 |
| ua.condition_refresh2(sub_id, mi_id) | 报警 | 写 | 仅指定 MI |
| ua.one_shot_shelve(shelving_state_id) | 报警 | 写 | 一次性屏蔽 |
| ua.timed_shelve(shelving_state_id, ms) | 报警 | 写 | 限时屏蔽 |
| ua.unshelve(shelving_state_id) | 报警 | 写 | 取消屏蔽 |
返回 Result<StatusCode>, 失败不 panic, 业务级失败由 StatusCode 表达。
代码示例
use opcua::{DarraOpcUa, StatusCode};
let ua = DarraOpcUa::new("opc.tcp://server:4840")?;
ua.connect()?;
let sub = ua.create_subscription(500)?;
let ev = sub.subscribe_events("i=2253")?; // ServerObject
ev.on_event_arrived(move |args| {
let event_id = args.get_field("EventId").as_byte_string()?;
let condition_id = args.get_field("ConditionId").as_string()?;
// a. 让服务端补发当前激活报警
ua.condition_refresh(sub.subscription_id())?;
// b. 用户点 "确认"
let rc = ua.acknowledge(&condition_id, &event_id, "操作员已知")?;
if rc != StatusCode::Good { eprintln!("Acknowledge 失败: {:?}", rc); }
// c. 现场处理
ua.confirm(&condition_id, &event_id, "现场已处理")?;
// d. 临时屏蔽 30 秒
ua.timed_shelve(&format!("{}.ShelvingState", condition_id), 30_000.0)?;
Ok(())
})?;
错误处理
| StatusCode | 含义 |
|---|---|
| Good | 成功 |
| BadEventIdUnknown | EventId 不匹配 |
| BadConditionAlreadyEnabled | 已启用 |
| BadConditionAlreadyShelved | 已屏蔽 |
最佳实践
- 首次订阅后必调 condition_refresh
- acknowledge 后再 confirm, 两步
- TimedShelve 单位 ms, 不是秒
- 不要在 on_event_arrived 里同步 ack, 用 mpsc 推队列后台处理
跨语言对照
| C# | Python | Java | C++ | Rust | C |
|---|---|---|---|---|---|
| Acknowledge | acknowledge | acknowledge | Acknowledge | acknowledge | DarraUa_Condition_Acknowledge |
| Confirm | confirm | confirm | Confirm | confirm | DarraUa_Condition_Confirm |
| ConditionRefresh | condition_refresh | conditionRefresh | ConditionRefresh | condition_refresh | DarraUa_Condition_Refresh |