MQTT Publisher

The flir-north-mqtt-scripted plugin provides a mechanism to publish MQTT message from a FLIR Bridge instance to an MQTT broker. It also provides a control back from an MQTT broker into the FLIR Bridge instance.

The plugin provides for a variety of MQTT features

  • Publishing to a topic of your choice.

  • An optional payload formatting script in Python that allows you to tailor the MQTT messages to your choice of format and content.

  • Selection of the quality of service to use.

  • Optional username/password authentication with the MQTT broker.

  • Use of certificates and private keys to secure your MQTT payloads.

  • Choice of control MQTT topics

  • Ability to send reading data or internal statistics as MQTT payloads.

Creation North

You create your north task or service in FLIR Bridge to send data to MQTT in the same way as any other north bound service.

  • Select North from the left hand menu bar.

  • Click on the + icon in the top left

  • Choose mqtt-scripted from the plugin selection list

  • Name your task

  • Click on Next

  • Configure the plugin

    mqtt_1

  • MQTT Broker: The IP address/hostname of the MQTT broker to use. Note FLIR Bridge requires an external MQTT broker is run currently and does not provide an internal broker in the current release.

  • Publish Topic: The MQTT topic to which data will be published. The topic may be a simple string or may contain a macro to be substituted from the current reading that is being send as the MQTT payload. Macros take the form $<name>$ where name is either the name of a datapoint within the reading or the reserved name ASSET.

  • Script: The Python script to execute to process the messages published. Initially a file must be uploaded, however once uploaded the user may edit the script in the box provided. A script is optional.

  • Control Topic: The MQTT topic to which the north will subscribe to receive control messages. The topic may include the usual MQTT wildcards; + for a single level wildcard and # for a multi-level wildcard

  • QoS: The MQTT Quality of Service to use for published messages.

  • Username: The username to be used if required for authentication. This should be left blank if authentication is not required.

  • Password: The password to use if username is to be used.

  • Trusted Certificate: The trusted certificate of the MQTT broker. If MQTTS communication is not required then this can be left blank.

  • Client Certificate: The certificate that will be used by the MQTT plugin.

  • MQTTS Key: The private key of the MQTT plugin. If the key is included in the PEM file of the client certificate this may be left blank.

  • Key Password: The password used to encrypted the private key. This may be left blank if the private key was not encrypt.

  • Source: The source of data to be published to the MQTT broker. This may be the readings or the statistics of FLIR Bridge itself.

  • Click on Next

  • Enable your north task and click on Done

Topics

The plugin supports both a single, fixed topic for all transmitted data that it sends and a mechanism by which the topic may be related to the data that is sent upstream. These dynamic topics are created using a substitution mechanism in the topic string.

In the simplest form, this may be to use the asset code of the asset as the topic string, this results in each asset being published to a different topic. To use the asset name you simply set the Publish Topic configuration item to the value $ASSET$.

However, the MQTT topic is often used to create namespaces within an organisation and it may be made up of many components. It is possible that these components exist as meta data, or may be added as meta data to a reading. In this case the values of datapoints may be used in the topic string. As an example, if the data pipeline that process data from a PLC used a filter in the pipeline to add an identifier for the production line to the readings, then this could be used in the MQTT topic.

For example we have a datapoint called prodline which contains the production line identifier, we can set the MQTT topic to be $prodline$/Centrifuge to allow us to publish data to a topic that contains the production line in the hierarchy.

Multiple substitutions may be included in a single topic in order to build up more complex name structures.

Another use of this substitution mechanism is when the data source provides some naming path or context for the data that is read. An example of this is the Asset Framework location when fetching data from an AVEVA PI Server, or the class path when reading data from an OPC UA server. These paths may be included as datapoints and either used verbatim in a substitution for the topic, augmented with other substitutions or fixed text. The paths themselves may also be modified in the data pipeline before arriving at the MQTT north plugin.

Generally, text datapoint values will be used in substitutions, however it is possible to use numeric values but care should be taken that the values chosen have predictable values that have meaning in a topic. General datapoints that contain measurements rarely have any use within a topic substitution.

Message Payload

The payload that is sent by this plugin is a simple JSON presentation of a set of reading values. A JSON array is sent with one or more reading objects contained within it. Each reading object consists of a timestamp, an asset name and a set of data points within that asset. The data points are represented as name value pair JSON properties within the reading property.

The fixed part of every reading contains the following

Name

Description

ts

The timestamp as an ASCII string in ISO 8601 extended format. If no time zone information is given it is assumed to indicate the use of UTC. This timestamp is added by FLIR Bridge when it first reads the data.

user_ts

