You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python OPC-UA服务器创建ST_NameValue结构体数组变量遇阻求助

解决OPC-UA服务器创建结构体数组变量及客户端写入问题

1. 先正确注册自定义结构体类型

OPC-UA中自定义结构体必须先在服务器地址空间完成类型注册,否则无法创建对应类型的变量。以下是ST_NameValue结构体的注册示例:

from opcua import Server, ua

server = Server()
server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")
uri = "http://your-company.com/opcua"
idx = server.register_namespace(uri)

# 创建ST_NameValue结构体类型
st_name_value_type = server.nodes.base_object_type.add_object_type(idx, "ST_NameValue")
# 添加结构体字段:Name(String类型)、Value(这里用Double示例,可替换为你需要的类型)
st_name_value_type.add_variable(idx, "Name", "", ua.VariantType.String).set_modelling_rule(True)
st_name_value_type.add_variable(idx, "Value", 0, ua.VariantType.Double).set_modelling_rule(True)

# 创建结构体数组类型
struct_type_node = server.get_node(f"ns={idx};i={st_name_value_type.nodeid.Identifier}")
array_type_node = server.nodes.base_data_type.add_array_type(struct_type_node, idx, "ArrayOfST_NameValue")

2. 创建astParam变量节点(解决AttributeError)

AttributeError多因未正确指定变量DataType或类型未注册导致。创建数组变量时需明确指定ValueRank和ArrayDimensions参数:

# 获取父节点(以Objects节点为例)
objects = server.get_objects_node()

# 创建astParam变量
ast_param = objects.add_variable(
    idx, 
    "astParam", 
    [],  # 初始空数组,后续可填充默认值
    datatype=array_type_node.nodeid,  # 必须传入数组类型的NodeId对象
    valuerank=ua.ValueRank.OneDimension,  # 声明为一维数组
    arraydimensions=[20]  # 指定数组长度为20
)
# 设置变量可读写
ast_param.set_writable()

常见AttributeError修复点:

  • 避免用字符串指定datatype:必须传入NodeId对象,而非字符串类型的类型名
  • 确保结构体类型已注册:检查ST_NameValue类型已成功添加到地址空间,可通过server.get_node验证
  • 核对方法调用:比如误将add_variable写成add_object,会导致属性不匹配

3. 客户端写入结构体数组的正确方式

客户端需先获取服务器的结构体类型定义,构造匹配的结构体实例数组,不能直接用普通字典或其他类型填充:

from opcua import Client

client = Client("opc.tcp://localhost:4840/freeopcua/server/")
client.connect()

try:
    # 获取结构体类型节点和astParam变量节点
    st_name_value_type = client.get_node(f"ns={idx};i={st_name_value_type.nodeid.Identifier}")
    ast_param_node = client.get_node(f"ns={idx};s=astParam")

    # 构造20个ST_NameValue实例
    struct_array = []
    for i in range(20):
        # 创建结构体实例
        struct_instance = client.get_node(st_name_value_type).call_method("0:CreateInstance")
        struct_instance.get_child(f"ns={idx};s=Name").set_value(f"Param_{i}")
        struct_instance.get_child(f"ns={idx};s=Value").set_value(i * 1.0)
        struct_array.append(struct_instance.get_value())

    # 写入数组到astParam
    ast_param_node.set_value(ua.Variant(struct_array, array_type_node.nodeid))
finally:
    client.disconnect()

客户端写入报错常见原因:

  • 数据类型不匹配:客户端构造的数组元素不是服务器定义的ST_NameValue实例,而是普通字典或其他类型
  • 数组长度不匹配:写入的数组长度不等于服务器指定的ArrayDimensions[20]
  • 权限问题:变量未调用set_writable()设置为可写

内容的提问来源于stack exchange,提问作者Autolab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:26:21