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] 区间内全部原始数据点.
前置 / 配套
- 高频数据点过多时改用 ReadProcessed 聚合.
- 想要含修改记录请用 ReadModified.
参数
| 参数 | 默认 | 说明 |
|---|---|---|
node_id_str | — | 目标 NodeId 字符串 |
start_time | — | 区间起 (UTC, 100ns since 1601) |
end_time | — | 区间止 |
num_values_per_node | 0 (不限) | 单次返回上限 |
return_bounds | 0/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