mosquitto mqtt – IoT Technology Overview

Spread the love

MQTT is a machine-to-machine messaging protocol, designed to provide lightweight publish/subscribe communication to “Internet of Things” devices. It is commonly used for geo-tracking fleets of vehicles, home automation, environmental sensor networks, and utility-scale data collection.

Mosquitto is a popular MQTT server (or broker, in MQTT parlance) that has great community support and is easy to install and configure.

we’ll install Mosquitto, retrieve SSL certificates from Let’s Encrypt, and set up our broker to use SSL to secure our password-protected MQTT communications.

The goal of this post is to introduce the lightweight protocol MQTT and its capabilities to send data between devices and other systems and to demonstrate them by implementing two clients with Eclipse Paho.

The term Internet of Things was first used by Kevin Ashton in 2009 for interconnecting physical devices over the internet. The basic idea is very simple: Physical devices can exchange data between each other or being controlled by others. Examples of such devices would be a refrigerator, a car, a building or basically any other electronic device. One of the most common use cases is the collection, transmission, consolidation and displaying of sensor data. The results could be a web dashboard with the aggregated values or an alarm, when a threshold is exceeded.

The application scenarios are almost unlimited. Imagine your alarm clock would know that your train to work is 15 minutes late and adjust itself accordingly. Also your coffee maker is switched on automatically 15 minutes later to make you a hot cup of coffee before you leave for work. Sounds like the future ? All that is already possible today. Ericsson predicts that in 2020 50 billion devices are connected over the internet. The communication between the huge amount of devices is enabled by IPv6 and lightweight communication protocols like MQTT.

MQTT was developed by Andy Stanford-Clark (IBM) and Arlen Nipper (Eurotech; now Cirrus Link) in 1999 for the monitoring of an oil pipeline through the desert. The goals were to have a protocol, which is bandwidth-efficient and uses little battery power, because the devices were connected via satellite link and this was extremely expensive at that time.

The protocol uses a publish/subscribe architecture in contrast to HTTP with its request/response paradigm. Publish/Subscribe is event-driven and enables messages to be pushed to clients. The central communication point is the MQTT broker, it is in charge of dispatching all messages between the senders and the rightful receivers. Each client that publishes a message to the broker, includes a topic into the message. The topic is the routing information for the broker. Each client that wants to receive messages subscribes to a certain topic and the broker delivers all messages with the matching topic to the client. Therefore the clients don’t have to know each other, they only communicate over the topic. This architecture enables highly scalable solutions without dependencies between the data producers and the data consumers.

MQTT Message Pattern :

As said before, MQTT protocol implements publish-subscribe paradigm. This paradigm decouples a client that publishes a message (“publisher”) to other clients that receive the message (“subscribers”). Moreover, MQTT is asynchronous protocol, that means that it does not block the client while it waits for the message. In contrast to HTTP protocol, that is mainly a synchronous protocol. Another interesting property of MQTT protocol is that it does not require that the client (“subscriber”) and the publisher are connected at the same time.

MQTT Publisher-Subscriber Pattern :

As described above MQTT is a message based protocol that uses publisher-subscriber pattern. The key component in MQTT is the MQTT broker. The main task of MQTT broker is dispatching messages to the clients (“subscribers”). In other words, it receives messages from publisher and dispatches these messages to the subscribers. While it dispatches messages, the MQTT broker uses the topic to filter the clients that will receive the message. The topic is a string and it is possible to combine the topics creating topic levels.

A topic is like a virtual channel that connects a publisher to its subscribers. This topic is managed by the MQTT broker. Through this virtual channel, the publisher is decoupled from the subscribers and the clients (publishers or subscribers) does not have to know each other. This makes this protocol highly scalable without a direct dependency from the message producer (“publisher”) and the message consumer (“subscriber”).

The schema below describes the MQTT architecture:

Use Case:  In order to make the subsequent code more understandable, we will use the transferring of sensor data from a temperature and brightness sensor to a control center over the internet as an example. The sensors will be connected to a Raspberry Pi, which acts as gateway to the MQTT broker, which resides in the cloud. On the other side is a second device, the control center, that also has an MQTT client and receives the data. Additionally we will implement a notification, which alerts the control center if the sensor is disconnected.

First we will implement the sensor client, which is simulating a thermometer and a brightness sensor. It should send a current value every second to the MQTT broker. In this case we are using the HiveMQ public broker on the MQTT Dashboard. The first step is to create an instance of the MqttClient class.

public class Publisher

{

public static final String BROKER_URL = “tcp://broker.mqttdashboard.com:1883”;

private MqttClient client;

 

public Publisher()

{

 

String clientId = Utils.getMacAddress() + “-pub”;

try

{

client = new MqttClient(BROKER_URL, clientId);

}

catch (MqttException e)

{

e.printStackTrace();

System.exit(1);

}

}

}

