跳到主要内容

update_history

往服务端 Historian 写入数据 (而不是当前 read / write 操作的"实时值"):

高敏感操作

HistoryUpdate 多数生产 Server 默认禁止, 需要管理员明确开启 + 合规审计. 详见服务端要求.

签名

pub fn Session::update_history(
&self,
node_id: &str,
update_type: HistoryUpdateType,
values: &[DataValue],
) -> Result<Vec<StatusCode>, OpcUaError>;

返回 Vec<StatusCode> — 每条值的写入状态, 顺序与 values 一致.

HistoryUpdateType

pub enum HistoryUpdateType {
Insert = 1, // 仅当时间点不存在才插入
Replace = 2, // 仅当时间点存在才替换
Update = 3, // Insert + Replace 任一适用 (推荐)
Remove = 4, // 按时间删 (用 DataValue.source_timestamp)
}

用法

补录历史数据

use darra_opcua::HistoryUpdateType;

// 大多数用户从历史 Read 拿到 DataValue 直接转 Update
let dvs = s.read_history(
"ns=2;s=Temperature_Backup",
yesterday, now, 1000,
)?;
let results = s.update_history("ns=2;s=Temperature", HistoryUpdateType::Update, &dvs)?;
for (i, st) in results.iter().enumerate() {
if !st.is_good() {
eprintln!("values[{}] failed: {}", i, st);
}
}

仅插入 (不覆盖已有)

let results = s.update_history("ns=2;s=Temperature", HistoryUpdateType::Insert, &dvs)?;

删除指定时间点

Remove 模式只看每个 DataValuesource_timestamp, value 字段被服务端忽略. 简单按区间删建议直接用 delete_history_range 更直观.


权限要求

  • 节点 AccessLevel bit 8 (HistoryWrite) 必须置位
  • 用户必须有 HistoryUpdate 权限
  • 大多数生产 Server 默认禁止, 需要管理员明确开启

错误

StatusCode原因
BAD_HISTORY_OPERATION_INVALID该节点不支持 HistoryUpdate
BAD_USER_ACCESS_DENIED无权限
BAD_ENTRY_EXISTS (Insert 模式)该时间点已存在
BAD_NO_ENTRY_EXISTS (Replace / Remove 模式)该时间点不存在

构造 DataValue (高级)

当前 SDK Rust 接口未直接暴露 DataValue 的 public builder (DataValue::from_raw / wrap_owned 是 crate 内部 API). 要手工构造历史值, 推荐方案:

  1. 从一个真实历史 Read 拿到 Vec<DataValue> 模板, 修改时间戳后回写
  2. 或在 PLC / 设备侧产生数据, 通过 write 实时写入, 让服务端 Historian 自动归档

如果业务必须从程序构造, 给 SDK 提 issue, 后续版本会扩展 DataValue::new(value, status, source_ts) 公共构造器.

错误处理

整体 RPC 失败返回 Err. 单条值失败通过 results[i] 判断:

let results = s.update_history(node_id, HistoryUpdateType::Update, &dvs)?;
let bad = results.iter().filter(|st| !st.is_good()).count();
if bad > 0 {
eprintln!("{}/{} values failed to write", bad, results.len());
}

下一步