OpcUaNode
OpcUaNode 是 NodeCollection 索引器返回的包装对象, 表示远程一个节点. Lazy Load — 只有访问属性才触发 RPC.
前置阅读
- 入口请看 NodeCollection.
- 想避免链式索引的多次 RPC 请用 TranslateBrowsePaths 一次性解析路径.
公共属性
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 标识 (无 RPC) | NodeId | string | R | 节点 ID 字符串 |
| 数据 (触发 RPC) | Value | DataValue | R | 当前值 — 触发 Read(Value) |
DisplayName | string | R | 显示名 — 触发 Read(DisplayName) | |
BrowseName | string | R | 浏览名 — 触发 Read(BrowseName) | |
Description | string | R | 描述 — 触发 Read(Description) | |
NodeClass | NodeClass | R | 节点类别 — 触发 Read(NodeClass) | |
DataType | string | R | 数据类型 NodeId — 触发 Read(DataType) | |
AccessLevel | byte | R | 访问权限位 — 触发 Read(AccessLevel) | |
| 子节点 (触发 RPC) | Children | IReadOnlyList<OpcUaReference> | R | 子节点列表 — 触发 Browse |
索引器
| 索引 | 返回 | 说明 |
|---|---|---|
node[browseName] | OpcUaNode | 子节点 (按 BrowseName 浏览) |
node[ns, browseName] | OpcUaNode | 指定命名空间的子节点 |
公共方法
| 方法 | 说明 |
|---|---|
Read(attribute) | 读指定 Attribute |
Write(value, attribute = Value) | 写指定 Attribute |
Browse(filter = Unspecified) | 浏览子节点 |
Subscribe(sub, samplingInterval = -1) | 在已有订阅上加 MonitoredItem |
例子
// 1. 拿节点 (无 RPC)
var temp = ua.Nodes["ns=2;s=Temperature"];
// 2. 读基本信息 (各 1 次 RPC)
Console.WriteLine($"NodeId = {temp.NodeId}");
Console.WriteLine($"DisplayName = {temp.DisplayName}");
Console.WriteLine($"DataType = {temp.DataType}");
Console.WriteLine($"NodeClass = {temp.NodeClass}");
// 3. 读值
using var dv = temp.Value;
Console.WriteLine($"Value = {dv.Value.AsDouble} °C @ {dv.SourceTimestamp}");
// 4. 写
temp.Write(new Variant(25.5));
// 5. 浏览子节点
foreach (var child in temp.Children)
Console.WriteLine($" {child.BrowseName} -> {child.NodeId}");
// 6. 链式访问 (Server.ServerStatus.CurrentTime)
using var time = ua.Nodes.Server["ServerStatus"]["CurrentTime"].Value;
Console.WriteLine($"Server time = {time.Value.AsDateTime}");
注意事项
- 所有触发 RPC 的属性都是"读一次返回一次", 不缓存. 想缓存自己存变量
- 链式访问
a["b"]["c"]每段都是一次 Browse RPC, 总计 N 次 DataValue必须 Dispose, 否则泄漏 native 内存- 跨线程使用
OpcUaNode安全, 但DataValue不要跨线程
与 Resolve 的对比
// 方式 A: 链式索引器 - 4 次 RPC
using var time = ua.Nodes.Server["ServerStatus"]["CurrentTime"].Value;
// 1次 2次 3次 4次 Read
// 方式 B: 路径解析 - 2 次 RPC
var node = ua.Resolve("/Objects/Server/ServerStatus/CurrentTime"); // 1 次
using var time = node.Value; // 1 次
// 方式 C: 直接 NodeId - 1 次 RPC
using var time = ua.Read("i=2258");
如果路径已知 → 方式 C; 探索式开发 → 方式 A.