Skip to main content

Tutorial Intro

Let's discover OPC UA Modeler in less than 5 minutes.

Getting Started

What you'll need

  • a PC running ubuntu or Windows with WSL.
  • Visual Studio Code and the YAML extension by RedHat installed.

installing opcua-modeler

We assume in this tutorial, that you are running a ubuntu installation. opcua-modeler can be installed as a snap package on ubuntu:

snap install opcua-modeler

Get it from the Snap Store

This installs the demo version of opcua-modeler that let you create small models for evaluation purposes. You'll need to contact sterfive to purchase a full license.

Get started by creating a new model locally.

Editing a model

Create a file named temperature-sensor.model.yaml with the following content

# yaml-language-server: $schema=https://support.sterfive.com/nodeset2.schema.json
namespaceUri: http://acme.com/UA/TemperatureSensor
version: 1.0.0
publicationDate: 2019-01-01T00:00:00Z
namespaces:
- di
objectTypes:
- browseName: TemperatureSensorType
subtypeOf: di:DeviceType
components:
- browseName: di:ParameterSet
components:
- browseName: Temperature
typeDefinition: ua:AnalogItemType
dataType: ua:Double
engineeringUnits: "degree Celsius"
description: |
The actual temperature
- browseName: TemperatureSetpoint
dataType: ua:Double
- browseName: di:MethodSet
methods:
- browseName: Calibrate
nodeClass: Method
inputArguments:
- name: coefficentA
dataType: ua:Double
description: the B coefficient used to perform the linear interpolation `T = A*x + B`
- name: coefficentB
dataType: ua:Double
description: the B coefficient used to perform the linear interpolation `T = A*x + B`
outputArguments:
- name: previousCoefA
dataType: ua:Double
- name: previousCoefB
dataType: ua:Double
description: Initiate the calibration of the sensor.
- browseName: SetTemperatureSetpoint
description: Install the temperature setpoint of the Temperature device
inputArguments:
- name: Temperature
dataType: ua:Double
instances:
- browseName: TemperatureSensor
typeDefinition: TemperatureSensorType
organizedBy: /ua:Objects/di:DeviceSet

Generate a model

$ opcua-modeler generate -i temperature-sensor.model.yaml

Results

You can find the generate NodeSet2.xml file at _generated_temperature-sensor.model.nodeset2.xml and the corresponding markdown file at _generated_temperature-sensor.model.doc1.md

