OPC UA调用Sinumerik机床Filehandling/Select方法遇BadNodeIdUnknown异常求助
问题场景
我基于OPC Foundation SDK开发的OPC UA客户端已成功连接Sinumerik系统机床的服务器,并实现了部分功能,但在调用Methods/Filehandling/Select方法选择已有零件程序时遇到问题:所有节点ID验证有效,但Call操作返回BadNodeIdUnknown异常。
尝试的代码
NodeId objectId = new NodeId("ns=2;s=/Methods/Filehandling"); NodeId methodId = new NodeId("ns=2;s=/Methods/Filehandling/Select"); inputArguments[0] = "Sinumerik/FileSystem/Part Program/000_TEST_OPC_2.MPF"; inputArguments[1] = 1; // 验证节点ID有效性 var resultobject = CorrespondingOPCNode.CorrespondingSession.ReadNode(objectId); var resultmethod = CorrespondingOPCNode.CorrespondingSession.ReadNode(methodId); var resultFile = CorrespondingOPCNode.CorrespondingSession.ReadNode(new NodeId("ns=2;s=" +(string)inputArguments[0])); IList<object> results = CorrespondingOPCNode.CorrespondingSession!.Call(resultobject.NodeId, resultmethod.NodeId, inputArguments.ToArray());
排查信息
- 节点ID验证:通过
ReadNode确认objectId、methodId以及零件程序的节点ID均有效,能返回正常节点信息。 - UaExpert对比:用UaExpert交互式调用该方法时,参数与代码完全一致,调用成功,日志如下:
12:44:35.189Z|6|4A38* --> UaSession::call [Session=1]
12:44:35.189Z|7|4A38* ObjectId: ns=2;s=/Methods/Filehandling
12:44:35.189Z|7|4A38* MethodId: ns=2;s=/Methods/Filehandling/Select
12:44:35.189Z|7|4A38* Number of InputArguments: 2
12:44:35.189Z|7|4A38* Argument[0] = Sinumerik/FileSystem/Part Program/000_TEST_OPC_2.MPF
12:44:35.189Z|7|4A38* Argument[1] = 1
12:44:35.189Z|4|4A38* CALL OpcUa_ClientApi_Call [Session=1]
12:44:35.252Z|4|4A38* DONE OpcUa_ClientApi_Call [ret=0x0,status=0x0]
12:44:35.252Z|7|4A38* Number of NoOfInputArgumentResults: 2
12:44:35.252Z|7|4A38* InputArgumentResults[0] = Good
12:44:35.253Z|7|4A38* InputArgumentResults[1] = Good
12:44:35.253Z|7|4A38* Number of NoOfOutputArguments: 1
12:44:35.253Z|7|4A38* OutputArguments[0] = 0
- 抓包对比:Wireshark抓包发现代码传递的输入参数类型与UaExpert存在差异,但不解为何服务器返回的是
BadNodeIdUnknown而非BadInvalidArgument。
解决建议
1. 避免NodeId的中间转换
代码中使用resultobject.NodeId和resultmethod.NodeId作为Call的参数,虽然ReadNode返回的节点有效,但可能存在SDK隐式转换(比如将字符串标识符转为数值型),导致服务器无法识别。直接使用最初创建的objectId和methodId调用:
IList<object> results = CorrespondingOPCNode.CorrespondingSession!.Call(objectId, methodId, inputArguments.ToArray());
2. 严格匹配参数类型
根据UaExpert的调用行为和服务器方法定义,修正参数类型:
- 第二个参数
1在UaExpert中大概率是UInt32类型,代码中需显式转换:inputArguments[1] = (uint)1; - 确认第一个参数的路径字符串是否需要转义特殊字符(如空格),或是否需要传入对应文件的NodeId而非路径字符串(部分服务器可能有此要求)。
3. 检查方法绑定规则
Sinumerik的OPC UA服务器可能对Filehandling/Select方法的调用有特殊绑定要求:
- 确认该方法是否必须绑定到特定对象节点(而非通用的
/Methods/Filehandling),比如当前机床的文件系统节点。 - 查阅Sinumerik OPC UA服务器官方文档,确认
Select方法的正确调用对象、参数类型和格式。
4. 启用客户端详细日志
开启OPC Foundation SDK的详细日志,对比Call请求的完整节点ID、参数信息与UaExpert的请求,定位节点ID传递过程中的差异。
内容的提问来源于stack exchange,提问作者ThomasH

