我正在尝试使用 OPC-UA 在基于 sinumerik 的机器上选择现有零件程序。我编写了一个应用程序来连接到服务器,等等,使用 OPC Foundation 模型和示例应用程序 - 到目前为止工作正常。
一个问题是访问函数Methods/Filehandling/Select
我已经在互联网上做了一些研究,发现了几个与该问题有关的未解答的问题。
我尝试使用以下方法:
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;
//verify, the nodeIds are Valid
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 均有效,但“调用”返回“BadNodeIdUnknown”异常,我无法弄清楚原因。在以交互方式调用方法后,我还查看了 UaExpert 的日志,详细显示了调用输入:
12:44:35.189Z|6|4A38* --> UaSession::call [会话=1] 12:44:35.189Z|7|4A38* 对象 ID: ns=2;s=/方法/文件处理 12:44:35.189Z|7|4A38* MethodId: ns=2;s=/Methods/Filehandling/Select 12:44:35.189Z|7|4A38* 输入参数数量:2 12:44:35.189Z|7|4A38* 参数 [0] = Sinumerik/FileSystem/Part Program/000_TEST_OPC_2.MPF 12:44:35.189Z|7|4A38* 参数 = 1 12:44:35.189Z|4|4A38* 调用 OpcUa_ClientApi_Call [会话=1] 12:44:35.252Z|4|4A38* 完成 OpcUa_ClientApi_Call [ret=0x0,状态=0x0] 12:44:35.252Z|7|4A38* NoOfInputArgumentResults 数量:2 12:44:35.252Z|7|4A38* 输入参数结果[0] = 好 12:44:35.253Z|7|4A38* 输入参数结果 = 好 12:44:35.253Z|7|4A38* NoOfOutputArguments 数量:1 12:44:35.253Z|7|4A38* 输出参数[0] = 0
有人有什么建议吗?如何调用该方法? 预先感谢!
编辑:按照建议,我用wireshark进行了跟踪:
很明显输入参数的类型存在问题 - 但这应该会导致 BadInvalidArgument 异常?
感谢@Kevin Herron 和他的建议,我发现频道编号的传输值为“1”,即 Int32,其中预期为 UInt32。所以我将代码更改为以下(调试状态,显示差异)
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;
var resultobject = CorrespondingOPCNode.CorrespondingSession.ReadNode(objectId);
var resultmethod = CorrespondingOPCNode.CorrespondingSession.ReadNode(methodId);
var refs = resultmethod.References;
var resultFile = CorrespondingOPCNode.CorrespondingSession.ReadNode(new NodeId("ns=2;s=" + (string)inputArguments[0]));
inputArguments[0] = resultFile.NodeId;
inputArguments[1] = (UInt32)1;
IList<object> results = CorrespondingOPCNode.CorrespondingSession!.Call(resultobject.NodeId,
resultmethod.NodeId, inputArguments.ToArray());
所以除了更改
inputArguments[0] = resultFile.NodeId;
(我之前已经尝试过但没有成功)之外,问题是正确格式化inputArguments[1] = (UInt32)1;
。
我仍然不明白的是,为什么错误消息是“BadNodeIdUnknown”,我想可能是因为传输的参数类型与任何现有函数不匹配...... 无论如何。它的工作方式是这样的。感谢大家的帮助!