Editor

Editor is returned by model:edit(). It is used to edit the address space. It has the 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 the same interface as objects returned from 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.

Method argument and structure field tables use the same compact shape:

Field

Required

Description

Name

yes

Argument or field name.

DataType

yes

Data type NodeId.

ValueRank

optional

Value rank. If omitted for method input arguments, the default rank is used.

ArrayDimensions

optional

Array dimensions.

Description

optional

Localized description.

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, a new Node ID is generated.

RefType:

Reference type as NodeId, String, reference type object, or nil to use HasComponent.

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: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, a 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

editor:typesFolder()

Returns the Types folder.

Returns:

Editable browser object for the Types folder.

editor:findNode(node)

Find a node by NodeId string or existing node table and return an editable object for it.

Node:

NodeId string or node table.

Returns:

Editable node object, or nil if the node is not found.

editor:getNode(node)

Return an editable object for a NodeId string or existing node table. Raises an error if the node cannot be resolved.

Node:

NodeId string or node table.

Returns:

Editable node object.

Object

object:addProperty(browseName, value, variableType, nodeId, refType)

Add a property to the object.

BrowseName:

QualifiedName | String Name of the property.

Value:

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

VariableType:

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

NodeId:

(optional) Node ID for the new property. If not provided, a 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, a new Node ID is generated.

RefType:

(NodeId or String or reference type object 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 a 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, a new Node ID is generated.

RefType:

Reference type as NodeId, String, reference type object, or nil to use HasComponent.

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[, nodeId])

Add a folder which stores other nodes (like ‘ObjectsFolder’)

BrowseName:

QualifiedName or String Name of the folder.

NodeId:

Optional Node ID for the new folder. If not provided, a new Node ID is generated.

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 of method argument tables.

OutputArguments:

Array of method argument tables.

NodeId:

(optional) Node ID for the new method. If not provided, a 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 type.

BrowseName:

QualifiedName | String Name of the property.

Value:

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

VariableType:

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

NodeId:

(optional) Node ID for the new property. If not provided, a 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, a new Node ID is generated.

RefType:

(NodeId or String or reference type object 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 a sub-object to the object type.

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, a new Node ID is generated.

RefType:

Reference type as NodeId, String, reference type object, or nil to use HasComponent.

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[, nodeId])

Add a 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 of method argument tables.

OutputArguments:

Array of method argument tables.

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, a new Node ID is generated.

RefType:

(NodeId or String or reference type object 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 child node variable by name.

Returns:

Variable

variable:setValueCallback(func)

Set a callback used when the variable value is read or written.

Func:

Function called by the address-space value handling code.

Returns:

nil

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 creating a variable, the variable type is used as a template for the new variable. If the 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. The root node will have a single structured value. For convenience, the editor will expand the hierarchy with fields in the underlying hierarchy. For each field, a separate variable node will be created 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, a new Node ID is generated.

RefType:

(NodeId or String or reference type object 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 child 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 describe how to encode and decode the structure. Fields are encoded in the order they are defined.

structure:addField(browseName, dataType, rank)

Add one field to the structure definition.

BrowseName:

Field name.

DataType:

Field data type NodeId.

Rank:

Optional value rank.

Returns:

nil

structure:setFields(fields)

Set fields for the structure.

Fields:

Array of structure field tables.

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 structure field tables.

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 of method argument tables.

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 of method argument tables.

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