This post is meant to be a quick start guide to pub/sub with MQTT on the m2m.io platform. The example is in Java utilizing the Paho Java client.

Account Setup

The first step in connecting to the m2m.io MQTT broker is to setup an account on the platform. An account can be created by visiting the m2m.io Developer Portal at http://app.m2m.io and clicking on the “Sign Up” link.

image

After completing the registration page a confirmation link will be sent to the email address provided. Click on the link to activate your account.

A new account starts with 5 licenses. A license allows one unique device or application to connect and publish data. Uniqueness is determined by MQTT client ID. More on MQTT client IDs later in this post.

Paho Java MQTT Client

This example depends on the Paho Java MQTT client library. This code can be found on GitHub: https://github.com/eclipse/paho.mqtt.java.

Read More


A few days ago we noticed some API calls were taking longer than we expected.  We were looking for a quick way to grab some analytics data to see at what point the calls were slowing down.  But how to store history and visualize where the problems exist?  How about monitoring API response times and posting them via MQTT to the platform itself?

Leveraging an existing Play! app we were currently using for system monitoring I was able to plug in a series of API calls run by a cron-type job scheduler.  In this case the API metrics module runs every 10 minutes.  See below for some Java pseudo code of this method.

// metrics message map
Map<String,Long> metrics = new Map<String, Long>();

// -- account call -------------------------------------- long initialStartTime = System.currentTimeMillis(); long startTime = initialStartTime; // << account API call here >> long stopTime = System.currentTimeMillis(); Logger.info("Account time:" + (stopTime - startTime)); metrics.put("api_account_call", stopTime - startTime); // -- group call ---------------------------------------- startTime = System.currentTimeMillis(); // << group API call here >> stopTime = System.currentTimeMillis(); Logger.info("Group time:" + (stopTime - startTime)); metrics.put("api_group_call", stopTime - startTime); // -- multipresent calls -------------------------------- for (String s : group.getThings()) { startTime = System.currentTimeMillis(); // << group API call here >> stopTime = System.currentTimeMillis(); Logger.info("Thing " + thingCount + "call time:" + (stopTime - startTime)); metrics.put("api_thing_" + thingCount + "_call", stopTime - startTime); } Logger.info("Total time:" + (stopTime - initialStartTime)); metrics.put("api_total", stopTime - initialStartTime); NotificationManager.pubResponseTimeMetric(metrics);

As you can see I gathered up the response times in a Map called metrics. This map will be the payload of the MQTT message sent to the platform.  Let’s see what pubResponseTimeMetric does.

public static void pubResponseTimeMetric(Map<String, Long> metricMap) {
  String payload = new Gson().toJson(metricMap);
  Logger.info("Publishing a metrics message: " + payload);

  Singleton
    .getInstance()
    .getOpsMqttClient()
    .publishNoWait(
      ConfigFactory.load().getString(
      "api.metrics_topic"), payload, 0, false);
}

This method makes use of a Singleton MQTT client that is constantly connected.  Behind the scenes this MQTT client is an instance of the Eclipse Paho Java MQTT client.  Here is an example MQTT message containing the API response times:

{
  "api_thing_1_call": "174",
  "api_group_call": "84",
  "api_total": "463",
  "api_thing_2_call": "96",
  "api_account_call": "105"
}

With this setup we get a message like the one above published every 10 minutes.

But how to visualize and make use of this data?  It turns out we’ve made some good progress filling out the functionality in our developer portal.

After signing in, I navigate to the Past tab.  This provides a visual way to pull up any past data published to our MQTT broker and platform.

image

By entering my stuff and thing (from the MQTT topic space), the _ wildcard for whatevers, 100 for the quantity and an appropriate timeframe I’m able to pull a list of 100 messages.  Cool enough but check out the next step.  By simply clicking on one of the values a chart is built visually showing the response times.

image

How cool is that?  With zero work on my part (after publishing the metric messages) I have a graph showing my response times on 10 minute intervals.

That huge spike at the right?  That’s when we were doing a maintenance activity and all API calls were proxied.  It just jumps right out.


A networked Arduino, a couple wires, copy/paste some code and in less than 10 minutes you’ll see your sensor values graphed in real-time and be able to see all past values you’ve ever published.

