1

I made a test program (altered this code) to browse into nodes from my opc ua server (siemens s7-1200):

using (var session = Session.Create(config, new ConfiguredEndpoint(null, selectedEndpoint, EndpointConfiguration.Create(config)), false, "", 60000, null, null).GetAwaiter().GetResult())
        {
            Console.WriteLine("Step 3 - Browse the server namespace.");
            ReferenceDescriptionCollection refs;
            byte[] bts;
            session.Browse(null, null, ObjectIds.ObjectsFolder, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out bts, out refs);
            Console.WriteLine("DisplayName: BrowseName, NodeClass");
            foreach (var rd in refs.Where(r => r.DisplayName == "ServerInterfaces"))
            {
                Console.WriteLine("{0}: {1}, {2}", rd.DisplayName, rd.BrowseName, rd.NodeClass);
                ReferenceDescriptionCollection refs2;
                byte[] bts2;
                session.Browse(null, null, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out bts2, out refs2);
                foreach (var nextRd in refs2)
                {
                    ReferenceDescriptionCollection refs3;
                    byte[] bts3;
                    Console.WriteLine("NameSpace+ {0}: {1}, {2}", nextRd.DisplayName, nextRd.BrowseName, nextRd.NodeClass);
                    session.Browse(null, null, ExpandedNodeId.ToNodeId(nextRd.NodeId, session.NamespaceUris), 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Variable | (uint)NodeClass.Object | (uint)NodeClass.Method, out bts3, out refs3);
                    foreach (var nextRd2 in refs3.Where(n => n.DisplayName != "Icon"))
                    {

                        NodeId nodeId = new NodeId(nextRd2.NodeId.ToString());
                        var value = session.ReadValue(nodeId);
                        Console.WriteLine("Node+ {0}: {1}, {2}, NodeId = {3}, Value = {4}", nextRd2.DisplayName, nextRd2.BrowseName, nextRd2.NodeClass, nextRd2.NodeId, value);
                    }
                }
            }

The problem I am facing is arrays. I have an array of INTs in my OPC ua server. Currently this is what the console displays:

ServerInterfaces: 3:ServerInterfaces, Object
NameSpace+ Server interface_1: 4:Server interface_1, Object
Node+ read: 4:read, Variable, NodeId = ns=4;i=2, Value = (null)
Node+ IntValue1: 4:IntValue1, Variable, NodeId = ns=4;i=7, Value = 100

This is my expected output:

ServerInterfaces: 3:ServerInterfaces, Object
NameSpace+ Server interface_1: 4:Server interface_1, Object
Node+ read: 4:read, Variable, NodeId = ns=4;i=2, Value = (null)
Node+ read: 4:read[0], Variable, NodeId = ns=4;i=3, Value = 1
Node+ read: 4:read[1], Variable, NodeId = ns=4;i=4, Value = 1
Node+ read: 4:read[2], Variable, NodeId = ns=4;i=5, Value = 1
Node+ read: 4:read[3], Variable, NodeId = ns=4;i=6, Value = 1
Node+ IntValue1: 4:IntValue1, Variable, NodeId = ns=4;i=7, Value = 100

How to alter this code (or new code) to get the expected output?

interface

w

raead

I made another program to get every node. The weird thing is I can get an array from some automaticaly generated content:

ServerProfileArray: System.String[]
                    [0] Variable = http://opcfoundation.org/UA-Profile/Server/StandardUA
                    [1] Variable = http://opcfoundation.org/UA-Profile/Server/Methods
                    [2] Variable = http://opcfoundation.org/UA-Profile/Server/StandardEventSubscription
                    [3] Variable = http://opcfoundation.org/UA-Profile/Server/DataAccess

But when I goes by my "read" it still doesn't display the array items:

read
                read:

TIA portal: tiaportal

Victor Pieper
  • 540
  • 2
  • 17
  • Can you add an screenshot of the address space ? E.g. with the unexpert? One thing I noticed: you use the displayname for selecting. The browsename is better for that because it is not localized – SFriedl Mar 28 '23 at 10:02
  • @SFriedl I added some info – Victor Pieper Mar 28 '23 at 10:05

1 Answers1

1

I figured it out sort off so better answer are still appreciated (:

Using: var references = session.FetchReferences(nodeId); You can get all references from a node. You will also get more info that you might not need but you can filter that out later.

foreach (var ref3 in refs3.Where(n => n.DisplayName != "Icon"))
                    {

                        NodeId nodeId = new NodeId(ref3.NodeId.ToString());
                        var value = session.ReadValue(nodeId);
                        Console.WriteLine("----------------------");
                        Console.WriteLine("Node+ {0}: {1}, {2}, NodeId = {3}, Value = {4}", ref3.DisplayName, ref3.BrowseName, ref3.NodeClass, ref3.NodeId, value);
                        var references = session.FetchReferences(nodeId);
                        if (references != null)
                        {
                            Console.WriteLine("array");
                            foreach (var reference in references.Where(r => r.NodeClass.ToString() == "Variable"))
                            {
                                Console.WriteLine(reference.BrowseName + " NodeId: " + reference.NodeId.ToString());
                            }
                        }
                        Console.WriteLine("----------------------");
                    }

Output:

Node+ read: 4:read, Variable, NodeId = ns=4;i=2, Value = (null)
array
4:[0] NodeId: ns=4;i=3
4:[1] NodeId: ns=4;i=4
4:[2] NodeId: ns=4;i=5
4:[3] NodeId: ns=4;i=6

Edit: Made something better.

When you input a nodeId you get the HierarchicalReferences beneath it, when you input a nodeId (from the array) and put array on true you get the arrayitems beneath it.

public ReferenceDescriptionCollection BrowseNode(string nodeId, bool array = false)
        {
            NodeId expandedNodeId = ExpandedNodeId.ToNodeId(nodeId, Session.NamespaceUris);
            NodeClass nodeClass = array ? NodeClass.Variable : (NodeClass.Variable | NodeClass.Object | NodeClass.Method);
            NodeId referenceType = array ? ReferenceTypeIds.HasComponent : ReferenceTypeIds.HierarchicalReferences;

            Session.Browse(
                null,
                null,
                expandedNodeId,
                0u,
                BrowseDirection.Forward,
                referenceType,
                true,
                (uint)nodeClass,
                out _,
                out ReferenceDescriptionCollection references
            );

            if (array && references.Count == 0)
            {
                return null;
            }

            return references;
        }
Victor Pieper
  • 540
  • 2
  • 17