247 lines
9.0 KiB
Python
247 lines
9.0 KiB
Python
#!/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() |