This example contains two “modes” of operation:  Provisioning & Normal modes.  When the device is started in provisioning mode it publishes a message to the m2m.io portal which associates the device to a user’s account.  This allows the m2m.io developer portal to recognize data published from a specific device and display the data in a meaningful way (graphs, maps, gauges and other widgets).  Provisioning only needs to be done once and a device can be entered again if the need arises to provision the device to a different user.

Normal mode means the device is in a continuous loop, reading data values from a sensor and publishing them to the m2m.io platform.  After a device is provisioned it can be started, powered down and restarted without provisioning.  This is the “normal” state of the device doing its job as a temperature monitor, light sensor or whatever other application it is designed to perform.

Prerequisites

  • Arduino (Uno in this example)
  • Ethernet/Wireless Shield & Library
  • MQTT Library (PubSubClient) - see here for an explanation on installing Arduino libraries
  • A free account on the m2m.io platform developer portal (more detail below)

Circuit

Below is a diagram and picture of the circuit used for this example.

image

Arduino with Ethernet Shield, potentiometer, jumper wire

image

Circuit Diagram - note the circuit diagram assumes an Ethernet / WiFi shield attached

The circuit contains two notable features.  First, a jumper wire (the white wire above, attached to analog pin 0).  This allows switching between device modes without a change of software.  With pin 0 jumpered to ground, the device will start in “provisioning mode”.  With the input floating or tied to +5V, the device is in “normal mode”.

The second feature is the use of a potentiometer as a sensor.  This allows for easy manipulation of the “sensor” value to see changes when initially setting up the circuit.  This portion of the circuit could easily be swapped for many of the sensor examples found online.

Account Registration
The m2m.io developer portal is located here.  Account registration is accomplished via the “Sign Up” link at the bottom of the page.
After signing in the Account page is shown:
image

Note the Domain field as this is used when configuring the software below.  Also note the Devices tab.  This is where your list of devices associated with the current account can be found.

Software

The Arduino sketch for this example can be downloaded from GitHub.  Note that this sketch relies upon the Ethernet Shield and library installed.  A future blog post will include support for the WiFi shield and corresponding library.

Once downloaded, the sketch needs to be updated with your credentials and domain from the m2m.io portal.

image

The username is the username (email) you used to create an account on the developer portal.

The password is the password for your developer portal account.  This value is not the clear text password, rather the MD5 hash of the password.  An MD5 string can be generated through command line tools such as md5 on Mac OS X and md5sum on Linux.  Online generators are also available by searching “md5 generator” with an online search engine.  To validate your chosen tool, the correct MD5 hash of “helloworld” is MD5 (“helloworld”) = fc5e038d38a57032085441e7fe7010b0.

Note the Domain is the 32 character MD5 hash found on the Account page:

image

The Device ID should be chosen to be a unique value between all of your devices.  Serial numbers, MAC addresses or any other unique value can be used.

Operation

Next the device will be provisioned to your m2m.io account.  Login to the portal and click on the Devices tab.  You should see a device list which may be blank if you have not yet provisioned any devices.

image

Click on “Register a device” to start listening for a provisioning message from the Arduino device.

With the jumper wire connected between Analog 0 and Ground, validate the sketch and download it into your Arduino.  You should see a successfully found device message after the Arduino connects to your network and publishes a registration message.  Common errors at this point are not connecting the ethernet cable to the ethernet shield and not having the jumper wire connected to ground.

The serial monitor can be used to help debug device mode (provisioning vs normal).

At this point the device has been successfully provisioned to your account and shows up in your device list.  The Arduino can now be started in normal mode and sensor values will be published to the m2m.io platform.  Simply disconnect the jumper wire from ground and press the reset button on the Arduino board.  The device will connect and publish sensor readings.  The potentiometer can be turned to vary the “sensor” values to see changes in real-time.

To see real-time values click the Go to button next to the device.  This displays an embedded MQTT client showing values published by the device:

image

Note that whenever the board starts up without the jumper attached to ground it will publish sensor values to the platform.  If needed, the device can be reprovisioned at any time by inserting the jumper wire again and pressing the reset button on the Arduino.

Platform Features

