如何读取ExtensionObject类型节点的值?读取结果与UAexpert不符求助
问题描述
我尝试读取一个ExtensionObject类型节点的值,代码返回结果为b'\x00\xff\xff\xff\xff',但UAexpert显示的值不同,且Wireshark抓取的服务器与客户端报文值和UAexpert一致。查阅大量资料后仍未解决,代码如下:
from opcua import Client, ua server_url = "opc.tcp://localhost:4840" client1 = Client(server_url) client1.connect() import time try: #call StartTransfer method method_0 = client1.get_node("ns=1;s=StartTransfer") parent_obj_0 = "ns=1;s=OpcUaDaqProfile" obj_1 = client1.get_node(parent_obj_0) out_1 = obj_1.call_method(method_0) node_id = "ns=1;s=data/OpcUaServer/channels/1/0_VALUES" node = client1.get_node(node_id) data_value = node.get_value() print("Node Value:", data_value.Body) finally: client1.disconnect()
解决方案
问题核心是python-opcua未正确解析该ExtensionObject对应的自定义类型,可通过以下步骤解决:
获取节点的类型定义
添加代码获取该节点的数据类型详情,明确扩展对象的结构:data_type_node = node.get_data_type() print("DataType NodeId:", data_type_node) data_type_def = data_type_node.get_data_type_definition() print("DataType Definition:", data_type_def) print("ExtensionObject TypeId:", data_value.TypeId)输出结果会告诉你该扩展对象对应的结构体字段、类型及NodeId,为后续解析提供依据。
注册自定义类型解码器
如果是服务器自定义的结构体类型,需在客户端注册对应的类型映射。假设通过步骤1得到类型NodeId为ns=1;i=1001,结构体包含一个Int32类型的Value字段,示例代码如下:from opcua import ua class CustomStruct(ua.Structure): Fields = [ ("Value", ua.Int32), ] DataTypeId = ua.NodeId(1001, 1) # 替换为实际的DataType NodeId ua.register_extension_object_type(CustomStruct.DataTypeId, CustomStruct)注册后再调用
node.get_value(),即可自动解析为结构体对象,直接访问其字段(如data_value.Value)即可得到正确值。手动解析字节流
若暂时无法注册解码器,可根据UAexpert显示的实际值类型,手动解析原始字节流。比如UAexpert显示的值为-1(对应Int32类型),则用小端模式解析:import struct # 小端Int32解析,根据实际类型调整格式符(<f为float,<q为Int64等) actual_value = struct.unpack('<i', data_value.Body)[0] print("解析后的值:", actual_value)
内容的提问来源于stack exchange,提问作者baixianjie
相关产品推荐
相关产品推荐

