EventFilter
概述
OPC UA Part 4 §7.18 EventFilter:
- select_clauses — 抓哪些字段
- where_clause — 过滤条件 (V1 暂未实现, 留 NULL)
DarraUa_SimpleAttributeOperand 字段: type_definition_id / browse_path / attribute_id / index_range。
API
typedef struct {
char* type_definition_id;
char** browse_path; // 字符串数组
size_t browse_path_count;
DarraUa_AttributeId attribute_id;
char* index_range; // null 表全部
} DarraUa_SimpleAttributeOperand;
typedef struct {
DarraUa_SimpleAttributeOperand* select_clauses;
size_t select_count;
char* where_clause; // V1: NULL
} DarraUa_EventFilter;
| 函数 | 类别 | 读写 | 说明 |
|---|---|---|---|
| DarraUa_Subscription_SubscribeEvents(sub, src_nid, filter, &out_ev) | 写 | 写 | 创建事件订阅 (filter 可为 NULL) |
代码示例
#include <opcua.h>
DarraUa_Session* ua;
DarraUa_Session_New("opc.tcp://localhost:4840", &ua);
DarraUa_Session_Connect(ua);
DarraUa_Subscription* sub;
DarraUa_Session_CreateSubscription(ua, 500.0, &sub);
// 构造 filter
const char* event_id_path[] = { "EventId" };
const char* event_type_path[] = { "EventType" };
const char* source_path[] = { "SourceName" };
const char* time_path[] = { "Time" };
const char* msg_path[] = { "Message" };
const char* sev_path[] = { "Severity" };
const char* cond_id_path[] = { "ConditionId" };
const char* active_state_path[] = { "ActiveState", "Id" };
DarraUa_SimpleAttributeOperand selects[8] = {
{ "i=2041", (char**)event_id_path, 1, ATTR_VALUE, NULL },
{ "i=2041", (char**)event_type_path, 1, ATTR_VALUE, NULL },
{ "i=2041", (char**)source_path, 1, ATTR_VALUE, NULL },
{ "i=2041", (char**)time_path, 1, ATTR_VALUE, NULL },
{ "i=2041", (char**)msg_path, 1, ATTR_VALUE, NULL },
{ "i=2041", (char**)sev_path, 1, ATTR_VALUE, NULL },
{ "i=2782", (char**)cond_id_path, 1, ATTR_VALUE, NULL },
{ "i=2915", (char**)active_state_path, 2, ATTR_VALUE, NULL },
};
DarraUa_EventFilter filter = {
.select_clauses = selects,
.select_count = 8,
.where_clause = NULL,
};
DarraUa_EventSubscription* ev;
DarraUa_Subscription_SubscribeEvents(sub, "i=2253", &filter, &ev);
void on_event(const DarraUa_EventArgs* e, void* ctx) {
/* fields 顺序与 select_clauses 一致 */
/* fields[0]=EventId, fields[5]=Severity, fields[6]=ConditionId ... */
}
DarraUa_EventSubscription_RegisterArrived(ev, on_event, NULL);
字段速查
| EventType | BrowsePath | 含义 |
|---|---|---|
| BaseEventType (i=2041) | ["EventId"] | 事件唯一 ID |
| BaseEventType | ["Severity"] | 严重度 1-1000 |
| ConditionType (i=2782) | ["ConditionId"] | 条件 NodeId |
| AcknowledgeableConditionType (i=2881) | ["AckedState", "Id"] | 是否 Ack |
| AlarmConditionType (i=2915) | ["ActiveState", "Id"] | 是否激活 |
实现说明
- Stack 不支持自定义 SelectClauses 时回退默认 5 字段并推 Diagnostic Info 事件
最佳实践
- 显式列字段
- 顺序对齐: fields[i] 顺序就是 select_clauses 顺序
- 报警面板必抓 ConditionId
跨语言对照
| C# | Python | Java | C++ | Rust | C |
|---|---|---|---|---|---|
| EventFilter | EventFilter | EventFilter | EventFilter | EventFilter | DarraUa_EventFilter |
| SimpleAttributeOperand | SimpleAttributeOperand | SimpleAttributeOperand | SimpleAttributeOperand | SimpleAttributeOperand | DarraUa_SimpleAttributeOperand |