A key feature of the m2m.io platform is the ability to recall previously posted values through a REST API.  Every message posted to the platform is stored in our backend data store so an application can pull the complete history of every device.  The developer portal provides several intuitive ways to visualize past / present stored values from the platform.

Present

The screenshot below shows a data tree showing the most recently published values:

image

And the same values as JSON.  The JSON view gives an example of the data returned when making an API call to the platform programmatically.

image

Notice that because the user is logged into the portal that domain does not need to be entered.  Arduino is the “stuff” parameter and Device1 is the “thing”.  In this way multiple Arduinos could be connected as Device1, Device2, and so on and this call could be used to query the most recent value from those devices.

Past

The screenshot below shows a graphical timeline of published sensor values.  The query is built using Arduino as the “stuff”, Device1 as the “thing” and t as the “whatever”.  In this way multiple values could have been published (e.g. temp, altitude, light) and each value could be queried.

image

Again the JSON view shows what would be returned from the API:

image

For more information on calling the API programmatically, see the blog post here.


This post walks through the generic C client for development on embedded devices.  While this library does required porting to your particular OS/TCP stack, we’ve tried to make it as easy as possible.

The example implements two basic functions:  provisioning a device and normal sensor publishing.

  • Provisioning:  This associates a device to a particular m2m.io user account.  This allows easy visualization of data sent by the device through various widgets on the portal.  This is an optional step and is done once per device.
  • Sensor publishing:  A common use of the m2m.io platform is publishing sensor data from various devices.  For example, a temperature monitoring device may wake up once every 15 minutes and publish the current temperature.  This would be the device’s “normal” operation.  The example code includes a dummy call to read a sensor value to illustrate this.

The m2m.io client libraries repo can be found on GitHub here.  In this repo you will find a folder named c_embedded.

image

In the base directory there is a Makefile, source subdirectories and a README file.  The include and src directories contain the libemqtt library.  This is a lightweight MQTT client written in C and targeted for use in embedded devices.  Inside the client directory are the application files which make use of the library.  The client/example.c file is the file we’ll look at in this post.

Inside this file you’ll find four methods which need to be ported for use with your particular platform’s TCP/IP stack:

  • init_socket
  • close_socket
  • send_packet
  • read_packet

If you are currently doing communication across a raw socket connection this porting should be straight forward.

For the remainder of the example we’ll be building and running in a Linux environment using the gcc toolchain.

Continuing the example from this point assumes you have a developer account on the m2m.io portal.  Instructions on how to sign up can be found at the bottom of the portal page.

At the top of example.c are a few constant values that are required to connect to the m2m.io platform.  These values are constants in this example but could easily be programmed into non-volatile storage in an embedded device.

image

The values for username and domain can be found on the Account tab of the m2m.io portal:

image

Note on the password field:  This is the password you use to sign into the developer portal.  This value is not the clear text password, rather the MD5 hash of the password.  An MD5 string can be generated through command line tools such as md5 on Mac OS X and md5sum on Linux.  Online generators are also available by searching “md5 generator” with an online search engine.  To validate your chosen tool, the correct MD5 hash of “helloworld” is MD5 (“helloworld”) = fc5e038d38a57032085441e7fe7010b0.

Now that the user information has been added the example can be built and run.

image

The example can then be run.  Running the example with the -p flag causes a provisioning message to be sent before sensor values are published.  Running without -p jumps straight to publishing sensor values.

Sensor Values

image

The screen on the right of the above screenshot is an MQTT client subscribed to the same topic on which the example app is publishing.  The same messages can be seen in the client as were published by the example running on the left.

The MQTT client used in this example is the MQTT web client developed by us at 2lemetry.  If using this client be sure to click on the Options tab at the top to enter your m2m.io credential when connecting to the MQTT broker.

image

Sensor values are published on the topic <domain>/<device type>/<device ID>.  In my specific case this is the topic io.m2m/things/device01 so this is the topic to which I subscribed in the MQTT client.

Provisioning

A provisioning message can be sent to associate the device to a user’s account.  To see a list of current devices click on the Devices tab when signed into the portal:

image

To provision a device to your account, first click on the Register a device button.  The portal will start listening for the provisioning message.  While the portal is listening, run the example with the -p flag.  The portal will recognize your device.

image

At this point you can navigate to your device.

image

