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

如何使用Python通过OPC UA订阅Object节点并获取子变量值?

问题解答

可行,但你的代码存在两个关键问题导致Handler不工作:

  1. 直接订阅Object节点不会触发数据变化通知——Object节点本身没有可变化的数值,服务器不会针对它发送datachange事件。
  2. datachange_notification方法没有实际的输出逻辑,即使触发也不会有任何反馈。

实现方法

你需要订阅Object节点下的所有Variable子节点,而非Object节点本身。以下是两种可行的实现方式:

方式一:手动遍历并订阅所有子Variable节点

先获取Object节点下的所有Variable子节点,再批量订阅这些节点,在Handler中直接打印触发变化的节点和对应值:

from opcua import Client
from opcua.ua import ObjectIds

class SubHandler(object):
    def datachange_notification(self, node, val, data):
        # 打印节点名称和对应的值
        print(f"节点 {node.get_browse_name().Name} 的值更新为: {val}")

client = Client("opc.tcp://1111.1111.1111.1111:1000")
client.connect()

try:
    # 获取目标Object节点
    obj_node = client.get_node("ns=2;ABC")
    # 遍历Object下的所有Variable子节点
    variable_nodes = []
    for child in obj_node.get_children():
        # 判断节点类型是否为Variable
        if child.get_node_class() == ObjectIds.Variable:
            variable_nodes.append(child)
    
    # 创建订阅并绑定Handler
    handler = SubHandler()
    subscription = client.create_subscription(500, handler)
    # 批量订阅所有Variable节点
    handle = subscription.subscribe_data_change(variable_nodes)
    
    # 保持客户端运行,等待接收通知(实际项目中可根据需求用循环或其他方式阻塞)
    input("按回车键退出...\n")
finally:
    # 清理资源
    subscription.unsubscribe(handle)
    subscription.delete()
    client.disconnect()

方式二:利用订阅的include_children参数(需服务器支持)

部分OPC UA服务器支持订阅节点时自动包含其子节点,可通过subscribe_data_change的include_children参数实现:

from opcua import Client

class SubHandler(object):
    def datachange_notification(self, node, val, data):
        print(f"节点 {node.get_browse_name().Name} 的值更新为: {val}")

client = Client("opc.tcp://1111.1111.1111.1111:1000")
client.connect()

try:
    obj_node = client.get_node("ns=2;ABC")
    handler = SubHandler()
    subscription = client.create_subscription(500, handler)
    # 订阅Object节点并指定包含子节点
    handle = subscription.subscribe_data_change(obj_node, include_children=True)
    
    input("按回车键退出...\n")
finally:
    subscription.unsubscribe(handle)
    subscription.delete()
    client.disconnect()

关键说明

  • 方式一兼容性更好,无论服务器是否支持子节点自动订阅都能生效;方式二依赖服务器的支持,部分服务器可能不兼容。
  • 必须确保datachange_notification方法内有明确的输出或处理逻辑,否则即使触发也无法看到效果。
  • 实际项目中,需要保持客户端处于运行状态(示例中用input阻塞,生产环境可使用while True循环或异步事件循环)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:31:03