HistoryReadModified (C)
如果服务端允许 HistoryUpdate (修改历史), 数据可能被改过. HistoryReadModified 拉到所有版本及修改记录, 用于审计 / 法规合规.
前置 / 配套
- 普通读取不带审计请用 ReadRaw.
- 写历史 / 修改历史请看 HistoryUpdate.
API
DARRA_OPCUA_API DarraUa_Status DARRA_OPCUA_CALL DarraUa_Session_HistoryReadModified(
DarraUa_SessionHandle h,
const char* node_id_str,
DarraUa_DateTime start_time,
DarraUa_DateTime end_time,
uint32_t num_values_per_node,
DarraUa_Boolean return_bounds,
DarraUa_DataValue*** out_values,
uint32_t* out_count);
参数语义与 ReadRaw 完全一致, 只是返回的 DataValue 是修改记录 (服务端内部含 ModificationInfo).
修改信息字段当前不暴露
ModificationInfo 包含 ModificationTime / UserName / UpdateType, 当前 SDK 只透出 DataValue 元数据 (Value / Status / Timestamp). 完整 ModificationInfo 字段在后续版本提供专用 getter.
释放
与 ReadRaw 相同:
DarraUa_DataValueArray_Delete(arr, cnt);
用法
#include <darra_opcua/darra_opcua_history.h>
DarraUa_DataValue** mods = NULL;
uint32_t mod_n = 0;
DarraUa_Status st = DarraUa_Session_HistoryReadModified(
h, "ns=2;s=Temperature",
yesterday_ft, today_ft,
/*num*/ 0, /* 不限 */
/*bounds*/ 0,
&mods, &mod_n);
if (DARRA_UA_STATUS_IS_GOOD(st)) {
for (uint32_t i = 0; i < mod_n; ++i) {
const DarraUa_Variant* v = DarraUa_DataValue_GetValue(mods[i]);
DarraUa_DateTime ts = DarraUa_DataValue_GetSourceTimestamp(mods[i]);
uint32_t s = DarraUa_DataValue_GetStatus(mods[i]);
double d = 0.0; DarraUa_Variant_GetDouble(v, &d);
printf("ft=%lld v=%g status=%s\n",
(long long)ts, d, DarraUa_StatusName(s));
}
}
DarraUa_DataValueArray_Delete(mods, mod_n);
何时用
- 法规合规: GMP / FDA 21 CFR Part 11 等要求"数据可追溯"
- 审计日志: 谁动了关键参数
- 数据修复回滚: 知道改之前的值是什么
服务端要求
- 必须实现 HistoryUpdate
- 必须保留修改历史 (而不是直接覆盖)
- 用户身份必须正确传递 (Username / Certificate Token)