I ran this example on a general purpose PC to easily show the flow of provisioning a device and publishing sensor data.  This also makes for a nice runnable package you can play with “out of the box”.  However, there are obvious changes that will need to be made to the example to adapt it to your embedded application.

First, as mentioned above, each device/OS has its own TCP/IP library.  The socket specific functions will need to be ported to your chosen library.

Secondly, there are pieces of the example that may not make sense in an embedded environment:

  • The device ID will most likely not be a constant in your code.  It will change for each device - ideally it will be a uniquely identifying string such as serial number or MAC address.  This will most likely be put into EEPROM or other non-volatile storage when the device is manufactured.
  • The provisioning mode will not be triggered by running with a -p flag.  This could be done by having the device recognize it is not currently provisioned (by a flag stored in EEPROM) and send a provisioning message on startup if not provisioned.  The device could also be provisioned at the time it is built.  Another simple option would be exposing a push-button or other user interaction to provision.  These are all application specific depending on how your device is used.
  • The sensor loop will read actual hardware values.

The m2m.io portal is available now; sign-up is free! We have created a simple user interface for monitoring all of your m2m.io data. It uses the same API calls outlined in our REST API page at m2m.io. Some of these are also outlined in other posts of this blog.

Upon creating an account, you will get 5 free licenses. Each license allows one client to connect. From here you can make the various API calls such as account, license, domain, stuff, past and present. In addition, we allow you to sign-up using social media accounts including Facebook, Twitter, Google and GitHub. Upon sign-up, the site will ask you which email address to connect your ID to in case the one you want to use differs from the email address that is connected to your social media account.

Let’s review each call and explain what type of data will be returned. The account call is used to create an account and retrieve your data. The account call

GET /1/account

will return data about your account, including your registered email address, your domain, your password, aclid and key. You can select tabs to view your data in table format

or JSON format.

The license call

GET /1/license/{domain}

will show the license info including aclid, account id, token, activation date, and key. The site returns this data for each license associated with your account and again gives you tab-selectable views of your data.

The domain call

GET /1/domain/{domain}

returns information about your domain. Including the name, domain, key, license limit (again, you get 5 free), and your stuff.

There are three stuff calls you make using the m2m.io portal. The first one is

GET /1/stuff/{domain}

which returns data about all of your things associated with your domain. You can sort and search this list.

The second stuff call is the

GET /1/stuff/domain/{stuff}

call which allows you to search for specific stuff.

Last, the

GET /1/stuff/domain/{stuff}/{whatever}

which returns information about your stuff based on domain, stuff and comma-separated whatevers.

The past call is in this format

GET /1/past/{domain}/{stuff}/{thing}?whatevers={some whatever}&limit={num}&end={epoch}&start={epoch}

and allows you to make a history call, returning time-descending historical data from this thing. You can limit the number of returns along with searching a specific time frame.

There are two present calls. First

GET /1/present/domain/{stuff}/{thing}

returns the last known data feed sent by this thing. The other present call is used to retrieve data about multiple things.

GET /1/multipresent/{domain}/{stuff}/{thing}?whatevers={comma-separated list}

so it returns the last known data feed sent by this thing for each whatever you provide.

You can use our mqtt.io site or Mac client to publish data, or retrieve data from other monitoring equipment or sensors.



This post shows a quick example of using MQTT and the m2m.io platform with an Arduino device.  I walk through the platform from end to end starting with setting up the Arduino to capture sensor data and ending with a super simple Play! app which shows the past sensor readings by consuming the data presented by the m2m.io platform API.

I hope you find it useful.

Overview

Connect.  Send.  Store.  Use.

This example was crafted to illustrate the main concepts of the m2m.io platform.

Connect:  The Arduino will connect via MQTT to the m2m broker.

Send:  Sensor data is sent to the broker/platform and command data is sent to the Arduino.

Store:  If formatted correctly, any MQTT traffic going to the broker will be stored for retrieval in the future.

Use:  The platform provides a simple, RESTful API for client applications to make use of their stored data.

This simple sensor application gathers light sensor data which is published to the broker.  Commands can be sent via MQTT to the sensor.

Arduino - Hardware

