Editor

Editor is returned by ua.Model:edit() method. It is used to edit the address space. It has same interface as browser with additional methods to add new nodes to the model.

To save changes to the model you should call editor.save() method. Without saving changes are not committed to the model.

Objects returned from the following methods editor.addXXX() have same interface as objects returned from ua.Model:browse() method plus additional methods to edit the node. All changes made to them are saved in the editor and will be committed to the model when you call editor.save() method.

editor.addObject(browseName, objectType, nodeId, refType)

Add an object to the model under ObjectsFolder node.

BrowseName:

QualifiedName or String Name of the object.

ObjectType:

NodeID | ObjectType object. Object type which will be used as a template for the new object. The hierarchy of object type will be expanded.

NodeId:

Node ID for the new object. If not provided, then new Node ID is generated.

RefType:

Reference type of the object.

Can be:
  • NodeID of the reference type

  • String with name of the reference type

  • Reference Type object

  • nil - then HasComponent reference type is used.

Example:

1  local object = editor:addObject("Sensor")
2  object:addVariable("Temperature", {Type=ua.VariantType.Double, Value=20})

Full source

editor.addObjectType(browseName)

Add an object type to the model.

BrowseName:

QualifiedName or String Name of the object.

Returns:

ObjectType

Example:

1-- Add a sensor object type. This object type will be used
2-- to create instances of sensors.
3local sensorObjectType = modelEditor:addObjectType("SensorType")
4-- Add a property to the sensor object type
5local addressProp = sensorObjectType:addProperty("Address",
6    {Type = ua.VariantType.Int32, Value = 1})
7
8local objectsFolder = modelEditor:objectsFolder()
9local sensorFolder = objectsFolder:addFolder("Sensors")

Full source

editor.addVariableType(browseName)

Add a variable type to the model.

Returns:

VariableType

Example:

1-- Add a variable type for the sensor data
2-- Variables of this type will have root node with structured value and
3-- underlying hierarchy of fields will be expanded.
4local sensorVariableDataType = modelEditor:addVariableType("SensorVariableDataType", nil, sensorDataType)
5-- Add a variable to the sensor object type
6local sensorDataVariable = sensorObjectType:addVariable("Data", nil, sensorVariableDataType)
7sensorDataVariable.Attrs.Description = {Text="Current measured sensor data"}

Full source

editor.addReferenceType(browseName)

Add a reference type to the model.

Returns:

Reference Type

editor.addEnum(browseName, values, nodeId)

Add an enum to the model.

Values:

Array of string. Each value is a name of the enum value, values are assigned in the order they are defined.

Returns:

Enum.

Example:

1-- Add enum for the sensor data
2local sensorDataEnum = modelEditor:addEnum("PrecisionType", {
3  "Low",
4  "Medium",
5  "High",
6})

Full source

editor.addStructure(browseName, nodeId)

Add a structure to the model.

BrowseName:

QualifiedName or String Name of the structure.

NodeId:

Node ID for the new structure. If not provided, then new Node ID is generated.

Returns:

Structure That can be used to add fields to the structure.

Example:

1-- Add a structure type for the sensor data
2local sensorDataType = modelEditor:addStructure("SensorDataType")
3sensorDataType:addField("Temperature", ua.DataTypeId.Double, ua.ValueRank.Scalar)
4sensorDataType:addField("Humidity", ua.DataTypeId.Double, ua.ValueRank.Scalar)
5sensorDataType:addField("Precision", ua.DataTypeId.Enumeration, ua.ValueRank.Scalar)

Full source

editor.save()

Save the model.

Returns:

nil

Example:

1local modelEditor = server.model:edit()
2local objectsFolder = modelEditor:objectsFolder()
3local sensorFolder = objectsFolder:addFolder("Sensors")
4local sensor1 = sensorFolder:addObject("Outside", sensorObjectType)
5local sensor2 = sensorFolder:addObject("Inside", sensorObjectType)
6
7-- Save the changes to the model
8modelEditor:save()

Full source

editor.objectsFolder()

Returns ‘ObjectsFolder’.

Returns:

Object that can be used for editing objects under ObjectsFolder.

Example:

