OPC-UA Integration
OPC-UA (Open Platform Communications Unified Architecture, IEC 62541) is a platform-independent industrial M2M protocol designed for reliable, secure data exchange in automation and IoT environments. The ThingsBoard OPC-UA integration connects to an OPC-UA server, subscribes to configured device nodes, decodes node values via an uplink converter, and pushes telemetry and attributes to the platform. In the reverse direction, it encodes Rule Engine messages via a downlink converter and delivers them to OPC-UA nodes as write operations or method calls.
Prerequisites
Section titled “Prerequisites”Download and install the OPC UA C++ Demo Server (Windows only).
- Launch UA Admin Dialog and note the Hostname / IP and Port values — you will enter them in the ThingsBoard integration.
- Launch UaCPPServer — the console window confirms the server is running and displays the endpoint URL in
opc.tcp://host:portformat.
ThingsBoard integration setup
Section titled “ThingsBoard integration setup”Create an uplink converter
Section titled “Create an uplink converter”OPC-UA uses a generic uplink converter. The uplink converter decodes incoming OPC-UA node values and maps them to the ThingsBoard data model.
The decoder function receives:
payload— JSON object with node values, e.g.{"temperature": "72.15819999999641"}metadata— node metadata:opcUaNode_name,opcUaNode_namespaceIndex,opcUaNode_identifier,opcUaNode_fqn,integrationName
Sample payload:
{ "temperature": "72.15819999999641"}Sample metadata:
{ "opcUaNode_namespaceIndex": "3", "opcUaNode_name": "AirConditioner_1", "integrationName": "OPC-UA Airconditioners", "opcUaNode_identifier": "AirConditioner_1", "opcUaNode_fqn": "Objects.BuildingAutomation.AirConditioner_1"}For the full decoder function reference, see Uplink data converter.
Import the uplink converter
- Download the uplink converter file:
- Go to Integrations center ⇾ Data converters.
- Click + Add data converter ⇾ Import converter.
- Drag and drop the downloaded JSON file into the Import converter window.
- Click Import.
The decoder function used in this tutorial:
var data = decodeToJson(payload);var deviceName = metadata['opcUaNode_name'];var namespaceIndex = metadata['opcUaNode_namespaceIndex'];var deviceType = 'airconditioner';
var result = { deviceName: deviceName, deviceType: deviceType, telemetry: { }, attributes: { namespaceIndex: namespaceIndex }};
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;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;Create a downlink converter
Section titled “Create a downlink converter”The downlink converter encodes RPC commands from ThingsBoard into OPC-UA write operations or method calls.
The output of the downlink converter must follow this structure:
[{ "contentType": "JSON", "data": "{\"writeValues\":[],\"callMethods\":[{\"objectId\":\"ns=3;s=AirConditioner_1\",\"methodId\":\"ns=3;s=AirConditioner_1.Stop\",\"args\":[]}]}", "metadata": {}}]The encoder returns a single object with these fields:
contentType—JSON,TEXT, orBINARYdata— JSON string with two optional arrays:writeValues—{nodeId, value}pairs; NodeId format:ns=<namespaceIndex>;<type>=<identifier>where<type>iss(string),i(numeric),g(GUID), orb(byte string)callMethods—{objectId, methodId, args}objects for calling OPC-UA methods
metadata— must be an empty object ({}) for OPC-UA
For the full encoder function reference, see Downlink data converter.
Create a downlink converter
- Go to Integrations center ⇾ Data converters.
- Click + Add data converter ⇾ Create new converter.
- Set Converter type to Downlink.
- Select integration type from the dropdown - OPC-UA.
- Enter a converter name:
OPC-UA Downlink Converter - In the Main encoding configuration, enter an encoder function:
var data = { writeValues: [], callMethods: []};
if (msgType === 'RPC_CALL_FROM_SERVER_TO_DEVICE') { if (msg.method === 'setState') { var targetMethod = msg.params === 'true' ? 'Start' : 'Stop'; var writeValue = { nodeId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName'], value: msg.params }; data.writeValues.push(writeValue); var callMethod = { objectId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName'], methodId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName']+'.'+targetMethod, args: [] }; data.callMethods.push(callMethod); }}
var result = { contentType: "JSON", data: JSON.stringify(data), metadata: {}};
return result;var data = { writeValues: [], callMethods: []};
if (msgType === 'RPC_CALL_FROM_SERVER_TO_DEVICE') { if (msg.method === 'setState') { var targetMethod = msg.params === 'true' ? 'Start' : 'Stop'; var writeValue = { nodeId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName'], value: msg.params }; data.writeValues.push(writeValue); var callMethod = { objectId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName'], methodId: 'ns=' + metadata['cs_namespaceIndex'] +';s=' + metadata['deviceName']+'.'+targetMethod, args: [] }; data.callMethods.push(callMethod); }}
var result = { contentType: "JSON", data: JSON.stringify(data), metadata: {}};
return result;- Optionally, click Test encoder function to validate.
- Click Add.
Create the integration
Section titled “Create the integration”- Go to Integrations center ⇾ Integrations and click + Add integration.
- Basic settings:
- Set Integration type to OPC-UA.
- Enable integration and Allow create devices or assets are on by default.
- Click Next.
- Uplink data converter:
- Select existing — choose a previously created
OPC-UA Uplink Converterfrom the list. - Click Next.
- Select existing — choose a previously created
- Downlink data converter:
- Select existing — choose a previously created
OPC-UA Downlink Converterfrom the list. - Click Next.
- Select existing — choose a previously created
- Configure the connection:
- Host — hostname or IP address of the OPC UA server.
- Port — port number of the OPC UA server
- Security —
None. - Identity —
Anonymous.
- Mapping type:
Fully Qualified Name. - Device Node Pattern:
Objects.BuildingAutomation.AirConditioner_\d+$— regex matched against OPC-UA node FQNs to identify device nodes; matches allAirConditioner_Npaths. - Subscription tags — define the node paths and output message keys:
- state —
State. - temperature —
Temperature - humidity —
Humidity - powerConsumption —
PowerConsumption.
- Click Add to complete the integration.
After saving, ThingsBoard connects to the OPC-UA server and 10 airconditioner devices appear on the Devices page.
Connection settings
Section titled “Connection settings”Host
Hostname or IP address of the OPC-UA server.
Port
Port number of the OPC-UA server. Default: 49320.
Endpoint
Optional path suffix appended to the server address when constructing the OPC-UA connection URL. Use this when the server exposes a specific endpoint path, for example /OPCUA/SimulationServer. Leave blank if the server listens on the root path (most common for demo servers).
Security
Message security policy for the OPC-UA session:
None— no encryption or signing (suitable for local/trusted networks)Basic128Rsa15— 128-bit symmetric encryption, RSA-15 key exchangeBasic256— 256-bit symmetric encryptionBasic256Sha256— 256-bit symmetric encryption with SHA-256 signing (recommended for production)
When any security policy other than None is selected, you must provide a client certificate and private key so the server can verify the ThingsBoard client’s identity.
Identity
Authentication method used when establishing the OPC-UA session:
Anonymous— no credentials required; the server must have anonymous logon enabledUsername— additional Username and Password fields appear; authenticate with a server-side account
Mapping type
Determines how ThingsBoard identifies device nodes on the OPC-UA server:
Fully Qualified Name— matches nodes by their full browsed path (e.g.Objects.BuildingAutomation.AirConditioner_1)ID— matches nodes by namespace index and node identifier
Device Node Pattern
Regular expression applied to OPC-UA node names or IDs to identify which nodes represent devices. Only nodes matching this pattern are subscribed to. Example: Channel1\.Device\d+$.
Namespace
OPC-UA namespace index used to scope node identifiers. Only visible when Mapping type is set to ID.
Subscription tags
Defines which child node values ThingsBoard reads from each matched device node. Each entry has:
- Key — the field name used in the ThingsBoard message payload (e.g.
temperature) - Path — relative path of the child node under the matched device node (e.g.
Temperature) - Required — when checked, a missing or unreadable value for this tag prevents the message from being processed; leave unchecked for optional tags
Execute remotely
When enabled, ThingsBoard generates an Integration key and Integration secret that allow the integration to run as a separate Remote Integration process outside the ThingsBoard cluster. This is the recommended approach when the OPC-UA server is only reachable from a local or isolated network that has no direct path to ThingsBoard.
Advanced settings
- Application name — OPC-UA client application name sent to the server during session establishment (informational)
- Application uri — OPC-UA client application URI; must be globally unique per the OPC-UA specification
- Scan period in seconds — how frequently ThingsBoard polls the OPC-UA server for updated node values. Default:
10 - Timeout in milliseconds — connection and request timeout. Default:
5000 - Description — optional text description for the integration
- Metadata — key-value pairs injected into every uplink message as
integrationMetadatain converter scripts
Configure and test downlink
Section titled “Configure and test downlink”To enable downlink (RPC) support, import the pre-built Airconditioners rule chain and wire it into the Root Rule Chain.
Import the Airconditioners rule chain
Section titled “Import the Airconditioners rule chain”Download: airconditioners_rule_chain.json
- Go to Rule chains, click + Add rule chain ⇾ Import rule chain, drag
airconditioners_rule_chain.jsoninto the window, and click Import. - The Airconditioners rule chain opens. Double-click the integration downlink node.
- Set Integration to your OPC-UA integration and click the orange checkmark to confirm.
- Click Apply changes to save the rule chain.
Modify the Root Rule Chain
Section titled “Modify the Root Rule Chain”- Go to Rule chains and open the Root Rule Chain.
- Search for
rule chainin the node panel and drag it onto the canvas. - In the Add rule node dialog, set Name =
Airconditionersand Rule chain = Airconditioners. Click Add. - Connect the message type switch node to the Airconditioners node using the Post Telemetry, Post attributes, Attributes Updated, and RPC Request to Device relations.
- Click Apply changes.
Airconditioners dashboard
Section titled “Airconditioners dashboard”Download the dashboard file: airconditioners_dashboard.json
- Go to the Dashboards page.
- Click + Add dashboard ⇾ Import dashboard.
- Drag and drop the downloaded JSON file into the Import dashboard dialog and click Import.
- Open the Airconditioners dashboard.
The dashboard displays real-time Temperature, Humidity, and Power Consumption graphs for all 10 airconditioners.
- In the Entities widget, click the Open airconditioner details icon next to any device.
- The Airconditioner status indicator is green. Click the Round switch to turn the airconditioner off.
After switching off, the status indicator turns grey, temperature and humidity begin to rise, and power consumption drops to zero.