跳到主要内容

read_history_processed (聚合)

最强大的 HistoryRead 模式, 配合标准聚合函数. 给区间 + 聚合函数 + 子区间宽度, 服务端返回每个子区间的聚合结果.

前置 / 配套

签名

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含义
AVERAGEi=2342算术平均
TIME_AVERAGEi=11285时间加权平均
TOTALi=2348累加 (代数和)
MINIMUMi=2346最小值
MAXIMUMi=2347最大值
COUNTi=2352区间内 Good 状态点数
STANDARD_DEVIATION_SAMPLEi=11427样本标准差
RANGEi=2353Max − Min
DELTAi=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 聚合
)?;

下一步