Browse OPC UA Server Namespace

This example shows you how to find OPC Unified Architecture (UA) servers, connect to them, and browse their namespace to find nodes of interest. To run this example in your MATLAB session, you will need to install and start the Prosys OPC UA Simulation Server. Read the Getting Started section of the OPC Toolbox documentation for further information.

OPC UA servers structure available data through one or more namespaces, consisting of multiple connected Nodes. Each namespace has an Index uniquely identifying that namespace. OPC Toolbox exposes two types of OPC UA Nodes: Object nodes, which help to organise data, and Variable nodes which store data in their Value property. Variables nodes may contain other Variable nodes as children.

All OPC UA servers must publish a Server node, containing information about the OPC UA server including capabilities of that server, available functionality of the server and other diagnostic information. The Server node must exist as namespace index 0, named 'Server'. This example will explore the ServerCapabilities node contained in the Server node of an example OPC UA server.

Explore Available OPC UA Servers on a Host

NOTE: This section of this example requires you to install the Local Discovery Service, and configure the Prosys OPC UA Simulation Server to register with the LDS. Instructions for how to do this are included in the Getting Started section of the OPC Toolbox documentation.

OPC UA servers may register with a Local Discovery Service on their host. The Local Discovery Service (LDS) publishes all available servers, as well as their unique "address" (or URL) for connecting to that server.

You can discover OPC UA servers available on a host using opcuaserverinfo. This example uses the local host.

serverList = opcuaserverinfo('localhost')
serverList = 

1×3 OPC UA ServerInfo array:
    index              Description                           Hostname               Port 
    -----  -----------------------------------  ----------------------------------  -----
      1    SimulationServer                     tmopti01win1064.dhcp.mathworks.com  53530
      2    UA Sample Server                     tmopti01win1064                     51210
      3    Quickstart Historical Access Server  tmopti01win1064                     62550

The list of servers shows the available OPC UA servers, and the hostname and port number on which you can connect to the server. You can find a specific server by searching the Description of the servers. Find the server containing the word "Simulation".

sampleServerInfo = findDescription(serverList, 'Simulation')
sampleServerInfo = 

OPC UA ServerInfo 'SimulationServer':

   Connection Information
    Hostname: 'tmopti01win1064.dhcp.mathworks.com'
        Port: 53530

Construct an OPC UA Client and Connect to the Server

In order to browse the server namespace, you need to construct an OPC UA Client and connect that client to the server. If you know the hostname and port of the OPC UA server, you could simply construct an OPC UA Client using the hostname and port arguments.

uaClient = opcua('localhost', 53530);

If you have previously discovered the server using the opcuaserverinfo command, you can construct the client directly from the opcuaserverinfo results.

uaClient = opcua(sampleServerInfo)
uaClient = 

OPC UA Client SimulationServer:
                     Hostname: tmopti01win1064.dhcp.mathworks.com
                         Port: 53530
                      Timeout: 10

                       Status: Disconnected

Initially the client is disconnected from the server, and shows a brief summary of the client properties. You know that the client is disconnected by querying the Status property, or calling the isConnected function.

status = uaClient.Status

isConnected(uaClient)
status =

    'Disconnected'


ans =

  logical

   0

Once you connect the client to the server, additional properties from the server are displayed.

connect(uaClient)
uaClient
uaClient = 

OPC UA Client SimulationServer:
                     Hostname: tmopti01win1064.dhcp.mathworks.com
                         Port: 53530
                      Timeout: 10

                       Status: Connected

                  ServerState: Running

                MinSampleRate: 0 sec
          MaxHistoryReadNodes: 0
      MaxHistoryValuesPerNode: 0
                 MaxReadNodes: 0
                MaxWriteNodes: 0

The display shows that the client Status is now 'Connected', the server is in the 'Running' state, and the client stores information regarding server limits. In this case, all limits are set to zero, indicating that there is no server-wide limit for sample rates, maximum nodes or values for read operations on the Sample Server.

