Adding Nodes

The OPC UA address space consists of a set of nodes interconnected by various types of references. There are two main categories of references: hierarchical and non-hierarchical.

Hierarchical references are used to construct a tree structure of nodes, which is commonly visible in different UI clients.

Non-hierarchical references have a special significance and are used to describe the relationships between nodes. For instance, the HasTypeDefinition reference type is used to define a type with a predefined set of fields.

Node attributes

Every node in OPC UA can be one of the following classes:

  • Variable

  • VariableType

  • Object

  • ObjectType

  • Method

  • View

  • DataType

  • ReferenceType

Each node has a set of attributes that describe it. The full list of attributes is detailed in the OPC-UA specification.

Folder and Variable nodes

The most basic nodes in the address space are Folder and Variable nodes. Folder nodes are used to organize the address space into a tree structure, while Variable nodes are used to store data values.

The SDK provides helper functions to simplify the process of adding Folder and Variable nodes to the address space:

ua.newFolderParams(parentNodeId, nodeName, requestedNodeId)

Function creates a table with parameters for adding a new folder node.

ua.newVariableParams(parentNodeId, nodeName, defaultValue, requestedNodeId)

Function creates a table with parameters for adding a new variable node.

parentNodeId:

( NodeID ) Parent node identifier.

nodeName:

(string) The internal name for the node. This name is used in the TranslateBrowsePathsToNodeIdsservice to resolve NodeId by the path from some nodes.

defaultValue:

(DataValue) The default value for the variable.

requestedNodeId:

( NodeID ) NodeID for the new node. The identifier will be automatically assigned by the server if NodeId equals ua.NodeId.Null.

Adding nodes example

A Variable in OPC-UA is a node in the address space with a set of predefined attributes:

-- Initial value for variables
local dataValue = {
  Value = {UInt32=30000}
}

-- Parameters of new folders and variables
local folderParams = {

  -- #1 TestFolder will be placed under ObjectsFolder with NodeId i=1000
  ua.newFolderParams(ObjectsFolder, "TestFolder", "i=1000"),

  -- #2 Varaibe will be placed under previous TestFolder with NodeId i=1000.
  --    That works because the folder with predefined NodeId is created before
  --    the variable
  ua.newVariableParams("i=1000", "UInt32", dataValue, "i=1001"),

  -- #3 TestFolder1 will be placed under ObjectsFolder.
  --    Its node id will be assigned by the server
  ua.newFolderParams(ObjectsFolder, "TestFolder1"),

  -- #4 Varaibe will be placed under previous Objects Folder.
  --    NodeId will be assigned by the server
  ua.newVariableParams(ObjectsFolder, "UInt32", dataValue),

}

local request = {
  NodesToAdd = {folderParams}
}

local resp, err = server:addNodes(request)

Full source

New node common attributes

To add new object into address space you need to pass a table with the following parameters:

ParentNodeId ( NodeID )

Parent node identifier.

ReferenceTypeId (NodeID)

Parent’s reference type identifier.

RequestedNewNodeId (NodeID)

NodeID for the new node. The identifier will be automatically assigned by the server if NodeId equals ua.NodeId.Null.

BrowseName (QualifiedName)

The internal non-localizable name for the node. This name is used in the TranslateBrowsePathsToNodeIdsservice to resolve NodeId by the path from some nodes.

NodeClass (uint8)

Node equal to ua.Types.NodeClass.Object,

TypeDefinition (NodeID)

Node ID of the object type definition. According this will be created an underlining node hierarcy.

NodeAttributes (ExtensionObject)

An Extension object table with attributes specific to the object node. The follwing sections describes the full set of attributes for different node classes.

Object NodeAttributes

TypeId (NodeID)

Node ID of Object attributes “i=354”

Body (ExtensionObject)

A body of extension object attrubutes:

SpecifiedAttributes = ua.Types.ObjectAttributesMask

DisplayName (LocalizedText)

Clients use this attribute if they want to show the name of the node to the user. Can be localized.

Description (LocalizedText)

The optional description attribute explains the purpose of the node using localized text.

WriteMask (UInt32)

Bit mask. Makes it possible for a client to write the Attributes of the Node.

UserWriteMask (UInt32)

Bit mask. Makes it possible for a client to write the Attributes of the Node.

EventNotifier (Byte)

Event notifier.

Object NodeAttributes example

local folderParams = { -- #1
  ParentNodeId = ObjectsFolder,
  ReferenceTypeId = Organizes,
  RequestedNewNodeId = "i=1000",
  BrowseName = {Name="TestFolder", ns=0},
  NodeClass = ua.Types.NodeClass.Object,
  TypeDefinition = FolderType,
  NodeAttributes = {
    TypeId = "i=354",
    Body = {
      SpecifiedAttributes = ua.Types.ObjectAttributesMask,
      DisplayName = {Text="DisplayName"},
      Description = {Text="Description"},
      WriteMask = 0,
      UserWriteMask = 0,
      EventNotifier = 0,
    }
  }
}