The timestamp as an ASCII string in ISO 8601 extended format. If no time zone information is given it is assumed to indicate the use of UTC. This timestamp is added by the device itself and can be used to reflect the timestamp the data refers to rather than the timestamp FLIR Bridge read the data.

asset

The name of the asset this reading represents.

readings

A JSON object that contains the data points for this asset.

The content of the readings object is a set of JSON properties, each of which represents a data value. The type of these values may be integer, floating point, string, a JSON object or an array of floating point numbers.

A property

"voltage" : 239.4

would represent a numeric data value for the item voltage within the asset. Whereas

"voltageUnit" : "volts"

Is string data for that same asset. Other data may be presented as arrays

"acceleration" : [ 0.4, 0.8, 1.0 ]

would represent acceleration with the three components of the vector, x, y, and z. This may also be represented as an object

"acceleration" : { "X" : 0.4, "Y" : 0.8, "Z" : 1.0 }

both are valid formats within FLIR Bridge.

An example payload with a single reading would be as shown below

 [
    {
        "user_ts"   : "2020-07-08 16:16:07.263657+00:00",
        "ts"        : "2020-07-08 16:16:07.263657+00:00",
        "asset"     : "motor1",
        "readings"  : {
                      "voltage"  : 239.4,
                      "current"  : 1003,
                      "rpm"      : 120147
                      }
    }
]

Payload Script

If a script is given then it must provide a method called convert, that method is passed a single reading as a Python DICT and must return a formatted string payload for that reading.

As a simple example lets assume we want a JSON payload to be sent, but we want to use different keys to those in the default reading payload. We will replaces readings with data, user_ts with when and asset with device. A simple Python script to do this would be as follows;

import json
def convert(reading):
    newReading = {
       "data" : reading["readings"],
       "when" : reading["user_ts"],
       "device" : reading["asset"],
    }
    return json.dumps(newReading)

An MQTT message would be sent with one reading per request and that reading would be formatted as a JSON payload of the format

{
    "data":
    {
        "sinusoid": 0.0,
        "sine10": 10.0
    },
     "when": "2022-02-16 15:12:55.196494+00:00",
     "device": "sinusoid"
}

Note that white space and newlines have been added to improve the readability of the payload.

The above example returns a JSON format payload, the return may however not be encoded as JSON, for example an XML payload

from dict2xml import dict2xml
def convert(reading):
    newReading = {
       "data" : reading["readings"],
       "when" : reading["user_ts"],
       "device" : reading["asset"],
    }
    payload = "<reading>" + dict2xml(newReading) + "</reading>"
    return payload

This return XML format data as follows

<reading>
   <data>
     <sine10>10.0</sine10>
     <sinusoid>0.0</sinusoid>
   </data>
   <device>sinusoid</device>
   <when>2022-02-16 15:12:55.196494+00:00</when>
 </reading>

Note that white space and formatting have been added for ease of reading the XML data. You must also make sure you have installed the Python XML support as this is not normally installed with FLIR Bridge, To do this run

pip3 install dict2xml

from the command line of the FLIR Bridge machine.

Control

The plugin will subscribe to a control topic in order to receive control messages into the FLIR Bridge system, these control messages take the form of JSON documents. These documents describe write requests that will be made to system. The most general form of request would be

{
    "write" : {
        "EngineSpeed" : "58"
    }
}

This would result in a broadcast write request being sent to all south services that support control to set the variable EngineSpeed to the value 58.

Requests may be targeted at a single service by giving the name of that service

{
    "service" : "Line002",
    "write" : {
        "EngineSpeed" : "58"
    }
}

Alternatively, if the request could be targeted to the service that is responsible for the ingestion of a particular asset, in this case the service that ingests the asset pump0013.

{
    "asset" : "pump0013",
    "write" : {
        "EngineSpeed" : "58"
    }
}

The request can also be targeted to an automation script that is run by the control dispatcher service, here the script name is given.

{
    "script" : "adjustSpeed",
    "write" : {
        "EngineSpeed" : "58"
    }
}

The script may implement multiple steps and interact with multiple services within FLIR Bridge.

All control requests will be validated bu the control dispatcher service to ensure that this MQTT north plugin has been given permission to interact with the services and scripts to which it sends control requests.

See Also

flir-filter-expression - A FLIR Bridge processing filter plugin that applies a user define formula to the data as it passes through the filter

flir-filter-python35 - A FLIR Bridge processing filter that allows Python 3 code to be run on each sensor value.

flir-south-mqtt-scripted - An MQTT south plugin that allows a Python script to be added to decode the MQTT payload

flir-south-simple-rest - A generic REST south plugin with support for a variety of common REST payloads and Python scripting to manipulate call results.