Stand with Ukraine flag
Try it now Pricing
Professional Edition
Getting Started
Devices Library Guides Installation Architecture API FAQ
On this page

OPC-UA Integration

Doc info icon
ThingsBoard PE Feature

Only Professional Edition supports Platform Integrations feature.
Use ThingsBoard Cloud or install your own platform instance.

Overview

OPC UA Integration allows you to stream data from the OPC UA server to ThingsBoard and converts the device payloads to the ThingsBoard format.

OPC-UA Integration Tutorial

In this tutorial, we will configure the integration between ThingsBoard and OPC-UA to get the Airconditioners data from the OPC UA C++ Demo Server and allow the user to switch on/off any Airconditioner using the Integration downlink feature.

Prerequisites

  • Download and install the OPC UA C++ Demo Server;
  • After installation, launch the UA Admin Dialog;
  • Make sure that the hostname/IP address where the OPC-UA server is hosted is set correctly, and remember the values for the hostname/IP and port. These values will be needed when configuring the OPC-UA integration.

image

  • Launch the UaCPPServer. The console dialog will open showing the server endpoints URLs

image

ThingsBoard setup

First, we need to create the Uplink Data converter that will be used for receiving the messages from the OPC UA server. The converter should transform the incoming payload into the required message format. The message must contain the deviceName and deviceType. These fields are used to submit the data to the correct device. If a device cannot not be found, a new device will be created. Here is how the payload from the OPC UA integration will look like:

Payload:

1
2
3
{
    "temperature": "72.15819999999641"
}

Metadata:

1
2
3
4
5
6
7
{
    "opcUaNode_namespaceIndex": "3",
    "opcUaNode_name": "AirConditioner_1",
    "integrationName": "OPC-UA Airconditioners",
    "opcUaNode_identifier": "AirConditioner_1",
    "opcUaNode_fqn": "Objects.BuildingAutomation.AirConditioner_1"
}

We will take the opcUaNode_name metadata value and map it to the deviceName and set the deviceType as airconditioner.

However, you can use another mapping in your specific use cases.

Also, we will retrieve the values of the temperature, humidity and powerConsumption fields and use them as device telemetries.


Go to the Integrations center section -> Data converters page and create a new uplink converter

One can use either TBEL (ThingsBoard expression language) or JavaScript to develop user defined functions. We recommend utilizing TBEL as it’s execution in ThingsBoard is much more efficient compared to JS.

Use this function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var data = decodeToJson(payload);
var deviceName = metadata['opcUaNode_name'];
var deviceType = 'airconditioner';

var result = {
   deviceName: deviceName,
   deviceType: deviceType,
   telemetry: {
   },
   attributes: {
   }
};

if (data.temperature != null) {
    result.telemetry.temperature = toFixed(data.temperature, 2);
}

if (data.humidity != null) {
   result.telemetry.humidity = toFixed(data.humidity, 2);
}

if (data.powerConsumption != null) {
   result.telemetry.powerConsumption = toFixed(data.powerConsumption, 2);
}

if (data.state != null) {
   result.attributes.state = data.state == '1' ? true : false;
}

/** Helper functions 'decodeToString' and 'decodeToJson' are already built-in **/

return result;

image

Use this function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var data = decodeToJson(payload);
var deviceName = metadata['opcUaNode_name'];
var deviceType = 'airconditioner';

var result = {
   deviceName: deviceName,
   deviceType: deviceType,
   telemetry: {
   },
   attributes: {
   }
};

if (data.temperature) {
    result.telemetry.temperature = Number(Number(data.temperature).toFixed(2));
}

if (data.humidity) {
    result.telemetry.humidity = Number(Number(data.humidity).toFixed(2));
}

if (data.powerConsumption) {
    result.telemetry.powerConsumption = Number(Number(data.powerConsumption).toFixed(2));
}

if (data.state !== undefined) {
    result.attributes.state = data.state === '1' ? true : false;
}

function decodeToString(payload) {
   return String.fromCharCode.apply(String, payload);
}

function decodeToJson(payload) {
   var str = decodeToString(payload);
   var data = JSON.parse(str);
   return data;
}

return result;

image

For sending Downlink messages from the Thingsboard to the OPC UA node, we need to define a downlink Converter.

In general, the output from a Downlink converter should have the following structure:

1
2
3
4
5
[{
    "contentType": "JSON",
    "data": "{\"writeValues\":[],\"callMethods\":[{\"objectId\":\"ns=3;s=AirConditioner_1\",\"methodId\":\"ns=3;s=AirConditioner_1.Stop\",\"args\":[]}]}",
    "metadata": {}
}]
  • contentType - defines how data will be encoded {TEXT | JSON | BINARY}. In case of OPC UA Integration, JSON is used by default.
  • data - the actual data that will be processed by OPC UA Integration and sent to the target OPC UA nodes:
    • writeValues - array of write values methods:
      • nodeId - target node in OPC UA NodeId format (ns=<namespaceIndex>;<identifiertype>=<identifier>)
      • value - value to write
    • callMethods - array of call methods:
  • metadata - not used in case of OPC UA Integration and can be empty.


Go to the Integrations center section -> Data converters page and create a new downlink converter.

One can use either TBEL (ThingsBoard expression language) or JavaScript to develop user defined functions. We recommend utilizing TBEL as it’s execution in ThingsBoard is much more efficient compared to JS.