1local modelEditor = server.model:edit()
2-- Get ObjectsFolder node
3local objectsFolder = modelEditor:objectsFolder()
4-- Create to node folders and add some variables to them
5local folder1 = objectsFolder:addFolder("Folder1")

Full source

Object

object.addProperty(browseName, propertyType, nodeId, refType)

Add a property to the object.

BrowseName:

QualifiedName | String Name of the property.

PropertyType:

(optional) NodeID | DataType. Property type which will be used as a template for the new property.

NodeId:

(optional) Node ID for the new property. If not provided, then new Node ID is generated.

RefType:

(optional) Reference type of the property.

Returns:

Variable object.

Example:

1  local configurationObject = object:addObject("Configuration")
2  configurationObject:addProperty("Address", {Type=ua.VariantType.String, Value="1"})
3  configurationObject:addProperty("Port", {Type=ua.VariantType.UInt16, Value=1234})

Full source

object.addVariable(browseName, value, variableType, nodeId, refType)

Add a variable to the object.

BrowseName:

(String or QualifiedName) Name of the variable.

Value:

(DataValue or Variant or nil) Value of the variable.

VariableType:

(NodeID or VariableType or nil) Variable type which will be used as a template for the new variable. The hierarchy of variable type will be expanded. If not provided, then BaseDataVariableType is used.

NodeId:

(NodeID or nil) Node ID for the new variable. If not provided, then new Node ID is generated.

RefType:

(NodeID or String or Reference Type or nil) Reference type of the variable. If not provided, then HasComponent reference type is used.

Returns:

Variable object.

Example:

1  local editor = model:edit()
2
3  local object = editor:addObject("Sensor")
4  object:addVariable("Temperature", {Type=ua.VariantType.Double, Value=20})

Full source

object.addObject(browseName, objectType, nodeId, refType)

Add an sub-object to the object.

BrowseName:

QualifiedName or String Name of the object.

ObjectType:

NodeID | ObjectType object. Object type which will be used as a template for the new object. The hierarchy of object type will be expanded.

NodeId:

Node ID for the new object. If not provided, then new Node ID is generated.

RefType:

Reference type of the object.

Can be:
  • NodeID of the reference type

  • String with name of the reference type

  • Reference Type object

  • nil - then HasComponent reference type is used.

Returns:

Object

Example:

1  local editor = model:edit()
2
3  local object = editor:addObject("Sensor")
4  object:addVariable("Temperature", {Type=ua.VariantType.Double, Value=20})
5  local configurationObject = object:addObject("Configuration")
6  configurationObject:addProperty("Address", {Type=ua.VariantType.String, Value="1"})

Full source

object.addFolder(browseName)

Add Folder which stores other nodes (like ‘ObjectsFolder’)

Returns:

Object with newly created folder

1-- Get ObjectsFolder node
2local objectsFolder = modelEditor:objectsFolder()
3-- Create to node folders and add some variables to them
4local folder1 = objectsFolder:addFolder("Folder1")

Full source

object.addMethod(browseName, func, inputArguments, outputArguments, nodeId)

Add a method to the Object.

Func:

Function to be called when the method is called by client.

InputArguments:

Array with description of input arguments. Each argument is a table with following fields:

  • Name

  • DataType

  • ValueRank (optional)

  • ArrayDimensions (optional)

  • Description (optional)

OutputArguments:

Array with description of output arguments. Each argument is a table with following fields:

  • Name

  • DataType

  • ValueRank

  • ArrayDimensions

  • Description

NodeId:

(optional) Node ID for the new method. If not provided, then new Node ID is generated.

Example:

 1  local inputArguments = {
 2    {Name = "Address",  DataType = ua.DataTypeId.String},
 3    {Name = "Port",     DataType = ua.DataTypeId.UInt16},
 4    {Name = "Enabled",  DataType = ua.DataTypeId.Boolean},
 5  }
 6
 7  local outputArguments = {
 8    {Name = "Result",  DataType = ua.DataTypeId.StatusCode},
 9  }
10
11  local func = function(address, port, enabled)
12    trace(string.format("New configuration: address=%s, port=%d, enabled=%s",
13      address, port, enabled))
14
15    return {
16      {Name="Result", {Type = ua.DataTypeId.StatusCode, Value = ua.StatusCode.Good}}
17    }
18  end
19
20  local method = object:addMethod("SetConfiguration",
21    func, inputArguments, outputArguments)