The circuits I constructed allow the Arduino device to read light levels using an analog input and (optionally) control an LED based on a set light level.  The optional LED portion of the circuit makes the Arduino a very simple control system which controls an output based on input values it senses.

I started with the SparkFun Arduino Inventor’s Kit which includes the components necessary to create a light sensing circuit.  This could easily be done with any Arduino device capable of hosting the Arduino Ethernet Shield and a couple standard components.

Parts List

Wiring Diagram
Photo of Completed Circuit

Arduino - Software / MQTT

There are four main tasks the Arduino software needs to take care of for this example:

  • Gather light sensor readings periodically
  • Publish sensor readings via MQTT
  • Listen for commands via MQTT
  • Control the LED based on a setpoint

An MQTT client is created in the setup function.

Every loop, the following happens:

  1. The MQTT client connects (if it is not already connected).
  2. Based on the “sensing mode” the application decides how to drive the LED.  It could be OFF, ON or SENSE.  In the SENSE case a light reading is taken and the LED is driven according to a hardcoded setpoint.
  3. In the SENSE case, if 5 seconds have elapsed since the last reading a new reading is published via MQTT.

When connecting an MQTT client a callback function is specified to handle any incoming MQTT messages on the subscribed topic(s).  In this function we check for commands in the proper JSON format and adjust our mode if the command specifies a new mode.

An interesting update to this app would be to handle receiving commands to change hardcoded values such as time we wait between publishing light readings or the “light”/”dark” setpoint.

Below is the Arduino code.  Note: This requires both the Ethernet library and MQTT Client Library to be installed in your Arduino library folder.  See an example here on how to install Arduino libraries.  (it’s easy!)

#include <SPI.h>
#include <PubSubClient.h>
#include <Ethernet.h>

/*
 * LightSensorMqttDemo
 *
 * A simple m2m.io platform demo for Arduino.
 */

#define MQTT_SERVER "q.m2m.io"

// MAC Address of Arduino Ethernet Sheild (on sticker on shield)
byte MAC_ADDRESS[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x31, 0xB8 };
PubSubClient client;

// Pin 9 is the LED output pin
int ledPin = 9;
// Analog 0 is the input pin
int lightPinIn = 0;

// defines and variable for sensor/control mode
#define MODE_OFF    0  // not sensing light, LED off
#define MODE_ON     1  // not sensing light, LED on
#define MODE_SENSE  2  // sensing light, LED controlled by software
int senseMode = 0;

unsigned long time;

char message_buff[100];

void setup()
{
  // initialize the digital pin as an output.
  pinMode(ledPin, OUTPUT);
  
  // init serial link for debugging
  Serial.begin(9600);
  
  if (Ethernet.begin(MAC_ADDRESS) == 0)
  {
      Serial.println("Failed to configure Ethernet using DHCP");
      return;
  }

  client = PubSubClient(MQTT_SERVER, 1883, callback);
}

void loop()
{
  if (!client.connected())
  {
      // clientID, username, MD5 encoded password
      client.connect("arduino-mqtt", "john@m2m.io", "00000000000000000000000000000");
      client.publish("io.m2m/arduino/lightsensor", "I'm alive!");
      client.subscribe("io.m2m/arduino/lightsensor");
  }
  
  switch (senseMode) {
    case MODE_OFF:
      // light should be off
      digitalWrite(ledPin, LOW);
      break;
    case MODE_ON:
      // light should be on
      digitalWrite(ledPin, HIGH);
      break;
    case MODE_SENSE:
      // light is adaptive to light sensor
      
      // read from light sensor (photocell)
      int lightRead = analogRead(lightPinIn);

      // if there is light in the room, turn off LED
      // else, if it is "dark", turn it on
      // scale of light in this circit is roughly 0 - 900
      // 500 is a "magic number" for "dark"
      if (lightRead > 500) {
        digitalWrite(ledPin, LOW);
      } else {
        digitalWrite(ledPin, HIGH);
      }
      
      // publish light reading every 5 seconds
      if (millis() > (time + 5000)) {
        time = millis();
        String pubString = "{\"report\":{\"light\": \"" + String(lightRead) + "\"}}";
        pubString.toCharArray(message_buff, pubString.length()+1);
        //Serial.println(pubString);
        client.publish("io.m2m/arduino/lightsensor", message_buff);
      }
      
      
  }
  
  // MQTT client loop processing
  client.loop();
}

