Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages
Cybus Learn |   How to Connect to an OPC UA Server

How to | 14 Juli 2020

How to Connect to an OPC UA Server

By: Marius Schmeding

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 Commissioning File
  • 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 is 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 ObjectsTypes, 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 Commissioning File, which we are about to create in the next step, will deal 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 current time

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 BrowseName 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.

Let’s pick some more variables from the address space. Below you find a table of all the variables and their 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 Commissioning File

The Commissioning File contains all connection and 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 the required sections for this example:

  • Description
  • Metadata
  • Parameters
  • Resources

Description and Metadata

These sections contain more general information about the commissioning file. You can give a short description and add a stack of metadata. Regarding the metadata, only the name is required while the rest is optional. We will just use the following set of information for this lesson:

description: >

  OPC UA Example Commissioning File
  Cybus Learn - How to connect and integrate an OPC UA server
  https://learn.cybus.io/lessons/how-to-connect-and-integrate-an-opcua-server/

metadata:

  name: OPC UA Example Commissioning File
  version: 1.0.1
  icon: https://www.cybus.io/wp-content/uploads/2019/03/Cybus-logo-Claim-lang.svg
  provider: cybus
  homepage: https://www.cybus.io

Parameters

Parameters allow the user to customize Commissioning Files for multiple use cases by referring to them from within the Commissioning File. Each time a Commissioning File is applied or reconfigured in the Connectware, the user is asked to enter custom values for the parameters or to confirm the default values.

parameters:

  opcuaHost:
    type: string
    description: OPC UA Host Address
    default: opcuaserver.com

  opcuaPort:
    type: integer
    description: OPC UA Host Port
    default: 48010

We are defining the host address details of our OPC UA server as parameters, so they are used as default, but can be customized in case we want to connect to a different server.

Resources

In the resources section we declare every resource that is needed for our application. The first resource we need is a connection to the OPC UA server.

Cybus::Connection
resources:

  opcuaConnection:
    type: Cybus::Connection
    properties:
      protocol: Opcua
      connection:
        host: !ref opcuaHost
        port: !ref opcuaPort
        #username: myUsername
        #password: myPassword

After giving our resource a name – for the connection it is opcuaConnection – we define the type of the resource and its type-specific properties. In case of Cybus::Connection we declare which protocol and connection parameters we want to use. For details about the different resource types and available protocols, please consult the Reference docs. For the definition of our connection we reference the earlier declared parameters opcuaHost and opcuaPort by using !ref. If you are using a username and password, you could also create parameters, to make them configurable. In our case the server does not require credentials.

Cybus::Endpoint

The next resources needed are the datapoints that we have selected earlier. Let’s add each OPC UA node by extending our list of resources with some endpoints.

  currentTime:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: i=2258

  Humidity:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        browsePath: /0:Objects/3:BuildingAutomation/3:AirConditioner_1/3:Humidity
        
  PowerConsumption:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: ns=3;s=AirConditioner_1.PowerConsumption
        
  Temperature:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: ns=3;s=AirConditioner_1.Temperature
        
  TemperatureSetpointSub:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      subscribe:
        nodeId: ns=3;s=AirConditioner_1.TemperatureSetPoint

  TemperatureSetpointWrite:
    type: Cybus::Endpoint
    properties:
      protocol: Opcua
      connection: !ref opcuaConnection
      write:
        browsePath: /0:Objects/3:BuildingAutomation/3:AirConditioner_1/3:TemperatureSetPoint

Each resource of the type Cybus::Endpoint needs a definition of the used protocol and on which connection it is rooted. Here you can easily refer to the previously declared connection by using its name. Furthermore we have to define to which OPC UA node the endpoint should subscribe or write by giving the nodeId or the browsePath.

Cybus::Mapping

To this point we are already able to read values from the OPC UA server and monitor them in the Connectware Explorer or on the default MQTT topics related to our service. To achieve a data flow that would satisfy the requirements of our integration purpose, we may need to add a mapping resource to publish the data on topics corresponding to our MQTT topic structure.

  mapping:
    type: Cybus::Mapping
    properties:
      mappings:
        - subscribe:
            endpoint: !ref currentTime
          publish:
            topic: 'server/status/currenttime'
        - subscribe:
            endpoint: !ref Humidity
          publish:
            topic: 'building-automation/airconditioner/1/humidity'
        - subscribe:
            endpoint: !ref PowerConsumption
          publish:
            topic: 'building-automation/airconditioner/1/power-consumption'
        - subscribe:
            endpoint: !ref Temperature
          publish:
            topic: 'building-automation/airconditioner/1/temperature'
        - subscribe:
            endpoint: !ref TemperatureSetpointSub
          publish:
            topic: 'building-automation/airconditioner/1/temperature-setpoint'
        - subscribe:
            topic: 'building-automation/airconditioner/1/temperature-setpoint/set'
          publish:
            endpoint: !ref TemperatureSetpointWrite

In this case the mapping defines which endpoints value is published on which MQTT topic. But as you may have noticed already, the Temperature Setpoint mapping is a bit different from the previous ones – here we have two endpoints: 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 and map it from the MQTT topic to the according endpoint. Then you can write to the endpoint by simply publishing on this MQTT topic. Please note that write messages have to be in JSON format containing the value as follows:

{
  "value": true
}

This message has the obligatory key „value“, which can contain a value of any data type (which should match the concerning endpoint): For instance boolean values just use true/false, integers are represented by theirselves like 3, decimals similarly appear as 10.45 and strings are written in "quotes".

Installing the Commissioning File

You now have the Commissioning File ready for installation. Head over to the Services tab in the Connectware Admin UI and hit the  (+) button to select upload the Commissioning File. You will be asked to set values for each member of the section parameters or confirm the default values. With a proper written Commissioning File, the confirmation of this dialog will result in the installation of a Service, which manages all the resources we just defined: The connection to the OPC server, the endpoints collecting data from the server and the mapping controlling where we can access this data. After enabling this Service you are good to go on and see if everything works out!

Admin UI Services

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.

Admin UI Explorer

On MQTT topics the data is provided in JSON format and applications consuming the data must take care of JSON parsing to pick the desired properties. Though this JSON structure is not represented by the Explorer view. Taking our currentTime topic as an example, the raw output would look as follows:

{
  "value":"2020-07-14T11:43:06.632Z",
  "timestamp":1594726986632
}

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 Commissioning File and installed the Service 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 gatheringfilteringforwardingmonitoringdisplayingbuffering, and all kinds of processing data… why not build a dashboard for instance? For guides checkout more of Cybus Learn.

Check out our media to this article: