跳到主要内容

HistoryReadEvents (C)

如果服务端记录事件历史, 客户端可以按时间区间拉历史事件 (报警 / 条件).

配套

API

#include <darra_opcua/darra_opcua_history.h>
#include <darra_opcua/darra_opcua_event.h>

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Session_HistoryReadEvents(
DarraUa_SessionHandle h,
const char* node_id_str, /* 通常 "i=2253" Server */
DarraUa_DateTime start_time,
DarraUa_DateTime end_time,
uint32_t num_values_per_node,
DarraUa_Event*** out_events,
uint32_t* out_count);

DarraUa_Event* 结构同 事件订阅.

内置 SelectClauses

固定 4 个标准字段 (与 Subscription Event 一致):

  • Severity (UInt16)
  • Message (LocalizedText)
  • SourceName (String)
  • Time (DateTime)

whereClause 留空 = 全部事件.

释放

DarraUa_EventArray_Delete(events, count);

_EventArray_Delete 释放数组本身、每个 Event 元素以及 Event 内部 strdup 出来的字符串字段.


用法

#include <darra_opcua/darra_opcua_history.h>
#include <darra_opcua/darra_opcua_event.h>

DarraUa_DateTime end = utc_now_ft();
DarraUa_DateTime start = end - 864000000000LL; /* 24 小时 */

DarraUa_Event** events = NULL;
uint32_t count = 0;

DarraUa_Status st = DarraUa_Session_HistoryReadEvents(
h, "i=2253",
start, end,
/*num*/ 0, /* 不限 */
&events, &count);

if (DARRA_UA_STATUS_IS_GOOD(st)) {
for (uint32_t i = 0; i < count; ++i) {
const DarraUa_Event* ev = events[i];
printf("[sev=%u] src=\"%s\" time=%lld msg=\"%s\"\n",
(unsigned)ev->severity,
ev->source_name ? ev->source_name : "",
(long long)ev->time,
ev->message ? ev->message : "");
}
}

DarraUa_EventArray_Delete(events, count);

服务端要求

  • 必须支持 HistoryRead Events (服务端 ServerCapabilities 标志位)
  • 事件源节点必须有 EventNotifier Attribute (12) bit 1 (HistoryRead) 置位

与实时事件订阅的关系

API拿什么
DarraUa_Subscription_AddEventItem(...)实时事件 (订阅期间发生的)
DarraUa_Session_HistoryReadEvents(...)历史事件 (服务端归档的)

通常组合用: 启动时 ReadEvents 拉过去 24 小时, 然后订阅接管实时.

下一步