// handles message arrived on subscribed topic(s)
void callback(char* topic, byte* payload, unsigned int length) {

  int i = 0;

  //Serial.println("Message arrived:  topic: " + String(topic));
  //Serial.println("Length: " + String(length,DEC));
  
  // create character buffer with ending null terminator (string)
  for(i=0; i<length; i++) {
    message_buff[i] = payload[i];
  }
  message_buff[i] = '\0';
  
  String msgString = String(message_buff);
  
  //Serial.println("Payload: " + msgString);
  
  if (msgString.equals("{\"command\":{\"lightmode\": \"OFF\"}}")) {
    senseMode = MODE_OFF;
  } else if (msgString.equals("{\"command\":{\"lightmode\": \"ON\"}}")) {
    senseMode = MODE_ON;
  } else if (msgString.equals("{\"command\":{\"lightmode\": \"SENSE\"}}")) {
    senseMode = MODE_SENSE;
  }
}

mqtt.io MQTT Client - Publish / Subscribe

To communicate with our Arduino we’ll use the websocket MQTT client at mqtt.io.

Some quick notes, the username and password are entered in the Options tab before connecting.  Signing in is required to see messages published on private namespaces.  See the help article here for more information.  The address we’ll use is the m2m MQTT broker at q.m2m.io, port 1883.

The screenshot below shows the Arduino publishing the “I’m Alive” message upon connecting.  Note that this message wasn’t sent in JSON format so it won’t be stored by the platform.

Commands can be sent to the Arduino by publishing from the web client.  Notice I publish commands in JSON format.  This causes the commands to be stored by the platform and we’ll be able to see their history if we want to pull them up.  Below is a screen shot showing publishing commands.  The commands are seen in the subscribe window as they are sent.

In the sequence sent above, the Arduino turned on the LED when receiving the “ON” command and off when receiving the “OFF” command.  Upon receiving the “SENSE” command it controlled the LED based on whether the light sensor was in the light or dark. This I was able to control by placing my hand over the photocell.

The screenshot below was captured while the Arduino was in SENSE mode.  It continously publishes light readings every 5 seconds and this data is seen live on the MQTT topic.

Platform API - Consuming Past Data with Play! Application

Now that we have brought up the device, sent it some commands and saw it publish some sensor readings let’s use the m2m.io API to see what just happened.  The API is documented in detail here.

For this example I wrote a quick Play! app in Scala.  The code below shows the LightReading model.  When the all() method is invoked, a call is generated to the past API endpoint requesting our “report:light” whatevers.  (“whatevers” = whatever you want to send)

package models

import play.api.libs.ws.WS
import play.api.libs.json.JsObject
import com.ning.http.client.Realm
import com.codahale.jerkson.Json

case class LightReading(timestamp: Long, value: Int)

object LightReading {

	def all(): List[LightReading] = {

		var returnList: List[LightReading] = List()

		val username = "john@m2m.io"
      	        val password = "password"

		val url = "http://api.m2m.io/1/past/io.m2m/arduino/lightsensor?whatevers=report:light"

		val response = WS.url(url)
      		.withAuth(username, password, Realm.AuthScheme.BASIC)
      		.get().await(10000).get


		var retJson = response.json.as[JsObject]

		retJson.fields.map { j =>
			val jsobj = j._2.as[JsObject]
			val m = Json.parse[Map[String, Int]](jsobj.toString)
			returnList = returnList :+ new LightReading(j._1.toLong, m.getOrElse("report:light", 0)) 
		}

		returnList
	}
}

After deploying the application and requesting the past page, the app returns history for both values read and commands sent.  There is a separate Command model similar to the one above to request “command:lightmode” whatevers.

Conclusion

Admittedly, this example is very simple.  But I believe it is a good illustration of how I went from bare Arduino breadboard to retrieving sensor values from a cloud-hosted API in less than a day.  Good luck with your projects!


m2m.io information and examples

The following examples show how to use the m2m.io MQtt broker and the api’s to retrieve that data.

Connecting to the broker

The first step is to acquire a username and password from http://help.m2m.io