As parameters for the constructor it is necessary to specify the URL of the broker (tcp://broker.mqtt dashboard.com:1883) and also the client id. The latter is an unique identifier overall the broker. A good choice for the client id is the MAC address of the computer, because that is automatically unique. In the example -pub is added to the mac address, because otherwise it wouldn’t work starting both clients on the same machine for testing. After creating the instance, it is possible to try to connect to the broker with calling client.connect(). Apart from a simple connect, it is also possible to hand over more parameters. One example is the clean session flag. When it is set to true, the broker will wipe the session every time the client disconnects, otherwise it will keep the subscription and buffer the messages sent with Quality of Service 1 and 2 (more on this later). The session is assigned to the client id, therefore it is truly important to have it unique. Another option is Last Will and Testament (LWT), which helps detecting failures of other clients. As stated above every client has an open connection, so when the client disconnects ungracefully the broker can detect that. If the client has set a LWT topic and message on connect, the broker will send that to the specified topic, which allows the client to notify others about its failure.

MqttConnectOptions options = new MqttConnectOptions();

options.setCleanSession(false);

options.setWill(client.getTopic(“home/LWT”), “I’m gone”.getBytes(), 2, true);

client.connect(options);

 

Now we have to implement the business logic to retrieve the values and send them every second, therefore we use an infinite loop and the methods publish Temperature and publishBrightness. Each method creates a MqttTopic object and a random value, which will then be published.

 

public static final String TOPIC_TEMPERATURE = “home/temperature”;

//…

while (true)

{

publishBrightness();

Thread.sleep(500);

publishTemperature();

Thread.sleep(500);

}

private void publishTemperature() throws MqttException {

final MqttTopic temperatureTopic = client.getTopic(TOPIC_TEMPERATURE);

final int temperatureNumber = Utils.createRandomNumberBetween(20, 30);

final String temperature = temperatureNumber + “°C”;

 

temperatureTopic.publish(new MqttMessage(temperature.getBytes()));

}

Each message can be published with one of three quality of service levels (QoS). These levels are associated with different guarantees. A message send with level 0 doesn’t have a guarantee at all, it implies fire and forget. Level 1 guarantees that the message will at least arrive once, but can arrive more than once. Level 2 is the most sophisticated choice, which guarantees that the message arrives at the destination exactly once. The choice of QoS is a trade-off, between protocol overhead and the guarantee that the message arrives, because ensuring QoS 2 is using more bandwidth than QoS 0.

The next step is implementing the subscribing client, which is reading the values on the topics home/temperature and “home/brightness”, plus observes the home/LWT topic for the last will message to detect a failure of the sensor client. The initialization of the MqttClient instance is almost the same, except we use -sub as a suffix for the client id. For receiving the messages sent by the sensor simulator, it is necessary to implement the MqttCallback interface. The MqttCallback interface defines three methods that need to implemented:

connectionLost, messageArrived and deliveryComplete. connectionLost is called when the connection is unexpectedly closed form the MQTT broker. This method is the best place for a reconnect logic. The method messageArrived is called when the broker sends a new message to this particular client. Finally, there is the delivery Complete method that is called after a message with QoS 1 or 2 reaches the broker. For our use case implementing the messageArrived method is enough. All arriving messages should be print out with topic and payload and if it is sent on the home/LWT topic, we additionally print out Sensor gone!.

MQTT is asynchronous protocol, that means that it does not block the client while it waits for the message. In contrast to HTTP protocol, that is mainly a synchronous protocol. Another interesting property of MQTT protocol is that it does not require that the client (“subscriber”) and the publisher are connected at the same time.

This protocol used publish-subscribe paradigm in contrast to HTTP based on request/response paradigm.  It uses binary messages to exchange information with a low overhead. It is very simple to implement and it is open. All these aspects contribute to its large adoption in IoT. Another interesting aspect is the fact that MQTT uses TCP stack as transmission substrate.

public class SubscribeCallback implements MqttCallback

{

@Override

public void connectionLost(Throwable cause) {}

@Override

public void messageArrived(MqttTopic topic, MqttMessage message)

{

System.out.println(“Message arrived. Topic: ” + topic.getName() + ” Message: ” + message.toString());

if (“home/LWT”.equals(topic.getName()))

{

System.err.println(“Sensor gone!”);

}

}

@Override

public void deliveryComplete(MqttDeliveryToken token) {}

}

After implementing the callback, we have to make it known to the MqttClient before connecting. Also after the successful connection is established, it is necessary to subscribe

 

mqttClient.setCallback(new SubscribeCallback());

mqttClient.connect();

mqttClient.subscribe(“home/#”);

 

Run both clients :

Now that the sensor client and the Control Center are implemented, it is time to run both applications. We start the Control Center first and then the sensor client. Once the sensor client starts, messages arrive at the Control Center. If you will now exit the sensor client ungracefully, this is recognized by the Control Center immediately through the Last Will and Testament message.

Congratulations, you have now build your first Internet of Things application with MQTT!

MeenaG Staff

Internet of Things Enthusiast

Leave a Reply