我想浏览OPC UA服务器上的特定节点,并使用它的方法。我使用open62541堆栈,我想使用一个自定义客户端。我的客户端连接到服务器,然后使用给定的示例浏览某些对象。它向我展示了根文件夹之后的第一层节点--如何找到特定的节点?还是让我浏览到这一点?在open62541项目中是否有一个我看不到的示例文件会打开我的眼睛?
我也找到了"Service_TranslateBrowsePathsToNodeIds“方法,但是我不太确定如何正确地使用它,哪一部分对我来说是有趣的。
举个例子:我想浏览节点"FileSystem",它位于一个比根文件夹更深的层,并且希望使用它的方法createFile。
发布于 2019-10-10 07:03:10
要调用方法,需要两个节点ids:
如果已经具有这些节点ids,则可以立即调用该方法。如果没有,OPC UA通常支持两个获取这些节点ids的选项:
ns=0;i=84)开始,递归地浏览所有子节点,直到找到具有特定浏览名称的节点为止。https://github.com/open62541/open62541/blob/58bd161557111847d068650eff5ad670a9aa0395/examples/client.c#L61TranslateBrowsePathsToNodeIds服务。也就是说,将/Objects/MyDevice/FileSystem/UploadFile (浏览名称的连接)与开始节点根(ns=0;i=84)连接,服务器将返回该特定节点的节点id (如果存在)。此服务采用相对路径,因此也可以使用其他节点作为开始节点async.c#L183。发布于 2022-03-31 15:23:46
经过一些尝试和错误之后,我发现了“魔术”位,可以让它处理服务器命名空间中的节点,例如真实设备,而不是像所有示例中所示的预定义UA节点,如时间戳或服务器状态。下面的代码来自于corpus_generator.c和check_services_view.c文件的Open62541,有两个关键区别:
下面的函数将接受指向UA_Client的指针和形成节点路径的浏览器名向量,从OPC中的Objects文件夹开始。
Node::Node (UA_Client *client, const std::vector<std::string> &browse_path)
: m_client (client)
{
m_id = UA_NODEID_NULL;
// Search for ID in client
UA_BrowsePath browsePath;
UA_BrowsePath_init (&browsePath);
browsePath.startingNode = UA_NODEID_NUMERIC (0, UA_NS0ID_OBJECTSFOLDER);
browsePath.relativePath.elements = (UA_RelativePathElement *)UA_Array_new (browse_path.size (), &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]);
browsePath.relativePath.elementsSize = browse_path.size ();
for (int i = 0; i < browse_path.size (); i++)
{
UA_RelativePathElement *elem = &browsePath.relativePath.elements[i];
elem->targetName = UA_QUALIFIEDNAME_ALLOC (1, browse_path.at (i).c_str ()); // Create in server namespace (1), not UA namespace (0)!
}
UA_TranslateBrowsePathsToNodeIdsRequest request;
UA_TranslateBrowsePathsToNodeIdsRequest_init (&request);
request.browsePaths = &browsePath;
request.browsePathsSize = 1;
UA_TranslateBrowsePathsToNodeIdsResponse response;
response = UA_Client_Service_translateBrowsePathsToNodeIds (m_client, request);
if (UA_STATUSCODE_GOOD == response.responseHeader.serviceResult && response.resultsSize > 0)
{
UA_BrowsePathResult *first = response.results;
if (first->targetsSize >= 1)
{
m_id = first->targets[0].targetId.nodeId;
std::cout << "Found ID";
}
else
{
std::cout << "OK response but no results";
}
}
else
{
std::cout << "Error in translate browsename";
}
UA_BrowsePath_deleteMembers (&browsePath); // Marked as deprecated, but UA_BrowsePath_delete() expects a heap-allocated pointer.
UA_TranslateBrowsePathsToNodeIdsResponse_deleteMembers (&response); // Idem
}https://stackoverflow.com/questions/58316274
复制相似问题