MQTT
warning
The document is a continuation of the previous document, if you have landed directly on this page then, Please read from page Get started.
What is MQTT?
MQTT is a protocol used to send and receive messages between 2 or more IoT devices.
Overview of how devices communicate using MQTT
- Device sending the message is called as Publisher.
- Device receiving the message is called as Subscriber
- Topic is the channel through which devices send and receive messages.
- MQTT Broker is a server that receives messages from the Publisher and routes the messages to the Subscriber.
List of MQTT features implemented in Shunya stack
With Shunya stack you can make IoT device to act as a
- Publisher. (Send messages to devices)
- Subscriber. (Receive messages from devices)
Using MQTT Shunya stack
Requirements to use MQTT Shunya stack
- Shunya OS installed (supported Arm devices) or Shunya OS docker container (X86 based windows/linux devices)
- MQTT broker installed on cloud and MQTT broker URL.
- MQTT broker authentication settings. (optional)
Steps to use MQTT Shunya stack
- Set MQTT broker settings in Shunya.
- Implementation as a Publisher
- Implementation as a Subscriber
note
Run the steps given below inside Shunya OS installed (supported Arm devices) or Shunya OS docker container (X86 based windows/linux devices) terminals.
Step 1: Set MQTT broker settings in Shunya.
Set MQTT Broker details, by editing the config file /etc/shunya/config.json
inside Shunya OS.
A simple configuration should contain these parameters.
Config | Description |
---|---|
mqttBrokerUrl | MQTT broker url |
mqttClientId | Unique Identification of the device (user can put any string that is convenient) |
mqttUsername | Username for MQTT broker authentication. (optional) |
mqttPassword | Password for MQTT broker authentication. (optional) |
note
Shunya stack will warn you if you are not using mqttUsername and mqttPassword configuration.
Example configuration:
Writing the below json in /etc/shunya/config.json
file, will tell the Shunya stack to connect to MQTT broker at url test.mosquitto.org:1883.
"mqttSettings": {
"mqttBrokerUrl": "test.mosquitto.org:1883",
"mqttClientId": "shunya pi3",
}
Step 2: Implementation as a Publisher
Let's try to implement Publisher using Shunya stack
Steps are :
Start with an ready to use template for sending messages via MQTT
git clone https://gitlab.iotiot.in/repo-public/examples.git
cd examples/simple-examples/send-messages-mqttOpen the
send-messages-mqtt.c
in an text editor and modify as per your use case.For our example, we need to first get the temperature data, add the code in your
main()
functionfloat temperature = 76.98; /* For now lets assume that the temperature is 76.89 Celsius*/
Publishing temperature data to topic, modify the code
float temperature = 76.98; /* For now lets assume that the temperature is 76.89 Celsius*/
/* Create a mqtt object */
mqttObj mqttBroker = newMqtt("mqttSettings"); /* Argument = JSON Title, Load settings from JSON file */
/* Connect to broker */
mqttConnect(&mqttBroker) ;
/* Publish message "76.98 C" to topic "temp" via MQTT*/
mqttPublish(&mqttBroker, "temp", "%.2f C", temperature);
mqttDisconnect(&mqttBroker); /* Disconnect MQTT */Once you are done editing, save and compile the code , by running
mkdir build && cd build
cmake ../
makeRun the code
sudo ./send-messages-mqtt
More examples to Publish messages via MQTT in shunya stack
- Send JSON string
- Send multiple variables
For sending JSON, change code in step 4. with the example given below.
char json[1024] = "{ "temp": 78.9, "sensor_name": "BME280" }";
/* Publish a json to topic "temp" via MQTT*/
mqttPublish(&mqttBroker, "temp", "%s", json);For sending multiple variables, change code in step 4. with the example given below.
float temperature = 76.89;
int humidity = 98;
/* Publish a string to topic "temp" via MQTT*/
mqttPublish(&mqttBroker, "temp", "temperature: %f, humidity: %d", temperature, humidity);
Step 3: Implementation as a Subscriber
Let's try to implement Subscriber using Shunya stack
Steps are :
Start with an ready to use template
git clone https://gitlab.iotiot.in/repo-public/examples.git
cd examples/simple-examples/receive-messages-mqttOpen the
receive-messages-mqtt.c
in an text editor and modify as per your use case.For our example, we need to first edit the code to store the received message to at file.
Add the code to print to a file in
processMessages()
function, because/* This function will get called everytime the Subscribed Topic receives a message */
void processMessages (int topicLen, char *topic, int msgLen, char *msg)
{
/* For now lets print the message.*/
printf("Received message\n\tFrom Topic: %s,\n\t Message: %s", topic, msg);
/* Print the message to a file */
FILE *file;
file = fopen("database", "r");
if (file != NULL) {
fprintf(file, "%s\n", msg);
}
fclose(file);
}Now lets subscribe to the topic "temp", so we can start receiving messages
/* Create a mqtt object */
mqttObj mqttBroker = newMqtt("mqttSettings"); /* Argument = JSON Title, Load settings from JSON file */
/* Connect to broker */
mqttConnect(&mqttBroker) ;
/* Send all the messages received to our processing function */
mqttSetSubCallback(&mqttBroker, processMessages);
/* Receive messages from topic "temp" via MQTT*/
mqttSubscribe(&mqttBroker, "temp");
mqttDisconnect(&mqttBroker); /* Disconnect MQTT */Once you are done editing, save and compile the code , by running
mkdir build && cd build
cmake ../
makeRun the code
sudo ./receive-messages-mqtt
More examples on receiving messages via MQTT shunya stack
- Receive JSON string
For sending multiple variables, change code in step 4. with the example given below.
void processMessages (int topicLen, char *topic, int msgLen, char *msg)
{
/* Parse JSON message using rapidjson */
rapidjson::Document jsonMsg;
jsonMsg.Parse(msg);
}
Understand this component with an example (ready to use code)
Let's take an example use case: Say we need to
- Subscribe to the topic "devices/instructions" and Turn on LED when we receive the message "LED".
- Publish "LED" to the topic "devices/instructions".
- Here we will be using both Publish and Subscribe features of MQTT.
- Example for both Publisher and subscriber at once
Steps are :
Start with an ready to use template for MQTT
git clone https://gitlab.iotiot.in/repo-public/examples.git
cd examples/full-examples/mqttOpen the
mqtt-example.c
in an text editor and modify as per your use case.For our example, we need to first load the MQTT broker settings, add the highlighted code in your
main()
function/* Create a mqtt object */
mqttObj mqttBroker = newMqtt("mqtt"); /* Argument = JSON Title */Connect to the MQTT broker, add the highlighted code in your
main()
function/* Connect to broker */
mqttConnect(&mqttBroker);Register the message processing function, add the highlighted code in your
main()
function/* Send all the messages received to our processing function */
mqttSetSubCallback(&mqttBroker, processMessages);Process all the received messages and take action when message LED is received at topic "devices/instructions" ,
/* This function will get called everytime the Subscribed Topic receives a message */
void processMessages (int topicLen, char *topic, int msgLen, char *msg)
{
/* Check if the message recevied is from topic "devices/instructions" */
if (strncmp(topic, "devices/instructions", strlen("devices/instructions")) == 0) {
/* Check if the message received is LED */
if (strncmp(msg, "LED", strlen("LED")) == 0) {
/* Turn ON LED */
setLed(40, ON); /* Turn on LED */
} else {
setLed(40, OFF); /* Turn off LED */
}
} else {
setLed(40, OFF); /* Turn off LED */
}
}Subscribe to the topic "devices/instructions" ,
/* Receive messages from topic "devices/instructions" via MQTT*/
mqttSubscribe(&mqttBroker, "devices/instructions");Publish "LED" to the topic "devices/instructions" ,
/* Send a message to topic "devices/instructions" via MQTT*/
mqttPublish(&mqttBroker, "devices/instructions", "LED");Once all the operations are done for MQTT, disconnect from the broker at the end,
mqttDisconnect(&mqttBroker); /* Disconnect from MQTT broker */
Once you are done editing, save and compile the code , by running
mkdir build && cd build
cmake ../
makeRun the code
sudo ./mqtt-example.c