Browsing the Server Namespace

The server namespace is incrementally retrieved directly into the OPC UA Client variable in MATLAB. You access the top level of the server namespace using the Namespace property. This property stores OPC UA Nodes. Each node can contain one or more Children, which are themselves nodes.

topNodes = uaClient.Namespace
topNodes = 

1x6 OPC UA Node array:
    index           Name            NsInd        Identifier         NodeType  Children
    -----  -----------------------  -----  -----------------------  --------  --------
      1    Server                   0      2253                     Object    12
      2    MyObjects                2      MyObjectsFolder          Object    1
      3    StaticData               3      StaticData               Object    9
      4    NonUaNodeComplianceTest  4      NonUaNodeComplianceTest  Object    33
      5    Simulation               5      85/0:Simulation          Object    7
      6    MyBigNodeManager         6      MyBigNodeManager         Object    1000

The node named 'Server' contains 12 children.

You can search the namespace using indexing into the Children property of available nodes. For example, to find the ServerCapabilities node, you can query the Children of the Server node.

serverChildren = topNodes(1).Children
serverChildren = 

1x12 OPC UA Node array:
    index         Name          NsInd  Identifier  NodeType  Children
    -----  -------------------  -----  ----------  --------  --------
      1    ServerStatus         0      2256        Variable  6
      2    ServerCapabilities   0      2268        Object    14
      3    ServerDiagnostics    0      2274        Object    4
      4    VendorServerInfo     0      2295        Object    0
      5    ServerRedundancy     0      2296        Object    5
      6    Namespaces           0      11715       Object    1
      7    ServerConfiguration  0      12637       Object    5
      8    NamespaceArray       0      2255        Variable  0
      9    Auditing             0      2994        Variable  0
     10    ServerArray          0      2254        Variable  0
     11    EstimatedReturnTime  0      12885       Variable  0
     12    ServiceLevel         0      2267        Variable  0

The ServerCapabilities node is the second node in the list.

serverCapabilities = serverChildren(2)
serverCapabilities = 

OPC UA Node object:
                      Name: ServerCapabilities
               Description: Describes capabilities supported by the server.
            NamespaceIndex: 0
                Identifier: 2268
                  NodeType: Object

                    Parent: Server
                  Children: 14 nodes.

Searching for Nodes in the Namespace

You can search for nodes from a Node variable, or from the Namespace property directly. To find the 'ServerCapabilities' node without indexing into the Namespace property, use findNodeByName. To avoid the search finding all instances of nodes containing the word 'ServerCapabilities' you use the '-once' parameter.

serverCapabilities = findNodeByName(topNodes, 'ServerCapabilities', '-once')
serverCapabilities = 

OPC UA Node object:
                      Name: ServerCapabilities
               Description: Describes capabilities supported by the server.
            NamespaceIndex: 0
                Identifier: 2268
                  NodeType: Object

                    Parent: Server
                  Children: 14 nodes.

To find all nodes containing the word 'Double' in the Name, query all topNodes using the '-partial' parameter. Note that this search will load the entire namespace into MATLAB, so use this search method with caution.

doubleNodes = findNodeByName(topNodes, 'Double', '-partial')
doubleNodes = 

1x6 OPC UA Node array:
    index          Name           NsInd       Identifier        NodeType  Children
    -----  ---------------------  -----  ---------------------  --------  --------
      1    Double                 4      Double                 Variable  0
      2    DoubleAnalogItemArray  3      DoubleAnalogItemArray  Variable  3
      3    DoubleAnalogItem       3      DoubleAnalogItem       Variable  3
      4    DoubleDataItem         3      DoubleDataItem         Variable  1
      5    DoubleArray            3      DoubleArray            Variable  0
      6    Double                 3      Double                 Variable  0

Understanding the NodeType

