#!/usr/bin/env python # -*- coding: utf-8 -*- """ OPC UA模块快速测试 简单验证OPC UA内置函数模块的基本功能 """ import sys import os import time # 添加项目根目录到路径 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from services.online_script.built_in_modules.opc_ua_module import VWEDOpcUaModule from tests.test_opc_ua_server import OpcUaTestServer def test_basic_functionality(): """测试基本功能""" print("=" * 60) print("OPC UA模块基本功能测试") print("=" * 60) # 1. 启动测试服务器 print("\n1. 启动OPC UA测试服务器...") server = OpcUaTestServer(host='localhost', port=4840) try: server.start_server() time.sleep(2) # 等待服务器启动 server_info = server.get_server_info() endpoint = server_info['endpoint'] namespace_idx = server_info['namespace_index'] print(f" 服务器端点: {endpoint}") print(f" 命名空间索引: {namespace_idx}") print(" 服务器启动成功!") # 2. 创建OPC UA模块实例 print("\n2. 创建OPC UA模块实例...") opc_module = VWEDOpcUaModule("test_script") print(" 模块实例创建成功!") # 3. 测试读取功能 print("\n3. 测试读取功能...") # 测试读取整数节点 try: value = opc_module.read_opc_value_with_namespace(namespace_idx, "i=1001", endpoint) print(f" ✓ 读取整数节点: ns={namespace_idx};i=1001 = {value}") except Exception as e: print(f" ✗ 读取整数节点失败: {e}") # 测试读取字符串节点 try: value = opc_module.read_opc_value_with_namespace(namespace_idx, "s=StringNodeId", endpoint) print(f" ✓ 读取字符串节点: ns={namespace_idx};s=StringNodeId = {value}") except Exception as e: print(f" ✗ 读取字符串节点失败: {e}") # 测试读取动态节点 try: value = opc_module.read_opc_value_with_namespace(namespace_idx, "Counter", endpoint) print(f" ✓ 读取计数器节点: ns={namespace_idx};Counter = {value}") except Exception as e: print(f" ✗ 读取计数器节点失败: {e}") # 4. 测试写入功能 print("\n4. 测试写入功能...") try: # 先读取原始值 original_value = opc_module.read_opc_value_with_namespace(namespace_idx, "i=1001", endpoint) print(f" 原始值: {original_value}") # 写入新值 new_value = 12345 result = opc_module.write_opc_value_with_namespace(namespace_idx, "i=1001", new_value, endpoint) print(f" ✓ 写入新值 {new_value}: {result}") # 验证写入 written_value = opc_module.read_opc_value_with_namespace(namespace_idx, "i=1001", endpoint) print(f" ✓ 验证写入值: {written_value}") if written_value == new_value: print(" ✓ 写入验证成功!") else: print(" ✗ 写入验证失败!") # 恢复原始值 opc_module.write_opc_value_with_namespace(namespace_idx, "i=1001", original_value, endpoint) print(f" ✓ 恢复原始值: {original_value}") except Exception as e: print(f" ✗ 写入测试失败: {e}") # 5. 测试订阅功能 print("\n5. 测试订阅功能...") try: # 创建订阅 value1 = opc_module.read_opc_value_by_subscription(namespace_idx, "Counter", endpoint) print(f" ✓ 订阅计数器(第一次): {value1}") # 等待值变化 print(" 等待3秒让值发生变化...") time.sleep(3) # 再次读取订阅值 value2 = opc_module.read_opc_value_by_subscription(namespace_idx, "Counter", endpoint) print(f" ✓ 订阅计数器(第二次): {value2}") if value1 != value2: print(" ✓ 订阅功能正常,值发生了变化!") else: print(" ! 订阅功能可能有问题,值没有变化") except Exception as e: print(f" ✗ 订阅测试失败: {e}") # 6. 测试错误处理 print("\n6. 测试错误处理...") # 测试读取不存在的节点 try: opc_module.read_opc_value_with_namespace(namespace_idx, "i=99999", endpoint) print(" ✗ 应该抛出异常但没有抛出") except RuntimeError as e: if str(e) == "read_opc_value error": print(" ✓ 正确处理不存在节点的错误") else: print(f" ! 异常消息不正确: {e}") except Exception as e: print(f" ! 异常类型不正确: {e}") # 7. 显示动态数据 print("\n7. 监控动态数据(5秒)...") start_time = time.time() while time.time() - start_time < 5: try: counter = opc_module.read_opc_value_with_namespace(namespace_idx, "Counter", endpoint) temp = opc_module.read_opc_value_with_namespace(namespace_idx, "Temperature", endpoint) bool_val = opc_module.read_opc_value_with_namespace(namespace_idx, "BooleanVariable", endpoint) timestamp = time.strftime('%H:%M:%S') print(f" [{timestamp}] 计数器: {counter}, 温度: {temp:.2f}°C, 布尔值: {bool_val}") time.sleep(1) except Exception as e: print(f" 监控错误: {e}") break # 8. 清理资源 print("\n8. 清理资源...") opc_module.cleanup() print(" ✓ OPC UA模块资源清理完成") print("\n" + "=" * 60) print("✓ 基本功能测试完成!") print("=" * 60) except Exception as e: print(f"测试过程中发生错误: {e}") import traceback traceback.print_exc() finally: # 停止服务器 print("\n停止测试服务器...") server.stop_server() print("测试服务器已停止") def show_server_info(): """显示服务器信息""" print("=" * 60) print("OPC UA测试服务器信息") print("=" * 60) server = OpcUaTestServer(host='localhost', port=4840) try: server.start_server() time.sleep(2) server_info = server.get_server_info() node_info = server.get_node_info() print(f"\n服务器信息:") print(f" 端点: {server_info['endpoint']}") print(f" 主机: {server_info['host']}") print(f" 端口: {server_info['port']}") print(f" 运行状态: {server_info['running']}") print(f" 命名空间索引: {server_info['namespace_index']}") print(f"\n可用测试节点:") if node_info: for name, info in node_info.items(): node_id_full = f"ns={info['namespace_index']};{info['node_id']}" print(f" {name}:") print(f" NodeId: {node_id_full}") print(f" 值: {info['value']} ({info['data_type']})") print(f"\n使用示例:") print(f"# Python代码示例") print(f"from services.online_script.built_in_modules.opc_ua_module import VWEDOpcUaModule") print(f"opc = VWEDOpcUaModule('test')") print(f"") print(f"# 读取整数节点") print(f"value = opc.read_opc_value_with_namespace({server_info['namespace_index']}, 'i=1001', '{server_info['endpoint']}')") print(f"print(f'整数节点值: {{value}}')") print(f"") print(f"# 写入值") print(f"result = opc.write_opc_value_with_namespace({server_info['namespace_index']}, 'i=1001', 8888, '{server_info['endpoint']}')") print(f"print(f'写入结果: {{result}}')") print(f"") print(f"# 订阅读取") print(f"value = opc.read_opc_value_by_subscription({server_info['namespace_index']}, 'Counter', '{server_info['endpoint']}')") print(f"print(f'订阅值: {{value}}')") except Exception as e: print(f"启动服务器失败: {e}") finally: server.stop_server() def main(): """主函数""" print("VWED OPC UA模块测试工具") print("请选择操作:") print("1. 运行基本功能测试") print("2. 显示服务器信息和使用示例") choice = input("请输入选择 (1 或 2, 默认1): ").strip() if choice == "2": show_server_info() else: test_basic_functionality() if __name__ == "__main__": main()