Javascript talking to littleBits Cloud API

LittleBits is a set of components that allow kids to build their own electrical circuits. The Cloudbit will send and receive values from the Internet.

For this project we wanted to build some Web pages with Javascript that could interact with the littleBits Cloud API.

littleBits Hardware Setup

cloudbit_setup

The Cloudbit enables an input to be sent to the Internet, and it will receive a value (output) from the Internet. For a test setup we used a dimmer bit to adjust the input value with a number bit to show the value. On the output side we used a bargraph bit. Other combinations of bits are possible. The key is to be able to test and see your input and output values.

Cloudbits Setup

For the Cloudbit setup you will need to create a sign-in on the littleBits web site. For details on how to setup your Cloudbit use the following link.

The Cloud API is a RESTful interface, that uses http requests with some header definitions. Before you get started you’ll need your specific littleBits device ID and authorization token. In your specific Cloudbit definition go to the Settings icon, and get your Device ID and AccessToken.

littlebit_id

Cloudbit Rest API – First Example Testing with curl

The Cloudbit API reference can be found at : http://developers.littlebitscloud.cc/#devices. 

The Cloudbit API is based on the REST API standard, and this means that an HTTP request is made with some extra parameters that are passed in the header. The most important header item is the littleBits authorization token.

Curl is command line software tool that allows you to issue an HTTP request with header and method parameters and it returns the results in a text format. Curl is available for Windows, OSX and Linux. As an example to query the CloudBit API to get all my devices the following command is issued (note you’ll need to enter your own authorization code) :

curl "https://api-http.littlebitscloud.cc/v2/devices" \
-H "Authorization: Bearer 4f3830b44e1d4b2789b50b0xxxxxx"

[
{"label":"twinbit",
"id":"00e04c0379bb",
"subscriptions":[],
"subscribers":[],
"user_id":118217,
"is_connected":true,
"input_interval_ms":200}
]

Javascript Device Monitor

The curl example can be done in Javascript using the Javascript built in XMLHttpRequest object.

A monitor page can be useful if you have a number of Cloudbits and you’re interested is checking their status. Below is a sample web page and the associated HTML/javascript code. It’s important to note that text that is returned needs to have the first few characters removed in order to have a clean JSON string.

js_status

<!DOCTYPE html>
<html>
<body>
<h1 id='title'>Cloudbit Status Monitor</h1>
<h2>
Label : <font color='red' id='LB_label'></font><br>
Is Connected : <font color='red' id='is_connected'></font><br>
</h2>
 
<script>
var xhttp = new XMLHttpRequest();
// change the authtoken to match your settings
var authtoken = "4f3830b44e1dxxxxxxxxxxxxxxxx";
var theURL =  "https://api-http.littlebitscloud.cc/devices/";
xhttp.open("GET", theURL, true);
xhttp.setRequestHeader("Accept","application/vnd.littlebits.v2+json");
xhttp.setRequestHeader("Authorization", "Bearer " + authtoken);
xhttp.onreadystatechange = function() {
  if (xhttp.readyState == 4 ) { // when the response is complete get the data
    // remove leading "[" and trailing ']'
    var theresponse = xhttp.responseText.substring(1, xhttp.responseText.length -1);
    var lb_data = JSON.parse( theresponse );  
    
    document.getElementById('LB_label').innerText =  lb_data.label;
    document.getElementById('is_connected').innerHTML = lb_data.is_connected;
  }
}
xhttp.send();
</script>

</body>


</html>

Read Value Example

Reading a CloudBit value is a little tricky because the data is returned as a stream that updates every second. I saw a lot of people asking for a single point read, so hopefully this will be available soon.

The read value HTTP request is a little more complex than the simple monitor device example because you need to include the device that you are querying and a head parameter of :  Accept: application/json.

A curl example would be:

curl -XGET "https://api-http.littlebitscloud.cc/v2/devices/00e04c0379bb/input" -H "Authorization: Bearer 4f3830b44e1d4b2789b50b09cb493f06750b968cff5d45331c75006025fa0dc9" -H Accept: application/vnd.littlebits.v2+json"

data:{"type":"input","timestamp":1543536039623,"percent":6,"absolute":66,"name":"amplitude","payload":{"percent":6,"absolute":66},"from":{"device":{"id":"00e04c0379bb","mac":"00e04c0379bb"}}}

