跳到主要内容

HistoryReadAtTime (C)

给一组离散时间点, 服务端按 "前一个 / 后一个 / 线性插值" 算法返回那个时刻的值. 用于"对齐时序":

前置 / 配套

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_bounds1 = 用最近的实际值; 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 行

下一步