Full source

Returns:

Method

object.getProperty(browseName)

Get a property from the object.

Returns:

Variable

object.getVariable(browseName)

Get a variable from the object.

Returns:

Variable

object.getComponent(browseName)

Get a component from the object.

Returns:

Object

object.getMethod(browseName)

Get a method from the object.

Returns:

Method

object.path(names)

Resolve node by path relative to current object.

Throws:

Error if path is not found.

Returns:

Node corresponding to the path.

ObjectType

objectType.addProperty(browseName, value, variableType, nodeId, refType)

Add a property to the object.

BrowseName:

QualifiedName | String Name of the property.

PropertyType:

(optional) NodeID | DataType. Property type which will be used as a template for the new property.

NodeId:

(optional) Node ID for the new property. If not provided, then new Node ID is generated.

RefType:

(optional) Reference type of the property.

Returns:

Variable object.

Example:

1-- Add a sensor object type. This object type will be used
2-- to create instances of sensors.
3local sensorObjectType = modelEditor:addObjectType("SensorType")
4-- Add a property to the sensor object type

Full source

objectType.addVariable(browseName, value, variableType, nodeId, refType)

Add a variable to the object.

BrowseName:

(String or QualifiedName) Name of the variable.

Value:

(DataValue or Variant or nil) Value of the variable. If not provided, then nil is used.

VariableType:

(NodeID or VariableType or nil) Variable type which will be used as a template for the new variable. The hierarchy of variable type will be expanded. If not provided, then BaseDataVariableType is used.

NodeId:

(NodeID or nil) Node ID for the new variable. If not provided, then new Node ID is generated.

RefType:

(NodeID or String or Reference Type or nil) Reference type of the variable. If not provided, then HasComponent reference type is used.

Returns:

Variable object.

Example:

1-- Add a sensor object type. This object type will be used
2-- to create instances of sensors.
3local sensorObjectType = modelEditor:addObjectType("SensorType")
4-- Add a variable to the sensor object type
5local sensorDataVariable = sensorObjectType:addVariable("Data", nil, sensorVariableDataType)
6sensorDataVariable.Attrs.Description = {Text="Current measured sensor data"}

Full source

objectType.addObject(browseName, objectType, nodeId, refType)

Add an sub-object to the object.

BrowseName:

QualifiedName or String Name of the object.

ObjectType:

NodeID | ObjectType object. Object type which will be used as a template for the new object. The hierarchy of object type will be expanded.

NodeId:

Node ID for the new object. If not provided, then new Node ID is generated.

RefType:

Reference type of the object.

Can be:
  • NodeID of the reference type

  • String with name of the reference type

  • Reference Type object

  • nil - then HasComponent reference type is used.

Returns:

Object

Example:

1-- Add a sensor object type. This object type will be used
2-- to create instances of sensors.
3local sensorObjectType = modelEditor:addObjectType("SensorType")
4-- Add an object to the sensor object type
5local busObject = sensorObjectType:addObject("Bus")
6busObject.Attrs.Description = {Text="Ethernet bus object"}

Full source

objectType.addFolder(browseName)

Add Folder which stores other nodes (like ‘ObjectsFolder’) Parameters are the same as for object.addFolder().

Returns:

Object with newly created folder

Example:

1-- Add a sensor object type. This object type will be used
2-- Add an object to the sensor object type
3local gpioFolder = sensorObjectType:addFolder("GPIO Pins")
4gpioFolder:addVariable("GPIO 1", {Type = ua.VariantType.Int32, Value = 1})
5gpioFolder:addVariable("GPIO 2", {Type = ua.VariantType.Int32, Value = 2})
6gpioFolder:addVariable("GPIO 3", {Type = ua.VariantType.Int32, Value = 3})

Full source

objectType.addMethod(browseName, func, inputArguments, outputArguments[, nodeId])

Add a method to the object type.

Func:

Function to be called when the method is called by client.

InputArguments:

Array with description of input arguments of a method. Each argument is a table with following fields:

  • Name

  • DataType

  • ValueRank (optional)

  • ArrayDimensions (optional)

  • Description (optional)