Next using a compatible 3.1 MQtt client, configure the username and md5sum(password) for the client. You may use anything for the clientid. Every clientid will require a license for connecting to q.m2m.io. Licenses are automatically provisioned until your license limit is reached. The clientid may be prefixed with ‘<stuff>/’to automatically configure the client for this grouping. This is useful when retrieving information about your ‘thing’. See Topic Namespace for further info on this.

Topic Namespace

In order for m2m.io to properly store your data this namespace pattern must be followed.

<domain>/<stuff>/<thing>

By default the topic namespace for an m2m.io client must start with their ‘domain’. Domains are obtained during registration of a new user account. The next level of the namespace, ‘stuff’ is a logical grouping of related things. The third level of the namespace, ‘thing’ relates to the client’s unique identifier.

If you don’t follow our recommended namespace pattern messages will still be passed by the broker as long as you have rights to publish/subscribe on the given topic. Messages will not be stored if the topic space is different.

Payload

In order for m2m.io to store the payload data the client must send the data in standard json object form. Here is an multi nested object example:

{
  "report": {
    "gps": {
        "latitude": "39.702610038220882",
        "longitude": "-104.97231300920248"
        },
        "temp": {
        "celsius": "252",
        "fahrenheit": "76"
        }
    }
}

Using the m2m.io API

Use the m2m.io API to retrieve the client information and data that you have published over time.

API Url - http://api.m2m.io/1

These examples will use the curl command line tool to show how to get the date that was just published:

Get account info

curl --user user@m2m.io:xxxxxx http://apm2m.io/1/account

{
    domain = "io.m2m";
    email = "user@m2m.io";
    key = "user@m2m.io";
    ok = 1;
    password = xxxxxx;
}

Get domain info

curl --user user@m2m.io:xxxxxx http://api.m2m.io/1/domain/io.m2m

{
    active = 1;
    domain = "io.m2m";
    key = "io.m2m";
    licenselimit = 1000000;
    name = m2mIO;
    ok = 1;
    stuff =     [
        "io.mqtt",
        tests,
        test,
        things,
        examples,
        scala
    ];
}

Get stuff info

curl --user user@m2m.io:xxxxxx http://api.m2m.io/1/stuff/io.m2m

[
  {
    active = 1;
    domain = "io.m2m";
    key = "io.m2m:things:Ee6DR";
    licenseid = "uJ5ULi6YL8Flf0w:ba481581-2eb3-40af-af3e-75b86624694a";
    ok = 1;
    stuff = things;
    thing = Ee6DR;
  },
   {
    active = 1;
    domain = "io.m2m";
    key = "io.m2m:examples:publisher";
    ok = 1;
    stuff = examples;
    thing = publisher;
  }
]

To filter by ‘stuff’

curl --user user@m2m.io:xxxxxx http://api.m2m.io/1/stuff/io.m2m/examples

[
  {
    active = 1;
    domain = "io.m2m";
    key = "io.m2m:examples:publisher";
    ok = 1;
    stuff = examples;
    thing = publisher;
  }
]

Present

Shows last known data sent from client

curl --user user@m2m.io:xxxxxx http://api.m2m.io/1/present/io.m2m/examples/publisher

{
    domain = "io.m2m";
    key = "io.m2m:examples:publisher";
    "m2m_nestedkeys" =     [
        report
    ];
    "m2m_raw" = "{\n\t  \"report\": {\n    \t\"gps\": {\n      \t\t\"latitude\": \"39.702610038220882\",\n      \t\t\"longitude\": \"-104.97231300920248\"\n    \t\t},\n    \t\t\"temp\": {\n      \t\t\"celsius\": \"252\",\n      \t\t\"fahrenheit\": \"76\"\n    \t\t}\n  \t\t}\n\t}";
ok = 1;
stuff = examples;
thing = publisher;
ttl = 0;

}

MultiPresent

Shows all last known data from a client parsed

curl --user user@m2m.io:xxxxxx http://api.m2m.io/1/multipresent/io.m2m/examples/publisher

