How to connect and integrate an OPC UA server

Marius Schmeding 2018-09-10

Prerequisites

This lesson assumes that you want to integrate the OPC Unified Architecture (a.k.a OPC UA) protocol with the Cybus Connectware. To understand the basic concepts of the Connectware, please checkout the Technical Overview lesson. To follow along with the example, you will also need a running instance of the Connectware. If you don't have that, learn How to install the Connectware. Although we focus on OPC UA here, we will ultimately access all data via MQTT. So you should also be familiar with MQTT. If in doubt, head over to our MQTT Basics lesson.

Introduction

This article will teach you the integration of OPC UA servers. In more detail, the following topics are covered:

  • Browsing the OPC UA address space
  • Identifying OPC UA datapoints
  • Specifying MQTT mappings
  • Creating the Device Commissioning profile
  • Establishing a connection via the Connectware Admin UI
  • Verifying data in the Connectware Explorer

The Commissioning Files used in this lesson are made available in the Example Files Repository on Github.

Selecting the tools

OPC UA server

Our example utilizes the public OPC UA server at opcuaserver.com. This makes it very easy to get started, but please be warned, that a OPC UA server used in production should neither be exposed to the Internet, nor should allow anonymous access. In case you bring your own device instead (e.g. a Simatic S7-1500 PLC), that's perfectly fine. If so, please make sure that a basic TCP connection is possible.

OPC UA browser

We will use FreeOpcUa's Simple OPC-UA GUI client for exploration in this guide. It's open source and available for all major OSs. If you feel more comfortable working on the terminal, go for Etienne Rossignon's opcua-commander. Or, if you prefer online tools, try One-Way Automation's OPC UA Web Client. It is free to use, but will ask you to sign up first and you won't be able to connect to servers on your local network. The choice is yours.

Exploring the OPC UA address space

Now that we have assembled all our tools, let's get started! Run your OPC UA browser and connect to the endpoint opc.tcp://opcuaserver.com:48010 (or whatever endpoint applies to you). Tada! – regardless of the chosen server/client, the three characteristic root nodes Objects, Types, and Views should show up, once the connection gets established. Explaining the OPC UA address space is certainly out of scope for this lesson – so we will only deal with the Objects tree here. But if you want to go further, then the Address Space Concepts documentation by Unified Automation is a good starting point.

OPC UA server connection established

Selecting datasource nodes

Go ahead and explore everything beneath Objects until you find the node displayed as CurrentTime. Select it and take a look at the Attributes pane – according to the NodeClass attribute we are dealing with a Variable here which implies, that there is a Value attribute as well. The Device Commissiong Profile, which we are to create in the next step, will deals with Variable nodes. They allow us to read and write data, depending on their designated AccessLevel attribute.

Proceed now with a right click on CurrentTime and select subscribe to data change. The Subscriptions pane then shows the actual value and it is updating at a fast rate.

OPC UA server browse currenttime

Now we know, that Variable nodes in the OPC UA address space are the datasources, but to utilize them with the Connectware, how do we reference them? There are two choices:

  1. By NodeId, which is a node's unique identifier. For example, the CurrentTime variable's NodeId is i=2258.

  2. By BrowsePath, which is the path of BrowseNames when you navigate the treeview. For example, the CurrentTime variable's BrowsePath assembles to /0:Objects/0:Server/0:ServerStatus/0:CurrentTime.

Both approaches have their pros and cons. In general, the NodeId is less clumsy than the BrowsePath, but also less descriptive. In this example, we prefer the NodeId and preserve some of the tree structure semantics when we create the MQTT mappings. You can find best practices for modelling your MQTT topics in our lesson Designing your MQTT Topic Structure.

Let's pick some more variables from the address space. Below you find a table of all the variables and there relevant data that will be used in the example. Pay attention to the last variable in the table. The Temperature Setpoint not only allows us to read data, but to also write data! That's pretty cool, since we can actually control something.

|Variable             |NodeId                                      |BrowsePath                                                               |AccessLevel              |
|–––––––––––––––––––––|––––––––––––––––––––––––––––––––––––––––––––|–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––|–––––––––––––––––––––––––|
|CurrentTime          |i=2258                                      |/0:Objects/0:Server/0:ServerStatus/0:CurrentTime                         |CurrentRead              |
|Humidity             |ns=3;s=AirConditioner_1.Humidity            |/0:Objects/3:BuildingAutomation/3:AirConditioner_1/3:Humidity            |CurrentRead              |
|Power Consumption    |ns=3;s=AirConditioner_1.PowerConsumption    |/0:Objects/3:BuildingAutomation/3:AirConditioner_1/3:PowerConsumption    |CurrentRead              |
|Temperature          |ns=3;s=AirConditioner_1.Temperature         |/0:Objects/3:BuildingAutomation/3:AirConditioner_1/3:Temperature         |CurrentRead              |
|Temperature Setpoint |ns=3;s=AirConditioner_1.TemperatureSetPoint |/0:Objects/3:BuildingAutomation/3:AirConditioner_1/3:TemperatureSetPoint |CurrentRead, CurrentWrite|

Writing the Device Commissioning File

The Device Commissioning File contains all connection parameters, mapping parameters and is read by the Connectware. To understand the file's anatomy in detail, please consult to the Reference docs. To get started, open a text editor and create a new file, e.g. opcua-example-commissioning-file.yml. The Commissioning File is in the YAML format, perfectly readable for human and machine! We will now go through the process of defining its three sections:

  • Source
  • Target
  • Mappings

Source

The source protocol section typically describes the device we want to integrate. It defines the device protocol and the connection parameters, along with optional defaults. This is the source section for our example:

source:
  driver: opcua
  connection:
    protocol: opc.tcp
    host: opcuaserver.com
    port: 48010
    username:
    password:
  defaults:
    operation: subscribe
    samplingInterval: 2000

Here we specify that we want to connect to an OPC UA server over TCP (opc.tcp). We define the host, the port and for demo purpose a username and password (which we leave blank for the example OPC UA server). Further, we set a default operation and samplingInterval, which will be applied to all mappings. If not stated different, each variable should be subscribed to value change at a minimum sampling interval of 2 seconds.

Target

The target protocol section is very simple if we stick with the default behavior. All data should be mapped to the internal MQTT broker of the Connectware. This is the target section:

target:
  driver: mqtt
  defaults:
    operation: write
    topicPrefix: cybus/learn

Our defaults here instruct the device-mapper to publish all source messages to their corresponding target MQTT topics, prefixed with cybus/learn.

Mappings

The mappings section references the datapoints that we have selected earlier. Let's add each OPC UA node and specify a corresponding target MQTT topic. Note the interchangeable use of nodeId and browsePath:

mappings:
# -----------------------------------------------------------------------------
# Server CurrentTime
- source:
    browsePath: /0:Objects/0:Server/0:ServerStatus/0:CurrentTime
  target:
    topic: server/status/currenttime
# -----------------------------------------------------------------------------
# Humidity
- source:
    browsePath: /0:Objects/3:BuildingAutomation/3:AirConditioner_1/3:Humidity
  target:
    topic: building-automation/airconditioner/1/humidity
# -----------------------------------------------------------------------------
# PowerConsumption
- source:
    nodeId: ns=3;s=AirConditioner_1.PowerConsumption
  target:
    topic: building-automation/airconditioner/1/power-consumption
# -----------------------------------------------------------------------------
# Temperature
- source:
    nodeId: ns=3;s=AirConditioner_1.Temperature
  target:
    topic: building-automation/airconditioner/1/temperature
# -----------------------------------------------------------------------------
# Temperature Setpoint
- source:
    nodeId: ns=3;s=AirConditioner_1.TemperatureSetPoint
  target:
    topic: building-automation/airconditioner/1/temperature
- source:
    operation: write
    nodeId: ns=3;s=AirConditioner_1.TemperatureSetPoint
  target:
    operation: subscribe
    topic: building-automation/airconditioner/1/temperature/set

As you may have noticed already, the Temperature Setpoint mapping is a bit different from the previous ones - here we have two mappings, one monitoring the variable and the other writing to the variable, when a new setpoint is received via MQTT. To make the write operation work, we simply have to reverse the data flow by overriding the operation properties (remember, we set that in the source and target defaults).

Installing the device

You now have the Commissioning File ready for installation. Head over to the Devices tab in the Connectware Admin UI and hit the Plus button to select upload the Commissioning File. The Connectware will immediately establish the connection to both source and target and displays the connection status on the created device card. You can expand the the card to see all current mappings associated with it.

Admin UI Devices View

Verifying the data

Now that we have a connection established between OPC UA server and Connectware, we can go to the Explorer tab, where we see a tree structure of our newly created datapoints. Hover an entry and select the eye icon on the right – this activates the live view and you should see data coming in at a rate that reflects the configured source sampleInterval.

Admin UI Explorer View

You may notice quite a payload there, which is because OPC UA provides a lot of context for each reading. Applications consuming the data must take care of JSON parsing to pick the desired properties.

{
  "value": {
    "dataType": "Double",
    "arrayType": "Scalar",
    "value": 59.95801599433421
  },
  "statusCode": {
    "value": 0,
    "description": "No Error",
    "name": "Good"
  },
  "sourceTimestamp": "2018-09-17T17:38:20.398Z",
  "sourcePicoseconds": 203100000,
  "serverTimestamp": "2018-09-17T17:38:20.398Z",
  "serverPicoseconds": 203100000
}

Summary

We learned quite a few things here. First, we used an OPC UA client application to browse the address space. This enabled us to pick the variables of our interest and reference them by their NodeId, or by BrowsePath. Given that information, we created a Device Commissioning File and installed the profile on the Connectware. In the Explorer we finally saw the live data on corresponding MQTT topics and are now ready to go further with our OPC-UA integration.

Where to go from here

The Connectware offers powerful features to build and deploy applications for gathering, filtering, forwarding, monitoring, displaying, buffering, and all kinds of processing data... why not build a dashboard for instance? For guides checkout more of Cybus Learn.