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 = { Type = ua.VariantType.UInt32, Value=30000, StatusCode = ua.StatusCode.Good } -- 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)
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.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.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.NodeClass.Object,
  TypeDefinition = FolderType,
  NodeAttributes = {
    TypeId = "i=354",
    Body = {
      SpecifiedAttributes = ua.ObjectAttributesMask,
      DisplayName = {Text="DisplayName"},
      Description = {Text="Description"},
      WriteMask = 0,
      UserWriteMask = 0,
      EventNotifier = 0,
    }
  }
}