添加 MonitoredItem
前置阅读
- 先创建 Subscription, 见 创建 Subscription.
- DataChanged 事件字段请看 DataChanged 事件.
- 改采样参数请看 Modify.
sub.Add(...)
public uint Add(
string nodeId,
AttributeId attribute = AttributeId.Value,
double samplingIntervalMs = -1.0);
| 参数 | 默认 | 说明 |
|---|---|---|
nodeId | — | 监控的 NodeId |
attribute | Value (13) | 监控的 Attribute |
samplingIntervalMs | -1 (跟订阅) | 服务端采样间隔. 0 = 尽快 |
返回: uint MonitoredItem handle (本地句柄, 用于后续 Modify / Remove)
异常: OpcUaException (BadNodeIdUnknown 等)
uint h = sub.Add("ns=2;s=Temperature");
uint h2 = sub.Add("ns=2;s=Pressure", AttributeId.Value, samplingIntervalMs: 100);
sub.AddMany(nodeIds, attribute)
一次 RPC 添加多个 MI, 比循环 Add 快得多:
public IReadOnlyList<(uint handle, StatusCode status)> AddMany(
IReadOnlyList<string> nodeIds,
AttributeId attribute = AttributeId.Value);
var nodes = Enumerable.Range(1, 100).Select(i => $"ns=2;s=T{i}").ToList();
var results = sub.AddMany(nodes);
for (int i = 0; i < nodes.Count; i++)
{
if (results[i].status == StatusCode.Good)
Console.WriteLine($" {nodes[i]} -> handle={results[i].handle}");
else
Console.WriteLine($" {nodes[i]} FAILED: {results[i].status}");
}
性能: 100 个 MI 用 AddMany 约 1 次 RPC (~10 ms), 用循环 Add 约 100 次 RPC (~500-1000 ms).
DataChanged 事件 args
订阅的回调参数 DataChangeEventArgs:
| 字段 | 类型 | 说明 |
|---|---|---|
MonitoredItemHandle | uint | 触发的 MI 句柄 |
NodeId | string | 该 MI 的 NodeId |
ValueString | string | 值的字符串表示 (预抽取, 跨线程安全) |
DataTypeName | string | 内置数据类型枚举名 (如 Double) |
Status | StatusCode | DataValue 的 Status |
SourceTimestamp | DateTime? | 数据源时间戳 |
ServerTimestamp | DateTime? | 服务端时间戳 |
安全设计
ValueString / DataTypeName 已在 C 层 Publish 线程同步抽取, 跨线程使用安全. 不再暴露原始 DataValue 指针, 避免 use-after-free 闪退.
移除
sub.Remove(handle);
sub.RemoveByNodeId("ns=2;s=Temperature"); // 按 NodeId 移除全部对应
不同 Attribute 的监控
除了默认监控 Value, 也能监控 Status / Quality:
sub.Add("ns=2;s=T1", AttributeId.Value);
sub.Add("ns=2;s=T1", AttributeId.StatusCode); // 只关心状态变化
DataChangeFilter (死区)
当前 SDK 默认不设 filter (任何变化都推). 如需 Absolute / Percent 死区, 走底层 API (后续版本会暴露).