data:{"type":"input","timestamp":1543536039650,"percent":6,"absolute":65,"name":"amplitude","payload":{"percent":6,"absolute":65},"from":{"device":{"id":"00e04c0379bb","mac":"00e04c0379bb"}}}

...

For an HTML/Javascript single point read the key to check the xhttp.readyState == 3 , this will catch the first streamed response.  Below is a single point example with code.

js_in

<!DOCTYPE html>
<html>
<head>
<title>littleBits Get Input</title>
<script>
var theinput = 0;

function get_input() {
// update with your deviceid and authtoken
  var deviceid = "00e04c0379bb";
  var authtoken = "4f3830b44e1d4b27xxxx";
  var theurl = "https://api-http.littlebitscloud.cc/devices/";
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {

    if (xhttp.readyState == 3 ) {
	  	var datapackage = xhttp.responseText.split("\n\ndata:");
		var lb_data = JSON.parse( datapackage[1] );		 
		document.getElementById("thevalue").innerText =  lb_data.percent;
		xhttp.open("GET","",true);
		xhttp.send();
    }
  }
  xhttp.open("GET", theurl + deviceid + "/input", true);
  xhttp.setRequestHeader("Accept","application/json");
  xhttp.setRequestHeader("Authorization", "Bearer " + authtoken);
  xhttp.send();
}
</script>
</head>
<body>

<h1 id='title'>littleBit Get Input</h1>
The value : <font id="thevalue"> XXXX </font>
<button type="button" onclick="get_input()">Request data</button>
<br>

</body>
</html>

Output Example

A CloudBit output can be either sustained or it can be timed out. The curl command is:

curl "https://api-http.littlebitscloud.cc/v2/devices/yourdevice_id/output" \
  -X POST \
  -H "Authorization: your_auth_code" \
  -H "Content-type: application/json" \
  -d '{ "percent": 100, "duration_ms": 3000 }'

For an HTML/Javascipt web the http response is a POST, and the value’s percent and duration are put into a JSON string:

var params = JSON.stringify({duration_ms: duration,percent: thevalue});

An example page and code is shown below:

js_out

<!DOCTYPE html>
<html>
<body>
<h2>CloudBit Output Test</h2>
<button type="button" onclick="sendoutput()">Send Output</button>
<br>
<pre>
Output Time (ms): <input type="text" id="duration" value="-1"/> (constant = -1)</br>
Output Value	: <input type="text" id="thevalue" value="80"/> (percent 0-100)</br> 
</pre>
<p id="demo"></p>


function sendoutput() {
	var xhttp = new XMLHttpRequest();
        // change to your device id
	xhttp.open("POST", "https://api-http.littlebitscloud.cc/devices/00e04c0379bb/output?", true);
	xhttp.setRequestHeader("Accept","application/vnd.littlebits.v2+json");
	// change to your Auth Token
	xhttp.setRequestHeader("Authorization", "Bearer 4f3830b44e1d4b27xxxx");
	xhttp.setRequestHeader("Content-Type","application/json");

	var duration = document.getElementById("duration").value;
	var thevalue = document.getElementById("thevalue").value;

	var params = JSON.stringify({duration_ms: duration,percent: thevalue});

	xhttp.onreadystatechange = function() {
		document.getElementById("demo").innerHTML = "Result=" +xhttp.responseText;
	}

	xhttp.send(params);
}


</body>
</html>

Gauges

Once you’ve got the basics down it’s possible to start making some more advanced applications. There are lot of Javascript charting libraries. For this example I used the Google  Charts library.

js_gauge

<html>
  <head>
   https://www.gstatic.com/charts/loader.js
   
	  var littleBitinput = 0;
      google.charts.load('current', {'packages':['gauge']});
      google.charts.setOnLoadCallback(drawChart);
      function drawChart() {

        var data = google.visualization.arrayToDataTable([
          ['Label', 'Value'],
          ['littleBits', 100],
        ]);

        var options = { 
          width: 600, height: 600,
          redFrom: 90, redTo: 100,
          yellowFrom:75, yellowTo: 90,
		  greenFrom: 60, greenTo: 75,
          minorTicks: 5
        };

        var chart = new google.visualization.Gauge(document.getElementById('chart_div'));

        chart.draw(data, options);

        setInterval(function() {
		  get_input();
          data.setValue(0, 1, littleBitinput);
          chart.draw(data, options);
        }, 500);
 
      }
	  function get_input() {
	  // change to your deviceid and authtoken
		  var deviceid = "00e04c0379bb";
		  var authtoken = "4f3830b44e1d4b27xxx";
		  var theurl = "https://api-http.littlebitscloud.cc/devices/";		  
		  var xhttp = new XMLHttpRequest();
		  
		  xhttp.onreadystatechange = function() {
			if (xhttp.readyState == 3 ) {
				var datapackage = xhttp.responseText.split("\n\ndata:");
				var lb_data = JSON.parse( datapackage[1] );		 
				littleBitinput =  lb_data.percent;
				xhttp.open("GET","",true);
				xhttp.send();
			}
		  }
		  xhttp.open("GET", theurl + deviceid + "/input", true);
		  xhttp.setRequestHeader("Accept","application/vnd.littlebits.v2+json");
		  xhttp.setRequestHeader("Authorization", "Bearer " + authtoken);
		  xhttp.send();

}
    
  </head>
  <body>

 

