1. How to build a depression
predictor
(a.k.a. a belgian weather station)
using Arduino & Node.js
@stevenbeeckman #iotbe #njugbe
2. In short
Arduino IDE: arduino.cc/dowload
Install StandardFirmata sketch on the Arduino
npm install johnny-five
write your script.js
Run node script.js
3. You need a host
computer connected to
the Arduino
4. Let’s build a depression
predictor
(or a belgian weather station)
5. Things we need
A sensor
Something to gather the sensor data
Something to store the generated timeseries
A visualisation
14. Design
Need a REST API over HTTP
(Mandatory) POST new sensor values
(Optional) GET overview of past sensor values
Store data in a time series friendly database
15. Packages you need
"dependencies": {
"hapi": "^6.5.1",
"moment": "^2.8.2",
"tempodb": "^1.0.0"
}
https://github.com/stevenbeeckman/iotbe-njugbe/
16. Hosting
This code can run on your own server or in the
cloud.
I ran it in the cloud, on Heroku and used the
free TempoDB add-on.
17.
18. Some code
var Hapi = require('hapi');
var server = new Hapi.Server(process.env.PORT || 3000);
server.route({
method: 'GET'
, path: '/'
, handler: function(request, reply){
reply('Hello, Internet of Things fans!');
}
});
server.start(function(){
console.log('Server running at:' + server.info.uri);
});
heroku create
git add index.js
git commit -m “First deploy.”
git push heroku master
http://iotbe-njugbe.herokuapp.com/
19. Writing to your TempoDB
var TempoDBClient = require('tempodb').TempoDBClient;
var tempodb = new TempoDBClient('heroku-5e2f03bd25cf424098426a8a21db26f3', process.env.TEMPODB_API_KEY, process.env.
TEMPODB_API_SECRET, {hostname: process.env.TEMPODB_API_HOST, port: process.env.TEMPODB_API_PORT});
var moment = require('moment');
server.route({
method: 'POST'
, path: '/sensor/{sensor_id}/measurement'
, config: {
handler: function(request, reply){
var newMeasurement = new Object();
newMeasurement.t = moment().format("YYYY-MM-DDTHH:mm:ss.SSSZZ");
newMeasurement.v = request.payload.value;
var tempodb_data = new Array();
tempodb_data.push(newMeasurement);
var series_key = 'sensor-' + request.params.sensor_id;
tempodb.write_key(series_key, tempodb_data, function(error, result){
error ? reply(error) : reply(result);
});
}
}
});
20. Writing to your TempoDB
var TempoDBClient = require('tempodb').TempoDBClient;
var tempodb = new TempoDBClient('heroku-5e2f03bd25cf424098426a8a21db26f3', process.env.TEMPODB_API_KEY, process.env.
TEMPODB_API_SECRET, {hostname: process.env.TEMPODB_API_HOST, port: process.env.TEMPODB_API_PORT});
var moment = require('moment');
server.route({
method: 'POST'
, path: '/sensor/{sensor_id}/measurement'
, config: {
handler: function(request, reply){
var newMeasurement = new Object();
newMeasurement.t = moment().format("YYYY-MM-DDTHH:mm:ss.SSSZZ");
newMeasurement.v = request.payload.value;
var tempodb_data = new Array();
tempodb_data.push(newMeasurement);
var series_key = 'sensor-' + request.params.sensor_id;
tempodb.write_key(series_key, tempodb_data, function(error, result){
error ? reply(error) : reply(result);
});
}
}
});
Not documented: date must be formatted.
new Date() will not work as is. Use moment.js for
easy formatting.
21. Writing to your TempoDB
var TempoDBClient = require('tempodb').TempoDBClient;
var tempodb = new TempoDBClient('heroku-5e2f03bd25cf424098426a8a21db26f3', process.env.TEMPODB_API_KEY, process.env.
TEMPODB_API_SECRET, {hostname: process.env.TEMPODB_API_HOST, port: process.env.TEMPODB_API_PORT});
var moment = require('moment');
server.route({
method: 'POST'
, path: '/sensor/{sensor_id}/measurement'
, config: {
handler: function(request, reply){
var newMeasurement = new Object();
newMeasurement.t = moment().format("YYYY-MM-DDTHH:mm:ss.SSSZZ");
newMeasurement.v = request.payload.value;
var tempodb_data = new Array();
tempodb_data.push(newMeasurement);
var series_key = 'sensor-' + request.params.sensor_id;
tempodb.write_key(series_key, tempodb_data, function(error, result){
error ? reply(error) : reply(result);
});
}
}
});
Single key value pairs {t,v} must be wrapped in an
Array too...
22. Writing to your TempoDB
var TempoDBClient = require('tempodb').TempoDBClient;
var tempodb = new TempoDBClient('heroku-5e2f03bd25cf424098426a8a21db26f3', process.env.TEMPODB_API_KEY, process.env.
TEMPODB_API_SECRET, {hostname: process.env.TEMPODB_API_HOST, port: process.env.TEMPODB_API_PORT});
var moment = require('moment');
server.route({
method: 'POST'
, path: '/sensor/{sensor_id}/measurement'
, config: {
handler: function(request, reply){
var newMeasurement = new Object();
newMeasurement.t = moment().format("YYYY-MM-DDTHH:mm:ss.SSSZZ");
newMeasurement.v = request.payload.value;
var tempodb_data = new Array();
tempodb_data.push(newMeasurement);
var series_key = 'sensor-' + request.params.sensor_id;
tempodb.write_key(series_key, tempodb_data, function(error, result){
error ? reply(error) : reply(result);
});
}
}
});
Warning:
You have to pass the TempoDB database name too,
which is not documented!