XML file
<?xml version="1.0"?>
<UANodeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd" xmlns:ns2="http://opcfoundation.org/UA/DI/Type.xsd" xmlns:ns1="http://acme.com/UA/TemperatureSensor/Type.xsd">
<NamespaceUris>
<Uri>http://acme.com/UA/TemperatureSensor</Uri>
<Uri>http://opcfoundation.org/UA/DI/</Uri>
</NamespaceUris>
<Models>
<Model ModelUri="http://acme.com/UA/TemperatureSensor" Version="0.0.0" PublicationDate="1900-01-01T00:00:00.000Z">
<RequiredModel ModelUri="http://opcfoundation.org/UA/" Version="1.05.01" PublicationDate="2022-02-24T00:00:00.000Z"/>
<RequiredModel ModelUri="http://opcfoundation.org/UA/DI/" Version="1.03.1" PublicationDate="2021-09-07T00:00:00.000Z"/>
</Model>
</Models>
<Aliases>
<Alias Alias="Argument">i=296</Alias>
<Alias Alias="Double">i=11</Alias>
<Alias Alias="EUInformation">i=887</Alias>
<Alias Alias="HasComponent">i=47</Alias>
<Alias Alias="HasModellingRule">i=37</Alias>
<Alias Alias="HasProperty">i=46</Alias>
<Alias Alias="HasSubtype">i=45</Alias>
<Alias Alias="HasTypeDefinition">i=40</Alias>
<Alias Alias="Int32">i=6</Alias>
<Alias Alias="LocalizedText">i=21</Alias>
<Alias Alias="Organizes">i=35</Alias>
<Alias Alias="Range">i=884</Alias>
<Alias Alias="String">i=12</Alias>
</Aliases>
<!--ReferenceTypes-->
<!--ObjectTypes-->
<!--ObjectType - 1:TemperatureSensorType {{{{ -->
<UAObjectType NodeId="ns=1;i=1000" BrowseName="1:TemperatureSensorType">
<DisplayName>TemperatureSensorType</DisplayName>
<Description>The Temperature Sensor</Description>
<References>
<Reference ReferenceType="HasComponent">ns=1;i=1001</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1005</Reference>
<Reference ReferenceType="HasSubtype" IsForward="false">ns=2;i=1002</Reference>
</References>
</UAObjectType>
<!--Object - 2:ParameterSet {{{{ -->
<UAObject NodeId="ns=1;i=1001" BrowseName="2:ParameterSet" ParentNodeId="ns=1;i=1000">
<DisplayName>ParameterSet</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1002</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1037</Reference>
</References>
</UAObject>
<UAVariable NodeId="ns=1;i=1002" BrowseName="1:Temperature" ParentNodeId="ns=1;i=1001" AccessLevel="3" DataType="Double">
<DisplayName>Temperature</DisplayName>
<Description>The actual temperature</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=2368</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1003</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1004</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1003" BrowseName="EURange" ParentNodeId="ns=1;i=1002" AccessLevel="3" DataType="Range">
<DisplayName>EURange</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
</References>
<Value>
<ExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<TypeId>
<Identifier>i=885</Identifier>
</TypeId>
<Body>
<Range>
<Low>-1</Low>
<High>1</High>
</Range>
</Body>
</ExtensionObject>
</Value>
</UAVariable>
<UAVariable NodeId="ns=1;i=1004" BrowseName="EngineeringUnits" ParentNodeId="ns=1;i=1002" DataType="EUInformation">
<DisplayName>EngineeringUnits</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
</References>
<Value>
<ExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<TypeId>
<Identifier>i=888</Identifier>
</TypeId>
<Body>
<EUInformation>
<NamespaceUri>http://www.opcfoundation.org/UA/units/un/cefact</NamespaceUri>
<UnitId>4408652</UnitId>
<DisplayName>
<Text>°C</Text>
</DisplayName>
<Description>
<Text>degree Celsius</Text>
</Description>
</EUInformation>
</Body>
</ExtensionObject>
</Value>
</UAVariable>
<UAVariable NodeId="ns=1;i=1037" BrowseName="1:TemperatureSetpoint" ParentNodeId="ns=1;i=1001" AccessLevel="3" DataType="Double">
<DisplayName>TemperatureSetpoint</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
</References>
</UAVariable>
<!--Object - 2:ParameterSet }}}} -->
<!--Object - 2:MethodSet {{{{ -->
<UAObject NodeId="ns=1;i=1005" BrowseName="2:MethodSet" ParentNodeId="ns=1;i=1000">
<DisplayName>MethodSet</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1006</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1033</Reference>
</References>
</UAObject>
<UAMethod NodeId="ns=1;i=1006" BrowseName="1:Calibrate" ParentNodeId="ns=1;i=1005">
<DisplayName>Calibrate</DisplayName>
<Description>Initiate the calibration of the sensor.</Description>
<References>
<Reference ReferenceType="HasProperty">ns=1;i=1007</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1008</Reference>
</References>
</UAMethod>
<UAVariable NodeId="ns=1;i=1007" BrowseName="InputArguments" ParentNodeId="ns=1;i=1006" ValueRank="1" ArrayDimensions="2" DataType="Argument">
<DisplayName>InputArguments</DisplayName>
<Description>the definition of the input argument of method 2:MethodSet.1:Calibrate</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
</References>
<Value>
<ListOfExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<ExtensionObject>
<TypeId>
<Identifier>i=297</Identifier>
</TypeId>
<Body>
<Argument>
<Name>coefficentA</Name>
<DataType>
<Identifier>i=11</Identifier>
</DataType>
<ValueRank>-1</ValueRank>
<ArrayDimensions/>
<Description>
<Text>the B coefficient used to perform the linear interpolation `T = A*x + B`</Text>
</Description>
</Argument>
</Body>
</ExtensionObject>
<ExtensionObject>
<TypeId>
<Identifier>i=297</Identifier>
</TypeId>
<Body>
<Argument>
<Name>coefficentB</Name>
<DataType>
<Identifier>i=11</Identifier>
</DataType>
<ValueRank>-1</ValueRank>
<ArrayDimensions/>
<Description>
<Text>the B coefficient used to perform the linear interpolation `T = A*x + B`</Text>
</Description>
</Argument>
</Body>
</ExtensionObject>
</ListOfExtensionObject>
</Value>
</UAVariable>
<UAVariable NodeId="ns=1;i=1008" BrowseName="OutputArguments" ParentNodeId="ns=1;i=1006" ValueRank="1" ArrayDimensions="2" DataType="Argument">
<DisplayName>OutputArguments</DisplayName>
<Description>the definition of the output arguments of method 2:MethodSet.1:Calibrate</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
</References>
<Value>
<ListOfExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<ExtensionObject>
<TypeId>
<Identifier>i=297</Identifier>
</TypeId>
<Body>
<Argument>
<Name>previousCoefA</Name>
<DataType>
<Identifier>i=11</Identifier>
</DataType>
<ValueRank>-1</ValueRank>
<ArrayDimensions/>
<Description>
<Text/>
</Description>
</Argument>
</Body>
</ExtensionObject>
<ExtensionObject>
<TypeId>
<Identifier>i=297</Identifier>
</TypeId>
<Body>
<Argument>
<Name>previousCoefB</Name>
<DataType>
<Identifier>i=11</Identifier>
</DataType>
<ValueRank>-1</ValueRank>
<ArrayDimensions/>
<Description>
<Text/>
</Description>
</Argument>
</Body>
</ExtensionObject>
</ListOfExtensionObject>
</Value>
</UAVariable>
<UAMethod NodeId="ns=1;i=1033" BrowseName="1:SetTemperatureSetpoint" ParentNodeId="ns=1;i=1005">
<DisplayName>SetTemperatureSetpoint</DisplayName>
<Description>Install the temperature setpoint of the Temperature device</Description>
<References>
<Reference ReferenceType="HasProperty">ns=1;i=1041</Reference>
</References>
</UAMethod>
<UAVariable NodeId="ns=1;i=1041" BrowseName="InputArguments" ParentNodeId="ns=1;i=1033" ValueRank="1" ArrayDimensions="1" DataType="Argument">
<DisplayName>InputArguments</DisplayName>
<Description>the definition of the input argument of method 2:MethodSet.1:SetTemperatureSetpoint</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
<Reference ReferenceType="HasModellingRule">i=78</Reference>
</References>
<Value>
<ListOfExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<ExtensionObject>
<TypeId>
<Identifier>i=297</Identifier>
</TypeId>
<Body>
<Argument>
<Name>Temperature</Name>
<DataType>
<Identifier>i=11</Identifier>
</DataType>
<ValueRank>-1</ValueRank>
<ArrayDimensions/>
<Description>
<Text/>
</Description>
</Argument>
</Body>
</ExtensionObject>
</ListOfExtensionObject>
</Value>
</UAVariable>
<!--Object - 2:MethodSet }}}} -->
<!--ObjectType - 1:TemperatureSensorType }}}}-->
<!--VariableTypes-->
<!--Other Nodes-->
<!--Object - 1:TemperatureSensor {{{{ -->
<UAObject NodeId="ns=1;i=1009" BrowseName="1:TemperatureSensor">
<DisplayName>TemperatureSensor</DisplayName>
<Description>The Temperature Sensor</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">ns=1;i=1000</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1010</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1014</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1015</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1016</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1017</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1018</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1019</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1020</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1021</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1022</Reference>
<Reference ReferenceType="Organizes" IsForward="false">ns=2;i=5001</Reference>
</References>
</UAObject>
<!--Object - 2:ParameterSet {{{{ -->
<UAObject NodeId="ns=1;i=1010" BrowseName="2:ParameterSet" ParentNodeId="ns=1;i=1009">
<DisplayName>ParameterSet</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1011</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=1038</Reference>
</References>
</UAObject>
<UAVariable NodeId="ns=1;i=1011" BrowseName="1:Temperature" ParentNodeId="ns=1;i=1010" AccessLevel="3" DataType="Double">
<DisplayName>Temperature</DisplayName>
<Description>The actual temperature</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=2368</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1012</Reference>
<Reference ReferenceType="HasProperty">ns=1;i=1013</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1012" BrowseName="EURange" ParentNodeId="ns=1;i=1011" AccessLevel="3" DataType="Range">
<DisplayName>EURange</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
<Value>
<ExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<TypeId>
<Identifier>i=885</Identifier>
</TypeId>
<Body>
<Range>
<Low>-1</Low>
<High>1</High>
</Range>
</Body>
</ExtensionObject>
</Value>
</UAVariable>
<UAVariable NodeId="ns=1;i=1013" BrowseName="EngineeringUnits" ParentNodeId="ns=1;i=1011" DataType="EUInformation">
<DisplayName>EngineeringUnits</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
<Value>
<ExtensionObject xmlns="http://opcfoundation.org/UA/2008/02/Types.xsd">
<TypeId>
<Identifier>i=888</Identifier>
</TypeId>
<Body>
<EUInformation>
<NamespaceUri>http://www.opcfoundation.org/UA/units/un/cefact</NamespaceUri>
<UnitId>4408652</UnitId>
<DisplayName>
<Text>°C</Text>
</DisplayName>
<Description>
<Text>degree Celsius</Text>
</Description>
</EUInformation>
</Body>
</ExtensionObject>
</Value>
</UAVariable>
<UAVariable NodeId="ns=1;i=1038" BrowseName="1:TemperatureSetpoint" ParentNodeId="ns=1;i=1010" AccessLevel="3" DataType="Double">
<DisplayName>TemperatureSetpoint</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
</References>
</UAVariable>
<!--Object - 2:ParameterSet }}}} -->
<!--Object - 2:MethodSet {{{{ -->
<UAObject NodeId="ns=1;i=1014" BrowseName="2:MethodSet" ParentNodeId="ns=1;i=1009">
<DisplayName>MethodSet</DisplayName>
<References>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
</References>
</UAObject>
<!--Object - 2:MethodSet }}}} -->
<UAVariable NodeId="ns=1;i=1015" BrowseName="2:Manufacturer" ParentNodeId="ns=1;i=1009" DataType="LocalizedText">
<DisplayName>Manufacturer</DisplayName>
<Description>Name of the company that manufactured the device</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1016" BrowseName="2:Model" ParentNodeId="ns=1;i=1009" DataType="LocalizedText">
<DisplayName>Model</DisplayName>
<Description>Model name of the device</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1017" BrowseName="2:HardwareRevision" ParentNodeId="ns=1;i=1009" DataType="String">
<DisplayName>HardwareRevision</DisplayName>
<Description>Revision level of the hardware of the device</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1018" BrowseName="2:SoftwareRevision" ParentNodeId="ns=1;i=1009" DataType="String">
<DisplayName>SoftwareRevision</DisplayName>
<Description>Revision level of the software/firmware of the device</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1019" BrowseName="2:DeviceRevision" ParentNodeId="ns=1;i=1009" DataType="String">
<DisplayName>DeviceRevision</DisplayName>
<Description>Overall revision level of the device</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1020" BrowseName="2:DeviceManual" ParentNodeId="ns=1;i=1009" DataType="String">
<DisplayName>DeviceManual</DisplayName>
<Description>Address (pathname in the file system or a URL | Web address) of user manual for the device</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1021" BrowseName="2:SerialNumber" ParentNodeId="ns=1;i=1009" DataType="String">
<DisplayName>SerialNumber</DisplayName>
<Description>Identifier that uniquely identifies, within a manufacturer, a device instance</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
</UAVariable>
<UAVariable NodeId="ns=1;i=1022" BrowseName="2:RevisionCounter" ParentNodeId="ns=1;i=1009" DataType="Int32">
<DisplayName>RevisionCounter</DisplayName>
<Description>An incremental counter indicating the number of times the static data within the Device has been modified</Description>
<References>
<Reference ReferenceType="HasTypeDefinition">i=68</Reference>
</References>
</UAVariable>
<!--Object - 1:TemperatureSensor }}}} -->
</UANodeSet>
Markdown documentation

