# MQTT Communication

Before you start exchanging messages with the cloud (via Edge Proxy), you need to connect with the MQTT broker that is running on your Ability Edge. We have listed the environment variables that will allow you to get all the necessary information (MQTT broker URL, username, password). In this article, we will show you an example of how you can use these values to connect to the broker. Although we only show you examples in C# and Node.js, you could use any other programming language that supports the MQTT protocol.

# Environment variables

Every Edge module has a number of environment variables, which are listed below:

# Common variables

Here is a list of environment variables that are required for every single Edge to work properly:

  • object_id - objectId of the module in the Ability Information Model
  • mqtt_client_id - the client ID of the module for MQTT communication
  • module_id - the login to establish the MQTT communication
  • mqtt_password_file - the path to the file that contains a password for establishing MQTT communication
  • mqtt_url - URL to the MQTT broker

# MQTT Topics

These variables contain the MQTT topics that your module will use to communicate with the Edge Agent.

  • topics_model_in - information models are delivered to the module from the cloud via this topic
  • topics_model_out - use this topic to send information model updates to the cloud
  • topics_methods_in - whenever a method/command is invoked from the cloud, it is delivered via this topic
  • topics_methods_out - use this topic to provide outputs/responses for method/command invocations
  • topics_messages_in - the optional acknowledgements for your requests are delivered here
  • topics_messages_out - use this topic to send telemetry information (variables, alarms, events) to the cloud
  • topics_local_in - used for local communication between Edge modules - messages from other modules will be delivered here
  • topics_local_out - used for local communication between Edge modules - send messages to other modules here
  • topics_files_out - module should publish a message to this topic when it wants to upload some local file to the cloud
  • topics_files_in - notifications about the file upload status will be delivered here

# Example of environment variables

Below, you can see an example of the environment variables that an Ability Edge module is given (only variables configured by the Ability Edge framework are shown). In this example, the module's name is "my_edge_module":

"module_id=my_edge_module",
"object_id=7f10b72b-7d09-4a8e-8e77-121645b9cc4a",
"mqtt_client_id=my_edge_module",
"mqtt_url=mqtt://edge-broker:1883",
"mqtt_password_file=/run/secrets/my_edge_module",
"topics_model_in=modules/my_edge_module/model/desired",
"topics_model_out=modules/my_edge_module/model/reported",
"topics_methods_in=modules/my_edge_module/methods/req",
"topics_methods_out=modules/my_edge_module/methods/res",
"topics_messages_in=modules/my_edge_module/messages/devicebound",
"topics_messages_out=modules/my_edge_module/messages/events",
"topics_local_in=modules/local/my_edge_module",
"topics_local_out=modules/local",
"topics_files_in=modules/my_edge_module/files/notifications",
"topics_files_out=modules/my_edge_module/files/upload",

The example below show the following operations:

  • etablishement of MQTT communication using parameters taken from the environment variables;
  • subscription to all of the topics where messages could come from;
  • publishing of one message - a single value for a variable called "temperature".

# C#

In the example we used the MQTTnet (version 3.0.14) for MQTT comunication.

using System.Linq;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;

var mqttClient = new MqttFactory().CreateMqttClient();
_mqttClient.UseApplicationMessageReceivedHandler(message => {
    //handle messages delivered from the topics you subscribe to
}); 

var mqttUrl = new System.Uri(Environment.GetEnvironmentVariable("mqtt_url");
var options = new MqttClientOptionsBuilder()
    .WithClientId(Environment.GetEnvironmentVariable("mqtt_client_id"))
    .WithTcpServer(mqttUrl.Host, mqttUrl.Port)
    .WithCredentials(
        Environment.GetEnvironmentVariable("module_id"),
        File.ReadAllText(Environment.GetEnvironmentVariable("mqtt_password_file")))
    .WithCleanSession()
    .Build();

await mqttClient.ConnectAsync(options, CancellationToken.None);

// Topics subscription
var topics = new[]
{
    Environment.GetEnvironmentVariable("topics_files_in"),
    Environment.GetEnvironmentVariable("topics_local_in"),
    Environment.GetEnvironmentVariable("topics_methods_in"),
    Environment.GetEnvironmentVariable("topics_model_in"),
    Environment.GetEnvironmentVariable("topics_messages_in")
};

var topicFilters = topics.Select(t => 
    new MqttTopicFilterBuilder().WithTopic($"{t}/#").Build());

await _mqttClient.SubscribeAsync(topicFilters);

// Sending a message (example of telemetry)

var message = new MqttApplicationMessageBuilder()
    .WithTopic($"{Environment.GetEnvironmentVariable("topics_messages_out")}/type=timeSeries")
    .WithPayload("{\"objectId\": \"116fff1d-d1c6-469b-8e8d-c0f6fd1a7f8e\", \"model\": \"abb.ability.device\", \"timestamp\": \"2021-02-09T13:52:21.4954232Z\",  \"value\": \"10.54\", \"variable\": \"temperature\"}")
    .WithExactlyOnceQoS()
    .WithRetainFlag()
    .Build();

await _mqttClient.PublishAsync(message, CancellationToken.None);

# Node.js

In the example we used the async-mqtt package for MQTT communications.

const mqtt = require("async-mqtt");
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);

const mqttClient = await mqtt.connectAsync(
    process.env.mqtt_url,
    { 
        username: process.env.mqtt_client_id, 
        password: (await readFile(process.env.mqtt_password_file)).toString('utf8') 
    })

mqttClient.on("message", receivedMessage) //callback for any incoming messages

// Topics subscription
await mqttClient.subscribe(`${process.env.topics_files_in}/#`)
await mqttClient.subscribe(`${process.env.topics_local_in}/#`)
await mqttClient.subscribe(`${process.env.topics_methods_in}/#`)
await mqttClient.subscribe(`${process.env.topics_model_in}/#`)
await mqttClient.subscribe(`${process.env.topics_messages_in}/#`)

// Sending a message (example of telemetry)
const message = {
    objectId: '116fff1d-d1c6-469b-8e8d-c0f6fd1a7f8e',
    variable: 'temperature',
    value: 10.54,
    timestamp: new Date().toISOString(),
    model: 'abb.ability.device'
}

await mqttClient.publish(
    `${process.env.topics_messages_out}/type=timeSeries`, 
    JSON.stringify(message()))
Last updated: 10/20/2021, 9:08:02 AM
Feedback