InfluxDB Service Integration

How to deploy InfluxDB as a Connectware service, including setup, configuration, and integrating data from OPC UA to InfluxDB.

This guide focuses on deploying containerized applications as a Connectware service. Step by step, we will create a service commissioning file that deploys an InfluxDB instance inside Connectware, configure Connectware's internal reverse proxy to access the container securely, and connect to a public OPC UA server to provide data for InfluxDB. Let's get started building the service commissioning file.

Prerequisites

To follow this guide, you will need the following:

Creating the Service Commissioning File

Services are installed using a service commissioning file. Within this text-based YAML file, all so-called resources like connections, endpoints, users, permissions, and containerized applications a service uses are listed. Below, we will derive an example service commissioning file that deploys an InfluxDB instance, which we can later use to visualize our data.

Description & Metadata

These first two sections of the service commissioning file provide general information. In the optional description section, you can give a short description of the service, which will also be displayed in the service details view on Connectware's Admin User Interface (Admin UI). The metadata section contains meta information for the service being installed. Only the name parameter is required, as it is used as the service ID. Other parameters, such as version, icon, provider, or homepage, are optional.

description: >
  Third-party Applications as Connectware Services Example
  How to deploy third-party applications as Connectware Services

metadata:
  name: third-party applications 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

This section configures values that are not set during installation. It allows us to create templates from services, where just a parameter like an IP address needs to be changed. In this case, we will have the host name and the port of our OPC UA server as parameters. This would allow us to quickly change these values as needed.

---
#------------------------------------------------------------------------------
# PARAMETERS
#------------------------------------------------------------------------------

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

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

Definitions

If we have some variables that we need more than once, we can use definitions for them. We recommend keeping them at the top of your service commissioning file if you need to change them. In this case, we use them to define some variables regarding InfluxDB that are needed on several occasions. The service described here is just an example. In a real deployment, it is recommended to secure passwords and tokens and not have them as clear text in your service commissioning files.

---
#------------------------------------------------------------------------------
# DEFINITIONS
#------------------------------------------------------------------------------

definitions:
  influxdbAdminUsername: admin
  influxdbAdminPassword: supersafepassword #only for example purposes
  influxdbToken: 'Em2KIZ5BGJC5Y39HAmtYWqc4nyAhR4c24qt6uGlYxJ4Y1GfOZtntqs3UgH1Ea4158k6gD5UKFps8u5Kc1HvSXB1diCxcz0niJpI'
  influxdbOrg: cybus

Resources

In the Resources section, we declare every resource needed for our service. All resources like connections, endpoints, users, permissions, and containerized applications are configured here.

Containers

Let's start with the container resources. They comprise the configuration for the Docker containers the service will deploy. These containers can either come from Docker Hub or from the Cybus Registry. That means any application deployed on Connectware can take full advantage of all the containerized software on Docker Hub and your custom containerized software delivered securely through the Cybus Registry.

In the example below, we pull the official InfluxDB from Docker Hub. Several options can be used when configuring containers. For the container-specific environment variables defined under the property environment, you should consult the container's documentation. If you have worked with Docker Compose before, the configuration of the container should feel familiar.

---
#------------------------------------------------------------------------------
# RESOURCES
#------------------------------------------------------------------------------

resources:
  #----------------------------------------------------------------------------
  # CONTAINERS
  #----------------------------------------------------------------------------

  influxdb:
    type: Cybus::Container
    properties:
      image: registry.hub.docker.com/library/influxdb:2.6
      ports:
        - 8086:8086
      volumes:
        - !sub '${influxdbDataVolume}:/var/lib/influxdb2'
        - !sub ${influxdbConfigVolume}:/etc/influxdb2
      environment:
        DOCKER_INFLUXDB_INIT_MODE: setup
        DOCKER_INFLUXDB_INIT_ORG: !ref influxdbOrg
        DOCKER_INFLUXDB_INIT_BUCKET: generic
        DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: !ref influxdbToken
        DOCKER_INFLUXDB_INIT_USERNAME: !ref influxdbAdminUsername
        DOCKER_INFLUXDB_INIT_PASSWORD: !ref influxdbAdminPassword

Volumes

Our configured container will need persistent storage space, so we create volumes for it. A volume is a resource that represents a storage space that can be associated with containers. We already linked the container resource to the volume resources we are configuring here: One for the database and another for configurations of InfluxDB.

---
#----------------------------------------------------------------------------
# VOLUMES
#----------------------------------------------------------------------------

influxdbDataVolume:
  type: Cybus::Volume

influxdbConfigVolume:
  type: Cybus::Volume

Ingress Routes