Model

Namespace http://acme.com/UA/TemperatureSensor

ObjectTypes

TemperatureSensorType

The Temperature Sensor

hierarchy TemperatureSensorType

TemperatureSensorType

AttributeValue
BrowseName1:TemperatureSensorType
IsAbstractfalse
Subtype of2:DeviceType

The Temperature Sensor

ReferenceNodeClassBrowseNameModellingRuleTypeDefinitionDataType
Components
HasComponentObject2:ParameterSetMandatoryBaseObjectType
HasComponentObject2:MethodSetMandatoryBaseObjectType

description

This digital temperature sensor for Industry 4.0 measures the temperature of a physical environment and converts the analog signal to a digital signal that is exposed to OPCUA. The sensor works by using a thermistor or a thermocouple to detect temperature changes, which generate a small electrical signal proportional to the temperature change. This signal is then amplified and converted to a digital signal using an Analog-to-Digital Converter (ADC) before being transmitted to the electronic device for processing.

In Industry 4.0, the digital temperature sensor is connected to the Industrial Internet of Things (IIoT) network, trough OPCUA allowing for real-time monitoring and control of temperature-sensitive processes.

The sensor may also incorporate additional features such as data logging, alarms, and remote control capabilities to enhance its functionality in the Industry 4.0 ecosystem.

