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()
|