Now let’s make sure Connectware is able to connect to the containers. For that, we need to set up some ingress routes, which will configure the internal reverse proxy of Connectware. This is needed because service containers running within Connectware architecture are not directly exposed and are running separately from Connectware core containers for security reasons. Ingress routes make them accessible from the outside as well as from within Connectware.

Ingress routes allow communication between Connectware core containers and custom containers. For the InfluxDB container, we define a TCP route between the container port 8086, on which the InfluxDB is available, and Connectware port 8086.

# InfluxDB
influxdbRoute:
  type: Cybus::IngressRoute
  properties:
    container: !ref influxdb
    type: tcp
    containerPort: 8086
    connectwarePort: 8086

To learn more about ingress route resources, see Cybus::IngressRoute.

Frontend

Now let’s create a button for easy access to the InfluxDB frontend. To do that, we define a link resource that will provide a button named InfluxDB on our service details view in Admin UI.

---
#----------------------------------------------------------------------------
# FRONTENDS
#----------------------------------------------------------------------------

Influx_WebUI:
  type: Cybus::Link
  properties:
    name: InfluxDB
    href: 'http://localhost:8086/'

Connections

We have completely configured the container resources and can now treat them like any other protocol we want to utilize in a service.

First, we have to define a connection to the InfluxDB container we just configured. For the specific case of accessing a containerized application within Connectware, the host has to be defined as connectware. Like previously defined with the ingress route, InfluxDB will be available on Connectware port 8086. The name of the InfluxDB bucket to store information is not really important in this use case and will be set to generic. The transport scheme will be set to http. To have some data to feed into our InfluxDB in this example, we also connect to a public OPC UA server from opcuaserver.com. It is the same one we used in the guide Using Connectware as an OPC UA Server.

---
#----------------------------------------------------------------------------
# CONNECTIONS
#----------------------------------------------------------------------------

influxdbConnection:
  type: Cybus::Connection
  properties:
    protocol: Influxdb
    connection:
      scheme: http
      host: connectware
      bucket: generic
      token: !ref influxdbToken
      org: !ref influxdbOrg

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

Endpoints

To now be able to write some data into InfluxDB, we set up a write endpoint which writes a measurement called airconditioner.

---
#----------------------------------------------------------------------------
# ENDPOINTS
#----------------------------------------------------------------------------

# InfluxDB

airconditionerWrite:
  type: Cybus::Endpoint
  properties:
    protocol: Influxdb
    connection: !ref influxdbConnection
    write:
      measurement: airconditioner

To have some data we can push into that endpoint, we connect to some endpoints on the public OPC UA server.

# OPCUA

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:
      nodeId: ns=3;s=AirConditioner_1.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

Mappings

To write the data from our OPC UA endpoints into our InfluxDB endpoint, we need mappings. We will additionally do some data pre-processing in this mapping to get the information about the data origin into the database, and for that, we utilize a so-called rule. This rule is powered by Connectware's Rule Engine, which uses JSONata as a powerful query and transformation language. The expression in this case will add the name of the last subtopic to the messageʼs JSON string under the key measurement. The value of this key will overwrite the default measurement name we defined in the endpoint definition when sent to InfluxDB. It is determined by the + operator in the subscribe topic definition that acts as a wildcard while deriving a context variable named measurement.

---
#----------------------------------------------------------------------------
# MAPPINGS
#----------------------------------------------------------------------------

influxdbMapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          topic: 'building-automation/airconditioner/1/+measurement'
        publish:
          endpoint: !ref airconditionerWrite
        rules:
          - transform:
              expression: '$merge([$,{"measurement": $context.vars.measurement}])'

To bring the OPC UA data into the right format, we set up some mappings that publish the data under the topic prefix building-automation/airconditioner/1/.

mqttMapping:
  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

With all of these mappings in place, we have now successfully connected our OPC UA data with our newly installed InfluxDB. The data is now flowing into the database.

Accessing InfluxDB’s UI and Setting up Your First Dashboard

If you installed and enabled the service, you should see an "InfluxDB" button on the Service Page next to the Links section. The button is the result of the link resource we defined and will, in this case, open a new tab with InfluxDB's Web UI.

On the login screen of InfluxDB, type in the username and password you set in your service commissioning file.

Let's create our first dashboard. Click Create Dashboard and in the dashboard editor click Add Cell. This should look similar to the screenshot below. When you select the generic bucket, you should see the defined OPC UA endpoints. Select the data you want to display and customize the cell to your liking.

Here is an example dashboard displaying the data from the OPC UA endpoints we configured in our service commissioning file.

Summary

In this guide, we learned how to deploy containerized applications as Connectware Services using InfluxDB, a time series database that provides simple visualization via its Web UI or could be used to build more sophisticated dashboards using Grafana in the future.

Last updated

Was this helpful?