browse
browse(node_id, filter = NodeClass.Unspecified) — 列出指定节点的直接子节点 (一层).
前置阅读 / 配套
- 大节点分页请用 browse_with_paging + browse_next.
- 路径式批量解析请用 translate_browse_paths.
签名
def browse(self,
node_id: str,
filter: NodeClass = NodeClass.Unspecified) -> List[Reference]: ...
def browse_many(self,
node_ids: List[str],
filter: NodeClass = NodeClass.Unspecified) -> List[List[Reference]]: ...
Reference 字段
| 字段 | 类型 | 说明 |
|---|---|---|
node_id | str | 子节点 NodeId |
browse_name | str | 浏览名 |
display_name | str | 显示名 |
node_class | NodeClass | 子节点类别 |
Reference.to_node(session) 转为可操作的 OpcUaNode.
例子
from darra_opcua import NodeClass
# 列出 Boiler1 下所有子节点
children = ua.browse("ns=2;s=Boiler1")
for c in children:
print(f" {c.node_class.name} {c.browse_name} -> {c.node_id}")
# 只看 Variable 类型
vars_ = ua.browse("ns=2;s=Boiler1", filter=NodeClass.Variable)
# 只看 Method
methods = ua.browse("ns=2;s=Calculator", filter=NodeClass.Method)
批量浏览 (browse_many)
如果同时要浏览多个节点 (例如 GUI 初次展开树), 用 browse_many 一次 RPC:
roots = ["i=85" /* Objects */, "i=86" /* Types */]
results = ua.browse_many(roots)
for nid, refs in zip(roots, results):
print(f"{nid}:")
for c in refs:
print(f" {c.browse_name}")
如果某个节点浏览失败 (NodeId 错), 对应槽位返回空列表, 不抛异常.
NodeClass filter
| 值 | 包含 |
|---|---|
Unspecified (0) | 全部 |
Object (1) | 仅 Object |
Variable (2) | 仅 Variable |
Method (4) | 仅 Method |
Object | Variable (按位或) | 组合 |
异常
OpcUaException(BadNodeIdUnknown) / OpcUaException(BadCommunicationError) 等. transport 失败抛, 单个子节点失败不抛.
大节点的分页 (ContinuationPoint)
如果一个节点有 1000+ 个子节点, 单次 browse 服务端可能截断. 此时 browse 只返回第一页.
要看全部, 用 browse_with_paging + browse_next:
page = ua.browse_with_paging("ns=2;s=BigFolder")
all_refs = list(page.references)
while page.continuation_point is not None:
page = ua.browse_next(page.continuation_point)
all_refs.extend(page.references)
性能
- 单次 browse: ~5-15 ms (网络往返 + 服务端遍历)
- browse_many 批量: 总耗时 ~ 单次 (省 N-1 次往返)
- 1000+ 子节点会分页, 加 browse_next 处理