{
  "report:gps" =     {
    customFieldMap =         {
        latitude = "39.702610038220882";
        longitude = "-104.97231300920248";
    };
    domain = "io.m2m";
    key = "io.m2m:examples:publisher:report:gps";
    ok = 1;
    stuff = examples;
    thing = "publisher:report:gps";
    ttl = 0;
  };
  "report:temp" =     {
    customFieldMap =         {
        celsius = 252;
        fahrenheit = 76;
    };
    domain = "io.m2m";
    key = "io.m2m:examples:publisher:report:temp";
    ok = 1;
    stuff = examples;
    thing = "publisher:report:temp";
    ttl = 0;
  };
}

Past

Shows history of all data from a client in a time series

curl --user user@m2m.io:xxxxxx http://api.m2m.io/1/past/io.m2m/examples/publisher?whatevers=report:gps:latitude,report:gps:longitude,report:temp:celcius,report:temp:fahrenheit
{ 1340314565706000 = { "report:gps:latitude" = "39.702610038220882"; "report:gps:longitude" = "-104.97231300920248"; "report:temp:celsius" = 252; "report:temp:fahrenheit" = 76; }; 1340320480805000 = { "report:gps:latitude" = "39.702610038220882"; "report:gps:longitude" = "-104.97231300920248"; "report:temp:celsius" = 252; "report:temp:fahrenheit" = 76; }; 1340320484088000 = { "report:gps:latitude" = "39.702610038220882"; "report:gps:longitude" = "-104.97231300920248"; "report:temp:celsius" = 252; "report:temp:fahrenheit" = 76; }; 1340320484855000 = { "report:gps:latitude" = "39.702610038220882"; "report:gps:longitude" = "-104.97231300920248"; "report:temp:celsius" = 252; "report:temp:fahrenheit" = 76; }; 1340320485523000 = { "report:gps:latitude" = "39.702610038220882"; "report:gps:longitude" = "-104.97231300920248"; "report:temp:celsius" = 252; "report:temp:fahrenheit" = 76; }; 1340320486135000 = { "report:gps:latitude" = "39.702610038220882"; "report:gps:longitude" = "-104.97231300920248"; "report:temp:celsius" = 252; "report:temp:fahrenheit" = 76; }; 1340320486746000 = { "report:gps:latitude" = "39.702610038220882"; "report:gps:longitude" = "-104.97231300920248"; "report:temp:celsius" = 252; "report:temp:fahrenheit" = 76; }; }

q.m2m.io

The q.m2m.io Broker allows the ability to connect your device and application clients using MQTT; a simple publish/subscribe protocol.  For more information about MQTT please visit http://mqtt.org

The m2m.io broker allows incoming connections to q.m2m.io on port 1883.  (If you’re licensed for SSL, use port 8883).  Any client connected is sandboxed within their “domain” level topic.  Only clients with authorization are allowed to connect to the broker. 

Here are the following steps in order to connect to our MQTT Broker.

Download a compatible 3.1 mqtt client.  We recomment the Eclipse Paho clients for Java or C.  The source can be downloaded from https://github.com/eclipse/paho.mqtt.java or https://github.com/eclipse/paho.mqtt.c

 Authentication

All clients connecting to q.m2m.io require a username and password.  Please request one at http://help.m2m.io

The client’s password must be sent as the md5sum of the password string.

Licenses

Licenses are given on a ‘domain’ level.  Each domain has a limited number of licenses that are auto provisioned to clientID’s that connect.  When a new client connects to our broker the clientID is checked for a license and allocated if needed.  Random clientID’s are not recommended since it will allocate a new license for each randomly created clientID.

Subscribing and Publishing

Subscribing is based on a TOPIC string.  By default your client will have access to public/# and <domain>/#  Any clients my publish and subscribe on public/# and only authorized clients can publish on your <domain>/#

Data is stored in m2m.io if the following 3 level topic is defined.  <domain>/<stuff>/<thing>  where <domain> is your domain, <stuff> is a grouping of things and <thing> is a unique identifier for a device.  Payload data must be in JSON object format to be parsed and saved to the datastore.  Any single or nested JSON object is allowed.  All other topic patterns or payload structure would not be stored but are allowed for pub/sub.  

Payload

This is an example of a valid payload that would be stored in the m2m.io datastore:

{
  "report": {
    "gps": {
      "latitude": "39.702610038220882",
      "longitude": "-104.97231300920248"
    },
    "temp": {
      "celsius": "252",
      "fahrenheit": "76"
    }
  }
}