跳到主要内容

HistoryReadRaw (C)

DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Session_HistoryReadRaw(
DarraUa_SessionHandle h,
const char* node_id_str,
DarraUa_DateTime start_time,
DarraUa_DateTime end_time,
uint32_t num_values_per_node, /* 0 = 不限 */
DarraUa_Boolean return_bounds,
DarraUa_DataValue*** out_values,
uint32_t* out_count);

最常用的历史读, 返回 [start_time, end_time] 区间内全部原始数据点.

前置 / 配套

参数

参数默认说明
node_id_str目标 NodeId 字符串
start_time区间起 (UTC, 100ns since 1601)
end_time区间止
num_values_per_node0 (不限)单次返回上限
return_bounds0/1是否返回边界点 (端点必含)
out_values出参, *out_values 指向 Stack malloc 的 DataValue* 数组
out_count出参, 数组长度

内存释放

DarraUa_DataValue** arr = NULL;
uint32_t cnt = 0;
DarraUa_Session_HistoryReadRaw(h, "ns=2;s=Temperature",
start, end, 1000, /*bounds*/ 1, &arr, &cnt);

/* ... 使用 ... */

DarraUa_DataValueArray_Delete(arr, cnt); /* 一次性释放数组 + 每项 */

完整用法

#include <darra_opcua/darra_opcua.h>
#include <darra_opcua/darra_opcua_history.h>
#include <stdio.h>
#include <time.h>

static DarraUa_DateTime utc_now_ft(void) {
return (DarraUa_DateTime)((int64_t)time(NULL) * 10000000LL + 116444736000000000LL);
}

int main(void)
{
/* ... Connect 略 ... */
DarraUa_SessionHandle h = /* ... */ 0;

DarraUa_DateTime end = utc_now_ft();
DarraUa_DateTime start = end - 36000000000LL; /* 1 小时 = 3600 秒 */

DarraUa_DataValue** values = NULL;
uint32_t count = 0;

DarraUa_Status st = DarraUa_Session_HistoryReadRaw(
h, "ns=2;s=Temperature",
start, end,
/*num*/ 1000,
/*return_bounds*/ 1,
&values, &count);

if (!DARRA_UA_STATUS_IS_GOOD(st)) {
fprintf(stderr, "HistoryReadRaw failed: %s\n", DarraUa_StatusName(st));
return -1;
}

printf("Got %u points\n", (unsigned)count);
for (uint32_t i = 0; i < count; ++i) {
const DarraUa_Variant* v = DarraUa_DataValue_GetValue(values[i]);
DarraUa_DateTime ts = DarraUa_DataValue_GetSourceTimestamp(values[i]);
double d = 0.0; DarraUa_Variant_GetDouble(v, &d);
printf(" ft=%lld v=%g\n", (long long)ts, d);
}

DarraUa_DataValueArray_Delete(values, count);
return 0;
}

ContinuationPoint 处理 (内部)

如果数据量大, 服务端可能分多次返回 (ContinuationPoint). SDK 内部已自动循环 HistoryReadNext, 客户端拿到的是合并后的完整列表.


错误码

状态码含义
Good成功
BadHistoryOperationUnsupported服务端无 Historian
BadNotReadable节点无 HistoryRead 权限
BadCommunicationError网络故障

性能与最佳实践

  • 高频数据 (1000 Hz+) 拉一天 = 86 M+ 点 → 必须用 num_values_per_node 限制或改用 ReadProcessed 聚合
  • 必须用 DarraUa_DataValueArray_Delete 一次性释放, 不要循环单 Delete + free 数组
  • 时间戳一律 UTC

下一步