read_history_at_time
给一组离散时间点, 服务端按 "前一个 / 后一个 / 线性插值" 算法返回那个时刻的值. 用于"对齐时序":
前置 / 配套
- 想拉聚合统计请用 ReadProcessed.
- 想拉区间所有原始点请用 ReadRaw.
签名
pub fn Session::read_history_at_time(
&self,
node_id: &str,
times: &[SystemTime],
use_simple_bounds: bool,
) -> Result<Vec<DataValue>, OpcUaError>;
| 参数 | 类型 | 说明 |
|---|---|---|
node_id | &str | 目标 NodeId |
times | &[SystemTime] | 离散时间点列表 (UTC) |
use_simple_bounds | bool | true = 阶梯型 (用 ≤ t 的最近点); false = 线性插值 |
用法
use std::time::{Duration, SystemTime};
// 拉过去 24 小时, 每整点的温度
let now = SystemTime::now();
let times: Vec<SystemTime> = (0..25).map(|h| {
now - Duration::from_secs(((24 - h) * 3600) as u64)
}).collect();
let values = s.read_history_at_time(
"ns=2;s=Temperature",
×,
/*use_simple_bounds*/ true,
)?;
for (t, v) in times.iter().zip(values.iter()) {
println!("{:?}: {:?}", t, v.variant());
}
与 ReadProcessed 的区别
| API | 返回 |
|---|---|
read_history_at_time | 每个时间点对应一个内插值 (不聚合) |
read_history_processed | 每个子区间一个聚合值 (Average / Min / Max / ...) |
例 "拉 24 小时, 每小时一个值":
read_history_at_time: 输入 25 个整点, 返回 25 个内插点 (每个整点的值, 可能是相邻原始点的线性插值)read_history_processed: aggregate=Average, interval=1 h, 返回 24 个区间的平均值
use_simple_bounds 选择
true(默认推荐): 用 ≤ t 的最近实际值. 数据是阶梯波 (PLC bool / int 状态量) 必用 truefalse: 服务端做线性内插. 数据是连续模拟量 (温度 / 压力) 推荐 false
应用场景
- 时序对齐: 不同传感器采样时间不同, 要拉到同一时刻才能比较
- 数据库导出: 整点抽样
- 报表: 每天 24 行
错误
| StatusCode | 原因 |
|---|---|
BAD_HISTORY_OPERATION_UNSUPPORTED | 服务端不支持 ReadAtTime |
BAD_INVALID_ARGUMENT | times 列表为空 |
DARRA_INVALID_ARGUMENT | node_id 含 NUL |