read_history_processed (聚合)
最强大的 HistoryRead 模式, 配合标准聚合函数. 给区间 + 聚合函数 + 子区间宽度, 服务端返回每个子区间的聚合结果.
前置 / 配套
- 拉所有原始点请用 ReadRaw.
- 指定时间点的内插值请用 ReadAtTime.
签名
pub fn Session::read_history_processed(
&self,
node_id: &str,
start: SystemTime,
end: SystemTime,
processing_interval_ms: f64,
aggregate_node_id: &str,
) -> Result<Vec<DataValue>, OpcUaError>;
标准聚合函数常量
darra_opcua::history_aggregate 模块:
| 常量 | NodeId | 含义 |
|---|---|---|
AVERAGE | i=2342 | 算术平均 |
TIME_AVERAGE | i=11285 | 时间加权平均 |
TOTAL | i=2348 | 累加 (代数和) |
MINIMUM | i=2346 | 最小值 |
MAXIMUM | i=2347 | 最大值 |
COUNT | i=2352 | 区间内 Good 状态点数 |
STANDARD_DEVIATION_SAMPLE | i=11427 | 样本标准差 |
RANGE | i=2353 | Max − Min |
DELTA | i=11286 | 区间末 − 区间始 |
完整列表见 OPC UA 聚合函数标准.
用法
24 小时温度的每小时平均
use std::time::{Duration, SystemTime};
use darra_opcua::history_aggregate;
let now = SystemTime::now();
let yesterday = now - Duration::from_secs(86400);
let values = s.read_history_processed(
"ns=2;s=Temperature",
yesterday, now,
/*processing_interval_ms*/ 3_600_000.0, // 1 hour
history_aggregate::AVERAGE,
)?;
// 返回 24 个 DataValue, 每个是该小时的平均值
for v in &values {
println!("avg = {}", v.variant().try_get_f64().unwrap_or(0.0));
}
一周每天的最大温度
let week_ago = now - Duration::from_secs(7 * 86400);
let maxes = s.read_history_processed(
"ns=2;s=Temperature",
week_ago, now,
86_400_000.0, // 1 day
history_aggregate::MAXIMUM,
)?;
一小时累计流量
let one_hour_ago = now - Duration::from_secs(3600);
let totals = s.read_history_processed(
"ns=2;s=FlowRate",
one_hour_ago, now,
3_600_000.0,
history_aggregate::TOTAL,
)?;
性能优势
- 避免拉百万点原始数据再客户端算
- 服务端常对历史数据建索引, 聚合极快
- 跨日 / 跨周报表的标准方案
服务端要求
- Historian 必须实现该聚合函数 (服务端 ServerCapabilities/AggregateFunctions 列出支持的)
- 不支持的聚合返回
BAD_AGGREGATE_NOT_SUPPORTED
参数校验
API 内部校验:
aggregate_node_id不能为空processing_interval_ms必须 > 0
否则返回 Err(OpcUaError { status: DARRA_INVALID_ARGUMENT, ... }).
自定义聚合 NodeId
如果服务端有非标准聚合, 直接传它的 NodeId 字符串:
s.read_history_processed(
"ns=2;s=Temperature",
yesterday, now,
60_000.0, // 1 分钟
"ns=2;s=Custom_RMS", // 自定义 RMS 聚合
)?;