MQTT.
MQTT (MQ Telemetry Transport
Protocol) is a protocol widely used in IoT space.
It is a messaging protocol designed to be used
primarily in resource-constrained environment.
For example:
· Situation where the bandwidth is
limited, the latency is high;
· Situation where the transmitting
device has limited processing power and memory (e.g.: 8 bit micro-controller,
32 KB memory) and where you want to limit power consumption.
MQTT is now
an OASIS standard (MQTT 3.1.1); See:
This is the
definition that you find in OASIS site:
“Providing a lightweight
publish/subscribe reliable messaging transport protocol suitable for
communication in M2M/IoT contexts where a small code footprint is required
and/or network bandwidth is at a premium.”
The
protocol overhead is minimal (message header can be as short as 2 bytes).
It is based on the Publish/Subscribe Design
Pattern.
Communication with MQTT requires a MQTT Broker:
the client publish a message to the broker, on a client-defined topic. On the
other side, several applications can subscribe to this topic, and receive messages.
Each application can act both as publisher and subscriber.
The same message can be consumed by more than
one application (this is an useful feature, you can easily add more processing
logic simply adding more subscribers to the same topic).
MQTT is based on TCP (this can be seen as a
limitation[1])
but adds to TCP some reliability features.
A client must be connected before sending a
message to the broker. In addition, there is a continuous exchange of ping and
acknowledge messages between the client and the broker, to ensure that the
broker knows if a client is still connected.
You can
specify a Quality of Service (QoS):
· QoS = 0 (best effort, no guaranteed
delivery);
· QoS = 1 (a message is received at
least once);
· QoS = 2 (a message is received once
and only once);
Another important feature is that the
communication can be made secure. You can protect the connection with
username/password or, more, you can encrypt the communication with MQTT over
TLS, ensuring confidentiality and integrity.
An OpenSource MQTT broker.
A widely
used MQTT OpenSource broker is Mosquitto. See:
Mosquitto
is a very light broker, written in C, now an Eclipse project.
It can be
easily installed on Linux, Mac OS and other OS.
You will
find it already installed and running on Intel Edison board.
With
Mosquitto, you also get two utilities useful to test the MQTT broker:
· mosquitto_pub, that can be used to
publish messages;
· mosquito_sub, that can be used to
subscribe to topics and receive messages.
In our
tests we will use Mosquitto installed on MacBook (OSX) and on a Raspberry PI
2, that act as an IoT gateway.
Some initial tests with Mosquitto.
You can start Mosquitto directly from the
command-line. There is a configuration file, mosquitto.conf, where you can set
many configuration parameters (for example the port the broker is listening on).
I have
created on my MacBook a script that starts Mosquitto:
vi start_mosquitto.sh
/usr/local/sbin/mosquitto -c /usr/local/etc/mosquitto/mosquitto.conf –v
On the
console you see:
1459525061: mosquitto version 1.4.2 (build date 2015-05-08
13:55:22-0700) starting
1459525061: Config loaded from /usr/local/etc/mosquitto/mosquitto.conf.
1459525061: Opening ipv4 listen socket on port 1883.
1459525061: Opening ipv6 listen socket on
port 1883.
(1883 is
the default port for MQTT).
To test that the broker configuration is
working correctly you can use mosquito_sub and mosquito_pub.
With mosquitto_sub you can register a subscriber
on the topic “temp” (you can use whatever string you want).
./mosquitto_sub -h localhost -t temp
(you here
specify that the broker is on localhost, but it can be on whatever machine is
connected through TCP).
After this
command you see on the Mosquitto console:
New client connected from ::1 as mosqsub/609-MacBook-Pro (c1, k60).
1459525180: Sending CONNACK to mosqsub/609-MacBook-Pro (0, 0)
1459525180: Received SUBSCRIBE from mosqsub/609-MacBook-Pro
1459525180: temp (QoS 0)
1459525180: mosqsub/609-MacBook-Pro 0 temp
1459525180: Sending SUBACK to mosqsub/609-MacBook-Pro
1459525240: Received PINGREQ from mosqsub/609-MacBook-Pro
1459525240: Sending PINGRESP to mosqsub/609-MacBook-Pro
Now, you can send on the same (temp) topic a
message simulating a value read from a temperature sensor:
./local/bin/mosquitto_pub -t temp -h localhost -m "36"
(m is the message. A sequence of
bytes).
And the
result on the window where you have launched the subscriber is:
./mosquitto_sub -h localhost -t temp
36
So, this way you have simulated a client that
publish a message on a topic, and a subscriber that receives this message.
From this example, you can understand that you
can test integration through MQTT protocol, using the utilities mosquitto_pub
and mosquitto_sub.
For example: you can create a NodeJS
application, running on Intel Edison, that reads values from a temperature
sensor attached and send the values to a MQTT broker on a Raspberry PI,
connected to the same WI-FI network. Then, you can simulate an application
subscribing to the topic using mosquitto_sub, run on the RPI 2.
Why MQTT (How many clients)?
In my
honest opinion, there are several reasons for using MQTT in IoT space:
1. If you want to manage readings from
sensors, you’re in the original use-case for MQTT (Telemetry);
2. The protocol is lightweight;
3. It is a reliable protocol; You can therefore
guarantee the delivery of messages;
4. You have client libraries available for
many languages: C, Java; Python, JavaScript (NodeJS);
NodeJS and MQTT.
There is a good client library for MQTT written
in JavaScript, available for the NodeJS platform: MQTT.js.
And here
you see an example of a NodeJS program, tested on Intel Edison, that:
1. Connect to a MQTT broker (on a RPI
2);
2. Simulate a reading from a sensor,
periodically;
3. Send a message to the broker on a
topic; The message is a JSON formatted message with the ID of the sensor and
the value of the temperature;
var TOPIC_NAME = 'temp';
var SENSOR_ID = 'SN1';
var BROKER_URL = 'mqtt://thethingbox';
var SLEEP_TIME = 30000; // 30 seconds
var mqtt = require('mqtt');
var mqtt_client =
mqtt.connect(BROKER_URL, {'keepalive' : 60});
mqtt_client.on('close', handle_mqtt_close);
mqtt_client.on('connect', handle_mqtt_connect);
mqtt_client.on('reconnect', handle_mqtt_reconnect);
mqtt_client.on('error', handle_mqtt_err);
mqtt_client.on('message', handle_messsage);
var msg = {};
var count = 0;
function handle_mqtt_connect()
{
console.log("MQTT
Connect...");
mqtt_client.subscribe('control/sn1', handle_mqtt_subscribe);
}
function handle_mqtt_subscribe(err, granted)
{
console.log("MQTT
Subscribe...");
if (err)
{
console.log(err);
}
}
function handle_mqtt_reconnect(err)
{
console.log("MQTT
Reconnect...");
if (err)
{
console.log(err);
}
mqtt_client = mqtt.connect(BROKER_URL, {'keepalive' :
60});
}
function handle_mqtt_err(err)
{
console.log("MQTT
Error...");
if (err)
{
console.log(err);
}
}
function handle_mqtt_close()
{
console.log("MQTT
Close...");
}
function after_publish()
{
// for now nothing...
}
function handle_messsage(topic, message, packet)
{
console.log('Message
received!');
console.log('msg = ' +
message.toString());
}
//
// this function is called periodically, simulate reading and send the msg
//
function readSensors()
{
count = count + 1;
console.log('***********************');
console.log("Iteration n.
%d", count);
// now use sensors module (sensors.js)
var rounded_temp = 99;
// it is simple to build the msg
object
// build the object message
// that will be sent as a JSON
message
msg.id = SENSOR_ID;
msg.temp =
rounded_temp.toString();
// send with qos = 2
if (rounded_temp)
mqtt_client.publish(TOPIC_NAME, JSON.stringify(msg), {'qos' : 2},
after_publish);
//call the indicated function
after SLEEP_TIME (in msec)
setTimeout(readSensors,
SLEEP_TIME);
}
readSensors();
No comments:
Post a Comment