184 lines
6.3 KiB
Python
184 lines
6.3 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
"""
|
|||
|
|
节点访问诊断脚本
|
|||
|
|
帮助诊断OPC UA节点访问问题
|
|||
|
|
"""
|
|||
|
|
import sys
|
|||
|
|
import time
|
|||
|
|
|
|||
|
|
# 添加项目路径
|
|||
|
|
sys.path.insert(0, r"d:\f-work\three_control_system\Feeding1129\opc")
|
|||
|
|
|
|||
|
|
from opcua_client_test import OPCUAClientTest
|
|||
|
|
|
|||
|
|
|
|||
|
|
def diagnose_node_access():
|
|||
|
|
"""诊断节点访问问题"""
|
|||
|
|
print("=" * 60)
|
|||
|
|
print("OPC UA 节点访问诊断")
|
|||
|
|
print("=" * 60)
|
|||
|
|
|
|||
|
|
# 创建客户端
|
|||
|
|
client = OPCUAClientTest()
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
# 连接到服务器
|
|||
|
|
print("\n[1] 连接到OPC UA服务器...")
|
|||
|
|
if not client.connect():
|
|||
|
|
print("连接失败!")
|
|||
|
|
return
|
|||
|
|
print("连接成功!")
|
|||
|
|
|
|||
|
|
# 获取对象节点
|
|||
|
|
objects = client.client.get_objects_node()
|
|||
|
|
print(f"\n对象节点: {objects}")
|
|||
|
|
print(f"对象节点ID: {objects.nodeid}")
|
|||
|
|
|
|||
|
|
# 浏览所有子节点
|
|||
|
|
print("\n[2] 浏览对象节点下的所有子节点...")
|
|||
|
|
try:
|
|||
|
|
children = objects.get_children()
|
|||
|
|
print(f"子节点数量: {len(children)}")
|
|||
|
|
for i, child in enumerate(children):
|
|||
|
|
try:
|
|||
|
|
browse_name = child.get_browse_name()
|
|||
|
|
node_id = child.nodeid
|
|||
|
|
print(f" {i+1}. {browse_name} -> {node_id}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" {i+1}. (获取名称失败: {e})")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"浏览子节点失败: {e}")
|
|||
|
|
|
|||
|
|
# 尝试不同的路径格式
|
|||
|
|
print("\n[3] 尝试不同的路径格式访问节点...")
|
|||
|
|
|
|||
|
|
path_formats = [
|
|||
|
|
# 格式1: 使用命名空间前缀
|
|||
|
|
"2:upper/2:upper_weight",
|
|||
|
|
"2:lower/2:lower_weight",
|
|||
|
|
|
|||
|
|
# 格式2: 原始字符串(避免转义问题)
|
|||
|
|
r"2:upper/2:upper_weight",
|
|||
|
|
r"2:lower/2:lower_weight",
|
|||
|
|
|
|||
|
|
# 格式3: 使用列表格式
|
|||
|
|
["2:upper", "2:upper_weight"],
|
|||
|
|
["2:lower", "2:lower_weight"],
|
|||
|
|
|
|||
|
|
# 格式4: 不带命名空间前缀
|
|||
|
|
"upper/upper_weight",
|
|||
|
|
"lower/lower_weight",
|
|||
|
|
["upper", "upper_weight"],
|
|||
|
|
["lower", "lower_weight"],
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
for path in path_formats:
|
|||
|
|
try:
|
|||
|
|
if isinstance(path, list):
|
|||
|
|
node = objects.get_child(path)
|
|||
|
|
else:
|
|||
|
|
node = objects.get_child(path)
|
|||
|
|
|
|||
|
|
browse_name = node.get_browse_name()
|
|||
|
|
value = node.get_value()
|
|||
|
|
print(f" ✓ 成功: {path}")
|
|||
|
|
print(f" 节点: {node}")
|
|||
|
|
print(f" 名称: {browse_name}")
|
|||
|
|
print(f" 值: {value}")
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 找到一个有效的就继续尝试其他格式
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" ✗ 失败: {path}")
|
|||
|
|
print(f" 错误: {e}")
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 尝试方法1:先获取设备对象,再获取变量
|
|||
|
|
print("\n[4] 方法1: 先获取设备对象,再获取变量...")
|
|||
|
|
try:
|
|||
|
|
upper_device = objects.get_child("2:upper")
|
|||
|
|
print(f" 上料斗设备: {upper_device}")
|
|||
|
|
|
|||
|
|
upper_weight = upper_device.get_child("2:upper_weight")
|
|||
|
|
value = upper_weight.get_value()
|
|||
|
|
print(f" ✓ 成功获取上料斗重量: {value}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" ✗ 失败: {e}")
|
|||
|
|
|
|||
|
|
# 尝试方法2:直接使用完整路径
|
|||
|
|
print("\n[5] 方法2: 直接使用完整路径...")
|
|||
|
|
try:
|
|||
|
|
# 注意:这里使用原始字符串避免转义问题
|
|||
|
|
upper_weight = objects.get_child(r"2:upper/2:upper_weight")
|
|||
|
|
value = upper_weight.get_value()
|
|||
|
|
print(f" ✓ 成功获取上料斗重量: {value}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" ✗ 失败: {e}")
|
|||
|
|
|
|||
|
|
# 尝试方法3:使用get_children遍历
|
|||
|
|
print("\n[6] 方法3: 使用get_children遍历查找...")
|
|||
|
|
try:
|
|||
|
|
for child in objects.get_children():
|
|||
|
|
try:
|
|||
|
|
browse_name = str(child.get_browse_name())
|
|||
|
|
if "upper" in browse_name.lower():
|
|||
|
|
print(f" 发现上料斗相关节点: {browse_name} -> {child.nodeid}")
|
|||
|
|
|
|||
|
|
# 尝试获取该节点的子节点
|
|||
|
|
for sub_child in child.get_children():
|
|||
|
|
try:
|
|||
|
|
sub_browse_name = str(sub_child.get_browse_name())
|
|||
|
|
if "weight" in sub_browse_name.lower():
|
|||
|
|
value = sub_child.get_value()
|
|||
|
|
print(f" └─ {sub_browse_name}: {value}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" └─ 获取{sub_browse_name}失败: {e}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" 处理节点失败: {e}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" ✗ 遍历失败: {e}")
|
|||
|
|
|
|||
|
|
# 尝试写入操作
|
|||
|
|
print("\n[7] 尝试写入操作...")
|
|||
|
|
try:
|
|||
|
|
# 找到有效的节点路径
|
|||
|
|
upper_device = objects.get_child("2:upper")
|
|||
|
|
upper_weight = upper_device.get_child("2:upper_weight")
|
|||
|
|
|
|||
|
|
# 写入测试值
|
|||
|
|
test_value = 123.45
|
|||
|
|
upper_weight.set_value(test_value)
|
|||
|
|
print(f" ✓ 成功写入: {test_value}")
|
|||
|
|
|
|||
|
|
# 读取验证
|
|||
|
|
read_value = upper_weight.get_value()
|
|||
|
|
print(f" ✓ 读取验证: {read_value}")
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" ✗ 写入失败: {e}")
|
|||
|
|
import traceback
|
|||
|
|
traceback.print_exc()
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"\n诊断过程出错: {e}")
|
|||
|
|
import traceback
|
|||
|
|
traceback.print_exc()
|
|||
|
|
|
|||
|
|
finally:
|
|||
|
|
try:
|
|||
|
|
client.disconnect()
|
|||
|
|
print("\n[8] 已断开连接")
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
|
|||
|
|
print("\n" + "=" * 60)
|
|||
|
|
print("诊断完成")
|
|||
|
|
print("=" * 60)
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
diagnose_node_access()
|