Use this function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var data = {
    writeValues: [],
    callMethods: []
};

if (msgType === 'RPC_CALL_FROM_SERVER_TO_DEVICE') {
    if (msg.method === 'setState') {
        var targetMethod = msg.params === 'true' ? 'Start' : 'Stop';
        var callMethod = {
              objectId: 'ns=3;s=' + metadata['deviceName'],
              methodId: 'ns=3;s=' +metadata['deviceName']+'.'+targetMethod,
              args: []
        };
        data.callMethods.push(callMethod);
    }
}

var result = {
    contentType: "JSON",
    data: JSON.stringify(data),
    metadata: {}
};

return result;

image

Use this function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var data = {
    writeValues: [],
    callMethods: []
};

if (msgType === 'RPC_CALL_FROM_SERVER_TO_DEVICE') {
    if (msg.method === 'setState') {
        var targetMethod = msg.params === 'true' ? 'Start' : 'Stop';
        var callMethod = {
              objectId: 'ns=3;s=' + metadata['deviceName'],
              methodId: 'ns=3;s=' +metadata['deviceName']+'.'+targetMethod,
              args: []
        };
        data.callMethods.push(callMethod);
    }
}

var result = {
    contentType: "JSON",
    data: JSON.stringify(data),
    metadata: {}
};

return result;

image

This converter will process the RPC command to the device using the method setState and a boolean params value to call the ‘Start’ or ‘Stop’ method of the airconditioner.

Destination node is detected using the deviceName field of the incoming message metadata.

OPC-UA Integration

  • Open the “Integrations center” section -> “Integrations” page and click + icon to create new integration. Name it OPC-UA Integration, select type “OPC-UA”. Click “Next”;

image

  • The next steps is to add the recently created uplink and downlink converters;

image

image

  • Specify host: hostname/IP (see Prerequisites);
  • Specify port: port (see Prerequisites);
  • Security: None (can be Basic128Rsa15 / Basic256 / Basic256Sha256 / None);
  • Identity: Anonymous (can be Anonymous / Username).

image

  • Mapping:
    • MappingType: Fully Qualified Name (can be Fully Qualified Name / ID);
    • Specify Device Node Pattern: Objects\.BuildingAutomation\.AirConditioner_\d+$

    (regular expression used to match scanned OPC UA Node FQNs/IDs to device name. In this sample, path on OPC UA Explorer is Objects\.BuildingAutomation\.AirConditioner_X, where X is a number from 1 to N. That’s why we use Objects\.BuildingAutomation\.AirConditioner_\d+$ as regular expression, because \d+ means any number from 1 to N, and $ means the end of the string);

    • Subscription tags (list of node tags (Path) to subscribe with mappings to keys (Key) used in the output message):
      • state - State;
      • temperature - Temperature;
      • humidity - Humidity;
      • powerConsumption - PowerConsumption.
  • Click “Add”.

image

The OPC-UA integration has been added.

The OPC-UA server simulates sending telemetry from devices to ThingsBoard. If you have done everything correctly, 10 new devices should appear on the “Devices” page as a result of the integration. Please make sure of this.

image

Open the details of any airconditioner and navigate to the “Latest telemetry” tab. You will see that telemetry values are frequently updated.

image

Airconditioners Rule Chain

To demonstrate OPC-UA integration and Rule Engine capabilities, we will create a separate rule chain to process the uplink and downlink messages related to the OPC-UA integration.

Let’s create the Airconditioners rule chain.

  • Download the airconditioners.json file;
  • Go to the “Rule Chains” page. To import this JSON file, click the + icon in the upper right corner of the screen and select “Import rule chain”;
  • Drag and drop downloaded JSON file to the Import rule chain window. Click “Import”;
  • The “Airconditioners” rule chain will open. Double-click on the “integration downlink” node and specify OPC-UA Integration in the integration field;
  • Apply all changes.
  • Open and edit the Root Rule Chain;
  • Find a rule chain node, drag and drop it to the rule chain. Name it Airconditioners, specify Airconditioners rule chain and click “Add”;
  • Tap on a right grey circle of “message type switch” node and drag this circle to left side of “rule chain” node. Here, select “Attributes Updated”, “Post telemetry”, and “RPC Request to Device”;
  • Click “Add” and save rule chain.

Airconditioners Dashboard

To visualize the Airconditioners data and test RPC commands, we will create the Airconditioners dashboard.

  • Download the airconditioners_dashboard.json file;
  • Go to the “Dashboards” page;
  • To import this JSON file, click the + icon in the upper right corner of the screen and select “Import dashboard”;
  • Drag and drop downloaded JSON file to the Import dashboard window. Click “Import”.

image

  • Open the Airconditioners dashboard;
  • You will see the telemetry till the last minute from all the 10 airconditioners;
  • Open any Airconditioner details page by clicking on the details button in the Entities widget;

image

  • You will find the Airconditioner status light green. Try to switch off the airconditioner by clicking on the On/Off Round switch;

image

  • The Airconditioner status light will turn into grey, the temperature will start rising, the humidity will start increasing and the power consumption will stop.

image

Video tutorial

See video tutorial below for step-by-step instruction how to setup OPC-UA Integration.



See also

Next steps