HistoryReadAtTime (C)
给一组离散时间点, 服务端按 "前一个 / 后一个 / 线性插值" 算法返回那个时刻的值. 用于"对齐时序":
前置 / 配套
- 想拉聚合统计请用 ReadProcessed.
- 想拉区间所有原始点请用 ReadRaw.
API
DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Session_HistoryReadAtTime(
DarraUa_SessionHandle h,
const char* node_id_str,
const DarraUa_DateTime* req_times,
uint32_t time_count,
DarraUa_Boolean use_simple_bounds,
DarraUa_DataValue*** out_values,
uint32_t* out_count);
| 参数 | 说明 |
|---|---|
req_times | 待查询的时间戳数组 (UTC 100ns ticks) |
time_count | 时间戳数量 (>0) |
use_simple_bounds | 1 = 用最近的实际值; 0 = 线性内插 (server 必须支持) |
out_values | 出参, DataValue* 数组与 req_times 一一对应 |
out_count | 实际返回数量 (通常 = time_count) |
返回顺序与 req_times 一一对应; server 对部分时间戳无值时会用 BadNoData 状态码标记.
用法
#include <darra_opcua/darra_opcua_history.h>
#include <stdio.h>
/* 拉过去 24 小时, 每整点的温度 */
DarraUa_DateTime hours[25];
DarraUa_DateTime end_ft = utc_now_ft();
DarraUa_DateTime midnight_ft = end_ft - (end_ft % 864000000000LL); /* 整 24h */
for (int i = 0; i < 25; ++i)
hours[i] = midnight_ft + (int64_t)i * 36000000000LL; /* 1 小时 */
DarraUa_DataValue** out = NULL;
uint32_t cnt = 0;
DarraUa_Status st = DarraUa_Session_HistoryReadAtTime(
h, "ns=2;s=Temperature",
hours, 25,
/*simple_bounds*/ 1,
&out, &cnt);
if (DARRA_UA_STATUS_IS_GOOD(st)) {
for (uint32_t i = 0; i < cnt; ++i) {
const DarraUa_Variant* v = DarraUa_DataValue_GetValue(out[i]);
double d = 0.0; DarraUa_Variant_GetDouble(v, &d);
printf("hour %u: %g\n", (unsigned)i, d);
}
}
DarraUa_DataValueArray_Delete(out, cnt);
与 ReadProcessed 的区别
| API | 返回 |
|---|---|
| ReadAtTime | 每个时间点对应一个内插值 (不聚合) |
| ReadProcessed | 每个子区间一个聚合值 (Avg / Min / Max / ...) |
例 "拉 24 小时, 每小时一个值":
- ReadAtTime: 输入 25 个整点, 返回 25 个内插点
- ReadProcessed: aggregate=Average, interval=1 h, 返回 24 个区间的平均值
应用场景
- 时序对齐: 不同传感器采样时间不同, 要拉到同一时刻才能比较
- 数据库导出: 整点抽样
- 报表: 每天 24 行