Nodes have a NodeType which describes whether that node is simply an organisational unit (an Object NodeType) or contains data that can be read or written (a Variable NodeType). An example of an Object node is tha ServerCapabilities node shown above. You cannot read data from an Object node. In this example, doubleNodes contains no Object nodes, and 6 Variable nodes.

allNodeTypes = {doubleNodes.NodeType}
allNodeTypes =

  1×6 cell array

  Columns 1 through 4

    {'Variable'}    {'Variable'}    {'Variable'}    {'Variable'}

  Columns 5 through 6

    {'Variable'}    {'Variable'}

Variable NodeTypes may contain Children - A NodeType of Variable does not guarantee that the node contains no Children. The second node listed is a variable node (and so its Value can can be read) but also has children (which can be read individually). For information on reading values from a node, see readValue.

Understanding Variable NodeType Properties

A Variable node has additional properties describing the data stored in the Variable node, including the server data type and access permissions for that node. To view these properties, display a Variable node.

doubleNodes(2)
ans = 

OPC UA Node object:
                      Name: DoubleAnalogItemArray
               Description: 
            NamespaceIndex: 3
                Identifier: DoubleAnalogItemArray
                  NodeType: Variable

                    Parent: AnalogItemArrays
                  Children: 3 nodes.

            ServerDataType: Double
        AccessLevelCurrent: read/write
        AccessLevelHistory: none
               Historizing: 0

This node has a ServerDataType of 'Double', and allows reading and writing of the Current value (AccessLevelCurrent property) but supports no historical data reading (AccessLevelHistory). The server is not Historizing this node, as evidenced by the Historizing property.

Some properties, such as ServerValueRank, and ServerArrayDimensions are not shown in the display of a node, but can be queried through the respective property. See help on these properties for further information.

doubleNodes(2).ServerArrayDimensions
ans =

  uint32

   0

Constructing Nodes Directly

Nodes are defined uniquely by their NamespaceIndex and their Identifier. You can construct a known node without browsing the Namespace property using the opcuanode function. For example, to construct the ServerCapabilities node directly you can use the NamespaceIndex 0 and Identifier 2268 (all OPC UA servers must publish a ServerCapabilities node with this NamespaceIndex and Identifier).

capabilitiesNode = opcuanode(0, 2268, uaClient)
capabilitiesNode = 

OPC UA Node object:
                      Name: ServerCapabilities
               Description: Describes capabilities supported by the server.
            NamespaceIndex: 0
                Identifier: 2268
                  NodeType: Object

                  Children: 14 nodes.

Note that nodes constructed using opcuanode have no Parent property.

capabilitiesNode.Parent
ans = 

Empty OPC UA Node object.

However their Children are automatically retrieved if the node is associated with a connected OPC UA Client.

capabilitiesNode.Children
ans = 

1x14 OPC UA Node array:
    index              Name              NsInd  Identifier  NodeType  Children
    -----  ----------------------------  -----  ----------  --------  --------
      1    ModellingRules                0      2996        Object    6
      2    AggregateFunctions            0      2997        Object    14
      3    HistoryServerCapabilities     0      11192       Object    15
      4    OperationLimits               0      11704       Object    12
      5    LocaleIdArray                 0      2271        Variable  0
      6    MinSupportedSampleRate        0      2272        Variable  0
      7    MaxQueryContinuationPoints    0      2736        Variable  0
      8    MaxByteStringLength           0      12911       Variable  0
      9    ServerProfileArray            0      2269        Variable  0
     10    MaxHistoryContinuationPoints  0      2737        Variable  0
     11    SoftwareCertificates          0      3704        Variable  0
     12    MaxStringLength               0      11703       Variable  0
     13    MaxBrowseContinuationPoints   0      2735        Variable  0
     14    MaxArrayLength                0      11702       Variable  0

Disconnect from Server

When you have finished communicating with the server, you should disconnect the client from the server. This is also automatically performed when the client variable goes out of scope in MATLAB.

disconnect(uaClient);