VWED_server/tests/test_opc_ua_quick.py

247 lines
9.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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()