ALL POSTS BY

Blog

MQTT Tutorial

Seeing your data in the dashboard is nice, but sometimes you need something different. If you have worked on other tutorials or developed with the cloud you probably noticed that we mainly use the MQTT protocol to stream live data to and from the cloud.

 

In this post we want to introduce you to some techniques and tools for working with our cloud and your device. As an example we use this code from our Photon Tutorial, where we explain how to connect a Photon to the cloud.

 

MQTT background

MQTT (Message Queue Telemetry Transport) is a lightweight connectivity and messaging protocol mostly used for IoT applications on top of the TCP/IP protocol. It uses publish and subscribe methods and is designed for low bandwidth, unreliable networks and battery longevity. MQTT is secure due to its parsing of a name and password. In addition, SSL or other encryption methods may be added. A broker is used to distribute the messages. In your home environment, for example, several sensors send data to our cloud via MQTT. There the broker distributes the data back to your applications and to the dashboard.

 

For further information check out:

  1. http://thejackalofjavascript.com/getting-started-mqtt/
  2. http://mqtt.org
  3. http://pubsubclient.knolleary.net/api.html

MQTT in our cloud

We maintain a MQTT Websocket client, free to use at http://mqtt-client.relayr.io/. Here you can see your incoming or outgoing raw data. To work with relayr's MQTT websocket you need your Client_id, Password as well as the topic:

 

#define DEVICE_ID "your_device_id"
#define MQTT_USER "your_device_id"
#define MQTT_PASSWORD "your_password"
#define MQTT_SERVER "mqtt.relayr.io"
#define MQTT_CLIENTID "your_client_id" //The  "clientId" given with the credentials

 

Now we are able to stream up to 128 bytes in a 200 ms frequency. If your JSON object is above this value your Photon will crash. Our solution was to keep the "meanings" short, but then you cannot see the data in the Dashboard - only via the MQTT broker/Websocket. Another option is to publish twice. But then you have to double check when you retrieve the data.

 

Seeing your raw data

The publish method is responsible for sending the data:

 void publish() {
  //create our json payload as {"meaning":"moisture","value":sensorvalue}
  StaticJsonBuffer<100> pubJsonBuffer;
  JsonObject& pubJson = pubJsonBuffer.createObject();
  //define a meaning for what we're sending
  pubJson["meaning"] = "moisture";
  //set our value key to the sensor's reading
  pubJson["value"] = analogRead(sensorPin);
  //copy our json object as a char array and publish it via mqtt
  char message_buff[100];
  pubJson.printTo(message_buff, sizeof(message_buff));
  client.publish("/v1/"DEVICE_ID"/data", message_buff);
  Serial.println("Publishing " + String(message_buff));
}


Once received, your data is transformed to fit our JSON format which can be seen streaming in the Logs. To see the raw data incoming you need to access http://mqtt-client.relayr.io/, our MQTT broker/Websocket. On the page in section:

 

  1. In "Username" type in your Client_id
  2. In "Password" type in your MQTT password
  3. Under subscription: add a new topic which is always /v1/client_id/# and subscribe
  4. If you click connect you should see you incoming data: {"meaning":"moisture","value":123}

Be sure to try it. And also change the JSON keys and values in the example to see the difference in what the cloud accepts and what is possible with MQTT.

 

Sending a command

MQTT also allows a two way data stream, so if you defined some command to your device you are able to send those commands via our cloud to your device. To send a command:

 

  1. Follow steps 1- 2 from above
  2. to publish messages: add the topic:/v1/client_id/cmd
  3. add a message in a defined format.
  4. click publish

It is important to mention that your command must be in a special format. If not otherwise defined the program uses the common JSON format. In the tutorial we posted a code snippet that showed how a Photon can be connected to the cloud. The snippet contains a method "callback" and "handle payload". Both are responsible for data received via MQTT. The message is transformed to a JSON, that's why we also have to send our command as a JSON to the device. The code says:

 

    //get value of the key "command"
  const char* command = json["command"];
  Serial.println("parsed command: " + String(command));
  if (String(command).equals("color"))
  {
    const char* color = json["value"];
    Serial.println("parsed color: " + String(color))
    String s(color);
    if (s.equals("red"))
      RGB.color(255, 0, 0);
    else if (s.equals("blue"))
      RGB.color(0, 0, 255);
    else if (s.equals("green"))
      RGB.color(0, 255, 0);


Then your command must look like: {"command":"color","value":"red"} .Upon hitting the publish button the LED color should switch from standard blue to red.

 

Try it out and have fun prototyping!