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
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
Attribute | Value |
---|---|
BrowseName | 1:TemperatureSensorType |
IsAbstract | false |
Subtype of | 2:DeviceType |
The Temperature Sensor
Reference | NodeClass | BrowseName | ModellingRule | TypeDefinition | DataType |
---|---|---|---|---|---|
Components | |||||
HasComponent | Object | 2:ParameterSet | Mandatory | BaseObjectType | |
HasComponent | Object | 2:MethodSet | Mandatory | BaseObjectType |
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
Argument | Description |
---|---|
coefficentA | the B coefficient used to perform the linear interpolation T = A*x + B |
coefficentB | the B coefficient used to perform the linear interpolation T = A*x + B |
previousCoefA | |
previousCoefB |
$(node.browseName.name} Method AddressSpace definition
Attribute | Value |
---|---|
BrowseName | Calibrate |
References | NodeClass | BrowseName | DataType | TypeDefinition | ModellingRule |
---|---|---|---|---|---|
HasProperty | Variable | InputArguments | Argument[] | PropertyType | Mandatory |
HasProperty | Variable | OutputArguments | Argument[] | PropertyType | Mandatory |
SetTemperatureSetpoint
Install the temperature setpoint of the Temperature device
Signature
SetTemperatureSetpoint(
[in] Double Temperature
)
SetTemperatureSetpoint method arguments
Argument | Description |
---|---|
Temperature |
$(node.browseName.name} Method AddressSpace definition
Attribute | Value |
---|---|
BrowseName | SetTemperatureSetpoint |
References | NodeClass | BrowseName | DataType | TypeDefinition | ModellingRule |
---|---|---|---|---|---|
HasProperty | Variable | InputArguments | Argument[] | PropertyType | Mandatory |