OutputArguments:

Array with description of output arguments of a method. Each argument is a table with following fields:

  • Name

  • DataType

  • ValueRank

  • ArrayDimensions

  • Description

Throws:

Error in case of errors.

Returns:

Method

Example:

 1-- Add a sensor object type. This object type will be used
 2-- to create instances of sensors.
 3local sensorObjectType = modelEditor:addObjectType("SensorType")
 4-- Add a method to the sensor object type
 5local function measureSensor(objectId, methodId, isAsync)
 6  if isAsync then
 7    return ua.StatusCode.Good
 8  end
 9
10  return ua.StatusCode.Good
11end
12local inputArguments = {
13  {Name = "IsAsync",  DataType = ua.DataTypeId.Boolean},
14}
15local outputArguments = {
16  {Name = "Status",  DataType = ua.DataTypeId.StatusCode},
17}
18local measureMethod = sensorObjectType:addMethod("Measure",
19    measureSensor, inputArguments, outputArguments)
20measureMethod.Attrs.Description = {Text="Measure the temperature of the sensor"}

Full source

objectType.getProperty(browseName)

Get a property from the object.

Returns:

Variable

objectType.getVariable(browseName)

Get a variable from the object.

Returns:

Variable

objectType.getComponent(browseName)

Get a component from the object.

Returns:

Object

objectType.getMethod(browseName)

Get a method from the object.

Returns:

Method

objectType.path(names)

Resolve node by path relative to current object.

Returns:

Node corresponding to the path.

Variable

variable.addVariable(browseName, value, variableType, nodeId, refType)

Add a variable to the object.

BrowseName:

(String or QualifiedName) Name of the variable.

Value:

(DataValue or Variant or nil) Value of the variable.

VariableType:

(NodeID or VariableType or nil) Variable type which will be used as a template for the new variable. The hierarchy of variable type will be expanded. If not provided, then BaseDataVariableType is used.

NodeId:

(NodeID or nil) Node ID for the new variable. If not provided, then new Node ID is generated.

RefType:

(NodeID or String or Reference Type or nil) Reference type of the variable. If not provided, then HasComponent reference type is used.

Returns:

Variable object.

Example:

1-- Add a variable for the sensor data
2local objectsFolder = modelEditor:objectsFolder()
3
4local sensorDataVariable = objectsFolder:addVariable("SensorData")
5sensorDataVariable:addVariable("Temperature",
6    {Type = ua.VariantType.Double, Value = 20})
7
8sensorDataVariable:addVariable("Humidity",
9    {Type = ua.VariantType.Double, Value = 50})

Full source

variable.getVariable(browseName)

Get a chile node variable by name.

Returns:

Variable

variable.path(names)

Resolve node by path relative to current variable.

Returns:

Node corresponding to the path.

VariableType

Variable type is a type of variable. It is used to describe the type of variable. When create a variable the variable type is used as a template for the new variable. If variable is structured then VariableType is used as a template for the new variable and its underlying hierarchy.

For example variable type BuildInfoType represents a structure with the following fields:

  • ProductUri

  • ManufacturerName

  • ProductName

  • SoftwareVersion

After creating a variable with type BuildInfoType, the variable will have the same fields as the variable type. Root node will single structured value. For convinience, editor will expand hierarchy with fields in the underlying hierarchy. For each field fill be created separate variable node with the same type as the field.

  • BuildInfo - Structured value

    • ProductUri - String

    • ManufacturerName - String

    • ProductName - String

    • SoftwareVersion - String

variableType.addVariable(browseName, value, variableType, nodeId, refType)

Add a variable to the object.

BrowseName:

(String or QualifiedName) Name of the variable.

Value:

(DataValue or Variant or nil) Value of the variable.

VariableType:

(NodeID or VariableType or nil) Variable type which will be used as a template for the new variable. The hierarchy of variable type will be expanded. If not provided, then BaseDataVariableType is used.

NodeId:

(NodeID or nil) Node ID for the new variable. If not provided, then new Node ID is generated.

RefType:

(NodeID or String or Reference Type or nil) Reference type of the variable. If not provided, then HasComponent reference type is used.

Returns:

Variable object.

Example:

1-- Add a variable type for the sensor data
2-- Variables of this type will have root node with structured value and underlying hierarchy of fields will be expanded.
3local sensorVariableDataType = modelEditor:addVariableType("SensorVariableType")
4sensorVariableDataType:addVariable("Temperature",
5    {Type = ua.VariantType.Double, Value = 20})
6
7sensorVariableDataType:addVariable("Humidity",
8    {Type = ua.VariantType.Double, Value = 50})

Full source

variableType.getVariable(browseName)

Get a chile node variable by name.

Returns:

Variable

variableType.path(names)

Resolve node by path relative to current variable type.

Throws:

Error if path is not found.

Returns:

Node corresponding to the path relative to current variable type.

Enum

enum.setValues(values)

Set values for the enum.

Values:

Array of string. Each value is a name of the enum value, values are assigned in the order they are defined.

Returns:

nil

Example:

1local values = sensorDataEnum:getValues()
2for i, value in ipairs(values) do
3  print(value)
4end
5
6-- Add a new value to the enum
7sensorDataEnum:setValues({"Low", "Medium", "High", "VeryHigh"})

Full source

enum.getValues()

Get values for the enum.

Returns:

Array of string. Each value is a name of the enum value, values are assigned in the order they are defined.

Example:

1local values = sensorDataEnum:getValues()
2for i, value in ipairs(values) do
3  print(value)
4end

Full source

Structure

Structure is a complex data type. It is a collection of fields. Structure types describes how to encode and decode the structure. Fileds are encoded in the order they are defined.

structure.setFields(fields)

Set fields for the structure.

Fields:

Array of tables with description of fields. Each field is a table with following fields:

  • Name

  • DataType

  • ValueRank

  • ArrayDimensions

  • Description

Returns:

nil

Example:

 1local fields = {
 2  {
 3    Name = "Temperature",
 4    DisplayName = {Text = "Temperature"},
 5    DataType = ua.DataTypeId.Double,
 6    ValueRank = ua.ValueRank.Scalar,
 7    IsOptional = false
 8  },
 9  {
10    Name = "Humidity",
11    DisplayName = {Text = "Humidity"},
12    DataType = ua.DataTypeId.Double,
13    ValueRank = ua.ValueRank.Scalar,
14    IsOptional = false
15  },
16  {
17    Name = "Precision",
18    DisplayName = {Text = "Precision"},
19    DataType = ua.DataTypeId.Enumeration,
20    ValueRank = ua.ValueRank.Scalar,
21    IsOptional = false
22  },
23}
24sensorDataType:setFields(fields)

Full source

structure.getFields()

Get fields for the structure.

Returns:

Array of fields. Each field is a table with following fields:

  • Name

  • DataType

  • ValueRank

  • ArrayDimensions

  • Description

Example:

1local allFields = sensorDataType:getFields()
2for _, field in ipairs(allFields) do
3  print(field.Name, field.DisplayName, field.DataType, field.ValueRank, field.IsOptional)
4end

Full source

structure.getField(fieldName)

Get field for the structure.

FieldName:

Name of the field.

Returns:

Field.

Example:

1local field = sensorDataType:getField("Precision")
2print(field.Name, field.DisplayName, field.DataType, field.ValueRank, field.IsOptional)

Full source

Method

method.setInputArguments(inputArguments)

Set input arguments for the method.

InputArguments:

Array with description of input arguments. Each argument is a table with following fields:

Returns:

nil

Example:

1local inputArguments = {
2  {Name = "IsAsync",  DataType = ua.DataTypeId.Boolean},
3  {Name = "Unit",  DataType = ua.DataTypeId.String},
4}
5measureMethod:setInputArguments(inputArguments)

Full source

method.setOutputArguments(outputArguments)

Set output arguments for the method.

OutputArguments:

Array with description of output arguments. Each argument is a table with following fields:

Returns:

nil

Example:

1local outputArguments = {
2  {Name = "Status",  DataType = ua.DataTypeId.StatusCode},
3  {Name = "Temperature",  DataType = ua.DataTypeId.Double},
4}
5measureMethod:setOutputArguments(outputArguments)

Full source

Reference Type

Reference type represents a kind of a reference between nodes.

referenceType.path(names)

Resolve node by path relative to current reference type.