ParameterSet

Temperature

The actual temperature

TemperatureSetpoint

MethodSet

Calibrate

Initiate the calibration of the sensor.

The Calibrate method initiate the calibrationof the temperature sensor on the physical device.

This method takes two arguments that define the linear interpolation T = A*x + B.

Signature
 Calibrate(
[in] Double coefficentA
[in] Double coefficentB
[out] Double previousCoefA
[out] Double previousCoefB
)
Calibrate method arguments
ArgumentDescription
coefficentAthe B coefficient used to perform the linear interpolation T = A*x + B
coefficentBthe B coefficient used to perform the linear interpolation T = A*x + B
previousCoefA
previousCoefB
$(node.browseName.name} Method AddressSpace definition
AttributeValue
BrowseNameCalibrate
ReferencesNodeClassBrowseNameDataTypeTypeDefinitionModellingRule
HasPropertyVariableInputArgumentsArgument[]PropertyTypeMandatory
HasPropertyVariableOutputArgumentsArgument[]PropertyTypeMandatory
SetTemperatureSetpoint

Install the temperature setpoint of the Temperature device

Signature
 SetTemperatureSetpoint(
[in] Double Temperature
)
SetTemperatureSetpoint method arguments
ArgumentDescription
Temperature
$(node.browseName.name} Method AddressSpace definition
AttributeValue
BrowseNameSetTemperatureSetpoint
ReferencesNodeClassBrowseNameDataTypeTypeDefinitionModellingRule
HasPropertyVariableInputArgumentsArgument[]PropertyTypeMandatory