2. OPC UA 客户端连接测试

任务目标

本案例要求使用 OPC UA 客户端连接网关上的 OPC UA 服务器,并读取服务器状态(如启动时间、当前时间、软件版本等)。通过本案例验证网关 OPC UA 服务是否正常监听、认证配置是否正确,为后续数据读写操作建立连接基础。

环境与依赖

  • 网关已启用 OPC UA 服务器功能,默认端口 4840,端点地址为 opc.tcp://<网关IP>:4840
  • 客户端环境:Python 3.8+,安装 opcua 库(pip install opcua)
  • 若网关启用了匿名访问限制,需提前在网关侧创建用户并配置相应权限

关键完整代码

以下 Python 脚本实现 OPC UA 客户端连接、读取服务器状态节点,并输出结果:

from opcua import Client
import sys

def read_server_status(endpoint_url):
    client = Client(endpoint_url)
    try:
        client.connect()
        print(f"[OK] 已连接: {endpoint_url}")

        # 读取服务器状态节点(标准节点ID)
        server_status = client.get_node("ns=0;i=2256")  # ServerStatus 对象
        # 子节点:启动时间、当前时间、状态、构建信息等
        start_time = server_status.get_child(["0:StartTime"])
        current_time = server_status.get_child(["0:CurrentTime"])
        state = server_status.get_child(["0:State"])
        build_info = server_status.get_child(["0:BuildInfo"])

        print(f"启动时间: {start_time.get_value()}")
        print(f"当前时间: {current_time.get_value()}")
        print(f"服务器状态: {state.get_value()} (0=运行中, 1=维护中)")

        # 读取软件版本(BuildInfo 子节点)
        product_uri = build_info.get_child(["0:ProductUri"])
        software_version = build_info.get_child(["0:SoftwareVersion"])
        print(f"产品URI: {product_uri.get_value()}")
        print(f"软件版本: {software_version.get_value()}")

        # 读取命名空间数组,确认服务器已加载信息模型
        ns_array = client.get_node("ns=0;i=2255").get_value()
        print(f"命名空间数量: {len(ns_array)}")
        for i, ns in enumerate(ns_array):
            print(f"  [{i}] {ns}")

    except Exception as e:
        print(f"[FAIL] 连接或读取失败: {e}")
        sys.exit(1)
    finally:
        client.disconnect()
        print("[INFO] 连接已关闭")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("用法: python opcua_client_test.py opc.tcp://<网关IP>:4840")
        sys.exit(1)
    read_server_status(sys.argv[1])

运行方式

pip install opcua
python opcua_client_test.py opc.tcp://192.168.1.100:4840

将 192.168.1.100 替换为实际网关 IP 地址。若网关启用了用户名/密码认证,需在代码中 client.connect() 前添加:

client.set_security_string("Basic256Sha256,SignAndEncrypt")
client.set_user("username")
client.set_password("password")

验证方法与判定标准

  • 连接成功标志:脚本输出 [OK] 已连接,且无异常堆栈
  • 状态读取成功:能打印出启动时间、当前时间、服务器状态为 0(运行中)
  • 版本信息完整:软件版本号与网关固件版本一致(可在网关 Web 管理页面核对)
  • 命名空间输出:至少包含 http://opcfoundation.org/UA/ 和网关自定义的命名空间 URI

若脚本在 connect() 阶段报错,请依次检查:网关 IP 是否可达(ping)、端口 4840 是否开放(telnet <IP> 4840)、网关 OPC UA 服务是否已启用、安全策略是否匹配(默认无加密则注释掉 set_security_string 行)。

常见问题

  • BadSecurityModeRejected:客户端与服务器安全策略不一致,注释安全设置或改为 None
  • BadUserAccessDenied:用户名密码错误或该用户无访问权限,检查网关用户配置
  • 连接超时:确认网关 IP 和端口正确,且网关防火墙未拦截 4840 端口