跳到主要内容

结构体解码

概述

OPC UA 1.04+ 把每个自定义结构体的字段定义放到 DataType 节点的 DataTypeDefinition 属性 (AttributeId=27, Part 5 §6.4.2)。客户端 Read 该属性 → 缓存 StructureDefinition → 拿到 ExtensionObject 字节后按字段顺序用 UA Binary 编码反序列化为 dict。

StructDecoder 实现了完整的协议层: 全部基本类型 + 嵌套结构 + 数组 + 枚举 + Union + Optional 字段。

API

成员类别读写说明
StructDecoder(ua)构造绑定到会话
decoder.decode(variant)方法解码 ExtensionObject, 返回 DynamicExtensionObject
decoder.decode_body(body, data_type_id)方法直接给字节 + DataType 解码
decoder.get_definition(data_type_id)方法获取 / 缓存 StructDefinition
decoder.prefetch_definitions(ids)方法预热缓存
obj[field_name]索引器取字段值
obj.fields属性字段名→值 dict
obj.definition属性StructDefinition

相关结构:

class StructureKind(IntEnum):
STRUCTURE = 0 # 普通
STRUCTURE_WITH_SUBTYPED_VALUES = 1 # 含子类型
STRUCTURE_WITH_OPTIONAL_FIELDS = 2 # 含可选字段 (前置 EncodingMask)
UNION = 3 # Union (前置 selector)
UNION_WITH_SUBTYPED_VALUES = 4 # Union + 子类型

代码示例

from opcua import DarraOpcUa, StructDecoder

with DarraOpcUa("opc.tcp://localhost:4840") as ua:
ua.connect()

dec = StructDecoder(ua)

# 1) 读自定义结构体
with ua.read("ns=2;s=Robot.CurrentPose") as dv:
pose = dec.decode(dv.value)

print(f"x = {pose['X']}") # 100.5
print(f"y = {pose['Y']}") # 200.3
print(f"q = {pose['Quaternion']}") # 嵌套 → DynamicExtensionObject

# 2) 全字段遍历
for name, value in pose.fields.items():
print(f"{name} = {value}")

# 3) 嵌套结构
quat = pose['Quaternion']
print(f"qw = {quat['W']}")

# 4) 数组字段
arr = pose['JointAngles'] # list
for a in arr:
print(a)

# 5) Union
with ua.read("ns=2;s=AnyValue") as uv:
u = dec.decode(uv.value)
print(f"selector field={u.definition.fields[0].name}")

# 6) 预热
dec.prefetch_definitions([
"ns=2;i=3001", # PoseType
"ns=2;i=3002", # QuaternionType
])

实现限制

  • Native 层 (DLL) 当前未导出 ExtensionObject TypeId/Body 提取接口, decode(variant) 在拿不到字节流时返回带 _status 字段的部分结果
  • 协议层全部已实现, native 接通后立刻可用 — decode_body(bytes, type_id) 重载
  • DiagnosticInfo 跳过 (生产代码极少用)

最佳实践

  • 共享一个 decoder, 字段表缓存复用
  • prefetch_definitions 启动时调
  • 嵌套结构直接索引访问
  • Union 看 selector

跨语言对照

C#PythonJavaC++RustC
StructDecoderStructDecoderStructDecoderStructDecoderStructDecoderDarraUa_StructDecoder
DecodedecodedecodeDecodedecodeDarraUa_StructDecoder_Decode
DynamicExtensionObjectDynamicExtensionObjectDynamicExtensionObjectDynamicExtensionObjectDynamicExtensionObjectDarraUa_DynamicExtensionObject

下一步