Final Comment

There are some great projects that you could do with littleBits and the CloudAPI.

One still project I did was to use smoothie charts http://smoothiecharts.org/ for the real time charts.

lb_chart2

 

 

 

 

MQTT and Javascript

MQTT (Message Queuing Telemetry Transport) is a  publish-subscribe-based messaging protocol that is used on many Internet of Things (IoT) projects. It works on top of the TCP/IP protocol and it is designed for connections with remote locations where a “small code footprint” is required or the network bandwidth is limited. The publish-subscribe messaging pattern requires a message broker.

MQTT_js_overview

There is support for MQTT on a large variety of programming languages and platforms. An Arduino or Raspberry Pi module can sent (or publish) I/O to a MQTT broker, and they can also receive (or subscribe) to data.

There are a number of MQTT brokers that can be used. One of the most popular ones is the Mosquitto MQTT broker, and it can be loaded on Windows, OSX and Linux systems. For this blog we will be using the Mosquitto test MQTT server. This Internet based server should not be used for real systems, but it is excellent for small short terms tests.

MQTT Web Sockets

The MQTT server has configurable MQTT and Web Socket ports. For a typical Raspberry Pi or Arduino connection, the default MQTT port 1883 would be used. In many Internet applications only certain ports are open, so for this reason a different MQTT Web Socket is used. This is configurable but ports like 80 or 8080 are typically used.MQTT_web_layout

Javascript Application

There are a number of MQTT javascript libraries that are available. One of the more popular ones is the Paho library that is available at:

https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js

As a first example we will look at creating 2 pages. The first page will  publish a value, and the second page will subscribe to the data.

MQTT_js_pubsub

The publish code is:

<html>
<head>
<title> MQTT Publish Message</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>

<script>
// Define some MQTT variables
var mqtt_server = "";
var mqtt_port = "";
var mqtt_destname = "";

function send_mqtt_msg() {
// Send an MQTT message
  mqtt_server = document.getElementById("mqtt_server").value;
  mqtt_port = Number(document.getElementById("mqtt_port").value);
 

  client = new Paho.MQTT.Client(mqtt_server, mqtt_port,"");
  client.connect({onSuccess:onConnect});
  document.getElementById("pubmsg").innerHTML = "Trying to connect...
";
}
function onConnect() {
  document.getElementById("pubmsg").innerHTML = "New connection made...
";
  var mqtt_destname = document.getElementById("mqtt_destname").value;
  var mqtt_msg = document.getElementById("mqtt_msg").value;   
  message = new Paho.MQTT.Message(mqtt_msg);
  message.destinationName = mqtt_destname;
  client.send(message);
  document.getElementById("pubmsg").innerHTML = "topic:" + mqtt_destname + " = " + mqtt_msg + " ...sent";
}  
// called when a message arrives
</script>
<body>
<h1>MQTT Publish Test Page</h1>

Server Name: <input type="text" id="mqtt_server" value="test.mosquitto.org"><br><br>
Websocket: <input type="text" id="mqtt_port" value="8080"><br><br>
DestinationName: <input type="text" id="mqtt_destname" value="my_IoT_value1"><br><br>
Message: <input type="text" id="mqtt_msg" value="test message"><br><br>

<button onclick="send_mqtt_msg()">Publish MQTT Message</button>
</body>
<hr>
<div id=pubmsg></div>
</html>

The subscribe code is:

<html>
<head>
<title> MQTT Subscribe Message</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
<script>

