NodeCollection — ua.nodes
NodeCollection 是 Session 的节点访问入口, 通过 [] 索引器返回 OpcUaNode 包装对象, 不立即触发 RPC (Lazy Load).
前置阅读
- 单节点 API 请看 OpcUaNode.
- 标准节点常量请看 WellKnownNodes.
索引器
| 索引 | 返回 | 说明 |
|---|---|---|
nodes[node_id_str] | OpcUaNode | 字符串 NodeId 访问 |
预定义入口属性
为方便, 内置常用入口:
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 标准入口 | root | OpcUaNode | R | Address Space 根 (i=84) |
objects | OpcUaNode | R | 业务数据根 (i=85) | |
types | OpcUaNode | R | 类型定义根 (i=86) | |
views | OpcUaNode | R | 视图根 (i=87) | |
server | OpcUaNode | R | Server 自身对象 (i=2253) |
# 这两行等价
t1 = ua.nodes.server["ServerStatus"]["CurrentTime"].value
t2 = ua.nodes["i=2253"]["ServerStatus"]["CurrentTime"].value
Lazy Load 机制
node = ua.nodes["ns=2;s=Temperature"] # ← 不触发 RPC
with node.value as dv: # ← 第一次 .value 才触发 read
print(dv.value)
第二次访问 .value 还是会重新 read (无缓存), 因为变量值随时变. 想缓存自己存变量.
子节点 BrowseName 索引
sub = node["ChildName"] # 通过 BrowseName 浏览子节点
底层逻辑:
- 立即用
browse(current_node_id)拿到子节点列表 - 找到
browse_name == "ChildName"(或display_name == "ChildName") 的子, 返回OpcUaNode包装 - 找不到返回
None
第一次访问会有 RPC 开销 (~5-10 ms), 后续路径访问连串都是单次 browse 的结果.
NodeId 拼装辅助
# 按 NamespaceUri + 数字 ID 构造 (动态 ns 推荐)
n = ua.nodes.make_numeric("urn:my-company:plc1", 1234)
# 按 NamespaceUri + 字符串 ID 构造
n = ua.nodes.make_string("urn:my-company:plc1", "Counter")
URI 找不到时抛 OpcUaException(DarraInvalidArgument).
何时用索引器, 何时用字符串
| 场景 | 推荐 |
|---|---|
| 已知精确 NodeId | 字符串 (ua.read("ns=2;s=...")) |
| 标准节点 (Server 状态等) | ua.nodes.server[...] |
| 浏览树 / 写一次性脚本 | 索引器 (ua.nodes["..."]["..."]) |
| 批量 (100+ 节点) | read_many / browse_many, 不要循环 |