【问题标题】:Browsing OPCUA nodes only working on top level浏览仅在顶层工作的 OPCUA 节点
【发布时间】:2020-02-18 09:13:53
【问题描述】:

我正在使用 OPC UA 项目https://github.com/OPCFoundation/UA-Java。我能够使用UAExpert 浏览OPCUA 服务器上的所有节点。

现在我正在尝试使用我的 java 客户端浏览所有节点。我能够检索节点层次结构第一级中节点的引用,其中 rootnameSpace = 1 和 rootIdentifier = "simsre"

BrowseDescription browse = new BrowseDescription();
browse.setNodeId(new NodeId(rootnameSpace, rootIdentifier));
browse.setBrowseDirection(BrowseDirection.Forward);
browse.setIncludeSubtypes(true);
browse.setNodeClassMask(NodeClass.Object, NodeClass.Variable);
browse.setResultMask(BrowseResultMask.All );
BrowseResponse res = mySession.Browse(null, null, null, browse);
ReferenceDescription[] references = res.getResults()[0].getReferences(); 

当我调用其他节点的代码时,如 rootnameSpace = 31 和 rootIdentifier = "/simsrede/" 下面我仍然得到一个结果但没有引用(所以 res.getResults()[0].getReferences() 返回 null) - browseResponse 的状态码类似于“GOOD” -

根据规范,标识符中允许使用所有 unicode 字符,因此斜杠和“|”不应该是问题。

我还尝试将条目添加到我的命名空间表中,并使用该表在从根节点开始的连续浏览请求中设置节点 ID

NamespaceTable table = NamespaceTable.getDefaultInstance();  
table.add(1, "urn:something:UnifiedAutomation:Uagateway"); 

...
//consecutive browse request starting from reference returned by first call
browse1.setNodeId(table.toNodeId(references[0].getNodeId()));
BrowseResponse res1 = mySession.Browse(null, null, null, browse);
ReferenceDescription[] references1 = res.getResults()[0].getReferences(); 

有人知道为什么会返回空引用,或者如何调试它吗?

【问题讨论】:

  • 你确定这是一个有效的 NodeId 吗?您可以与其他客户端浏览相同的节点吗?你能得到一个 Wireshark 捕获吗?
  • 我忘了提到我能够使用UAExpert浏览节点,并且browseResponse的状态代码类似于GOOD。我会尝试让wireshark 在我的环境中运行——这是检查响应的最佳选择吗?
  • 比较来自 UaExpert 的 Wireshark 捕获与来自您的代码的捕获,以了解您在做什么不同/错误。
  • 另外,来自 OPC 基础的 Java 堆栈也不再维护。你可以考虑github.com/eclipse/milo

标签: java client opc-ua


【解决方案1】:

我使用了浏览功能

Byte[] cp;ReferenceDescriptionCollection refs; m_session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out cp, out refs)
      

如果 refs 来自第一级的节点集合,我会得到。 Foreach 节点我在递归中调用了 Browse 函数,在其中我将节点添加到 OPCTreeNode 的集合中

        public void GetChildNodes(Session sesja, ReferenceDescription Parametr, OPCTreeNode treeNode)
    {
        ReferenceDescriptionCollection nodes;
        byte[] tmpbytes;
        sesja.Browse(null, null, ExpandedNodeId.ToNodeId(Parametr.NodeId, sesja.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out tmpbytes, out nodes);
        foreach (var tmpnode in nodes)
        {
            OPCTreeNode tmpNode = new OPCTreeNode($"{tmpnode.DisplayName}", $"{tmpnode.NodeId}");
            treeNode.ChildTreeNodes.Add(tmpNode);
            GetChildNodes(sesja, tmpnode, tmpNode);
        }
    }

OPCTreeNode 类

    public class OPCTreeNode // element struktury parametrów sesji 
{
    public string DiplayName { get; set; }
    public string NodeId { get; set; }

    public List<OPCTreeNode> ChildTreeNodes;

    public OPCTreeNode()
    {
        ChildTreeNodes = new List<OPCTreeNode>();
    }

    public OPCTreeNode(string displayName, string nodeId)
    {
        this.DiplayName = displayName;
        this.NodeId = nodeId;
        ChildTreeNodes = new List<OPCTreeNode>(); 
    }
}

【讨论】:

    猜你喜欢
    • 2016-11-01
    • 2017-05-04
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-13
    相关资源
    最近更新 更多