历史模型 (History)
OPC UA 的历史访问与聚合查询机制允许客户端读取服务端 Historian 中存储的时序数据与事件.
服务端能力
服务端必须支持 Historian (历史档案) 才能返回历史数据, 否则统一返回 BadHistoryOperationUnsupported.
配套阅读
- 配套规范 — HA Historical Access — 聚合函数 NodeId 速查
- 快速开始 — History — 5 模式 API 速览
- 示例 — 历史数据导出 — 分批拉 + 导 Excel
HistoryRead 5 模式
OPC UA 把"读历史"细分为 5 种语义不同的请求:
1. ReadRawModified — 时间区间内的全部数据点
最常用. 给一个 [startTime, endTime] 区间, 返回所有数据点 (含时间戳 + 值 + 状态).
Time: 0s 1s 2s 3s 4s 5s
Value: 10 12 15 18 17 20
↑ ↑
start end
返回: 12, 15, 18, 17, 20 (5 个点)
2. ReadAtTime — 指定时间点的内插值
给一组离散时间点, 服务端按"前一个/后一个/线性插值"等算法返回那个时刻的值. 适合做"对齐时序":
请求时间: 0.5s, 1.5s, 2.5s
返回: 10/12 之间, 12/15 之间, 15/18 之间 (具体由 Server 插值规则决定)
3. ReadProcessed — 聚合
最强大. 给区间 + 聚合函数 + 子区间, 服务端返回每个子区间的聚合结果.
常用聚合函数包括:
- Average — 区间内平均
- Minimum / Maximum
- Sum / Count
- TimeAverage — 时间加权平均
- Range — Max - Min
- Delta — End - Start
- Total — 含状态权重
例: "查 24 小时温度的每小时最大值":
- start = 昨天0点, end = 今天0点
- aggregate = Maximum
- processingInterval = 3600000 ms (1 小时)
- → 返回 24 个值
4. ReadEvents — 事件历史
服务端可以记录事件历史, 客户端按时间区间 + EventFilter 拉历史事件:
// 返回过去 24 小时严重度 ≥ 500 的所有报警
var events = ua.History.ReadEvents("i=2253",
startTime: now.AddDays(-1), endTime: now,
filter: EventFilter.WithSeverity(500));
5. ReadModified — 含修改记录
如果服务端允许 HistoryUpdate (修改历史), 这个模式能拉到"被修改过的版本", 包含修改人 / 修改时间 / 旧值. 法规审计场景用.
HistoryUpdate
ua.History.UpdateData(nodeId, dataValues); // Insert/Replace/Update
ua.History.DeleteRange(nodeId, startTime, endTime);
ua.History.DeleteAtTime(nodeId, times);
HistoryUpdate 默认禁用
大多数生产 Server 默认禁止 HistoryUpdate, 需要管理员明确授予 HistoryWrite 权限.
节点的 Historizing Attribute
Variable 节点的 Historizing (20) Attribute 表示该节点当前是否正在记录历史. true = 正在记, false = 没记 (此时 ReadHistory 可能返回空).
如果节点的 AccessLevel bit 4 (HistoryRead) 没置位, 服务端会拒绝 HistoryRead.
性能注意
- HistoryRead 默认有 ContinuationPoint 分页, 大区间会分多次返回
- maxValues=0 表示不限制 (服务端可能强制截断)
- 高频数据 (1000Hz+) 拉一天就是上亿点, 务必加
maxValues或用ReadProcessed聚合