function sub_mqtt_msg() {
// Send an MQTT message
  var mqtt_server = document.getElementById("mqtt_server").value;
  var mqtt_port = Number(document.getElementById("mqtt_port").value);

  client = new Paho.MQTT.Client(mqtt_server, mqtt_port,"");
  client.onMessageArrived = onMessageArrived;
  client.onMessageArrived = onMessageArrived;
  client.connect({onSuccess:onConnect});
  document.getElementById("submsg").innerHTML = "Trying to connect...
";

}
function onConnect() {
  document.getElementById("submsg").innerHTML = "New connection made...
";
  var mqtt_destname = document.getElementById("mqtt_destname").value;  
  client.subscribe(mqtt_destname);
  document.getElementById("submsg").innerHTML = "Subscribing to topic: " + mqtt_destname + " ...
";
}
function onMessageArrived(message) {
  var result = message.destinationName + " : " + message.payloadString + "
";
  document.getElementById("submsg").innerHTML = result;
}

</script>
<body>
<h1>MQTT Subscribe Test Page</h1>

Server Name: <input type="text" id="mqtt_server" value="test.mosquitto.org"><br><br>
Websocket: <input type="text" id="mqtt_port" value="8080"><br><br>
DestinationName: <input type="text" id="mqtt_destname" value="my_IoT_value1"><br><br>

<button onclick="sub_mqtt_msg()">Subscript to MQTT</button>
<hr>
<h2>Subscribed Messages:</h2>
<div id=submsg></div>
</body>

</html>

Once you’ve got the basics down it’s possible to make some more advanced web interface pages.

Chart and Gauges

For your IoT projects there are a lot of Dash board options that are available. One of my favorites is Node-Red because it is totally free and standalone.

If you would like to create your own web interface there are a number of good javascript charting and gauge libraries available. For my examples I used Google charts with the Gauge chart . To simulate the inputs I used three of our MQTT Publish pages.

MQTT_js_sim

The code for the gauges page is :

<html>
<head>
<title>IoT - MQTT to JS</title>
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.js" type="text/javascript"></script>
<script src="https://www.gstatic.com/charts/loader.js" type="text/javascript"></script>

<script>
// MQTT variables
var MQTTnames = ["my_IoT_value1","my_IoT_value2","my_IoT_value3"];
var MQTTvalues = [0,0,0];


// Define the Google gauge chart
      google.charts.load('current', {'packages':['gauge']});
      google.charts.setOnLoadCallback(drawChart);

      function drawChart() {

        var data = google.visualization.arrayToDataTable([
          ['Label', 'Value'], 
      [MQTTnames[0], MQTTvalues[0]],
      [MQTTnames[1], MQTTvalues[1]],
      [MQTTnames[2], MQTTvalues[2]],      
        ]);

        var options = {
          width: 800, height: 1000,
          redFrom: 90, redTo: 100,
          yellowFrom:75, yellowTo: 90,
          minorTicks: 5
        };

        var chart = new google.visualization.Gauge(document.getElementById('chart_div'));

        chart.draw(data, options);

        setInterval(function() {
      for (var i=0; i < MQTTnames.length; i++) {
      data.setValue(i, 1, MQTTvalues[i]);
      }
          chart.draw(data, options);

      }, 1000);
}

// Create a client instance
client = new Paho.MQTT.Client("test.mosquitto.org", 8080,"");
client.onMessageArrived = onMessageArrived;

// connect the client
client.connect({onSuccess:onConnect});

// called when the client connects
function onMessageArrived(message) {
  
  for (var i=0; i < MQTTnames.length; i++) {
  if (message.destinationName == MQTTnames[i]) {
    MQTTvalues[i] = Number(message.payloadString);
  }
  }
}
function onConnect() {
  // Once a connection has been made, make a subscription and send a message.
  for (var i=0; i < MQTTnames.length; i++) {
  client.subscribe(MQTTnames[i]);
  }
}
// called when a message arrives
</script>
<body>
<h1  style = 'font-size: xx-large'>IoT - MQTT to JavaScript</h1>
<div id="chart_div" style="width: 100%; height: 100%;"></div>
</body>
</html>

There are many other charting options that could be used. Below is an example using the Google Chart library with bars instead of gauges.

MQTT_js_bars.png

Final Comment

Using Javascript to interact with your IoT projects open up a lot of potential for adding functionality. I found that the Python version of the Paho MQTT library to have better documentation and perhaps some more functions, but at the end of the day I was able to do all the I wanted.