28
How to build a depression predictor (a.k.a. a belgian weather station) using Arduino & Node.js @stevenbeeckman #iotbe #njugbe

Arduino & node.js

Embed Size (px)

DESCRIPTION

How to combine Arduino, a photoresistor, node.js, hapi.js and a time series database called TempoDB?

Citation preview

Page 1: Arduino & node.js

How to build a depression predictor

(a.k.a. a belgian weather station)

using Arduino & Node.js@stevenbeeckman #iotbe #njugbe

Page 2: Arduino & node.js

In short

Arduino IDE: arduino.cc/dowloadInstall StandardFirmata sketch on the Arduinonpm install johnny-fivewrite your script.jsRun node script.js

Page 3: Arduino & node.js

You need a host computer connected to

the Arduino

Page 4: Arduino & node.js

Let’s build a depression predictor

(or a belgian weather station)

Page 5: Arduino & node.js

Things we need

A sensorSomething to gather the sensor dataSomething to store the generated timeseriesA visualisation

Page 6: Arduino & node.js

photoresistor Arduino MacBook Browsercloud

Page 7: Arduino & node.js

Heroku+

node.js+

hapi.js+

TempoDB

add-on

photoresistor Arduino Uno

Node.js +

Johnny Five +

request+

forever

TempoDB web app

ADC http httpusb

Page 8: Arduino & node.js

Heroku+

node.js+

hapi.js+

TempoDB

add-on

photoresistor Arduino Uno

Node.js +

Johnny Five +

request+

forever

TempoDB web app

ADC http httpusb

Page 9: Arduino & node.js

MacGyver-ism: no resistors in house and no nearby shops to buy them from -> use a piezo as a resistor

Page 10: Arduino & node.js

Heroku+

node.js+

hapi.js+

TempoDB

add-on

photoresistor Arduino Uno

Node.js +

Johnny Five +

request+

forever

TempoDB web app

ADC http httpusb

Page 11: Arduino & node.js
Page 12: Arduino & node.js

Packages you need

npm install --save johnny-fivenpm install --save requestnpm install -g forever

usage: forever start script.jsforever list (to see what’s running)

https://github.com/stevenbeeckman/arduino-j5

Page 13: Arduino & node.js

Heroku+

node.js+

hapi.js+

TempoDB

add-on

photoresistor Arduino Uno

Node.js +

Johnny Five +

request+

forever

TempoDB web app

ADC http httpusb

Page 14: Arduino & node.js

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

Page 15: Arduino & node.js

Packages you need "dependencies": {

"hapi": "^6.5.1",

"moment": "^2.8.2",

"tempodb": "^1.0.0"

}

https://github.com/stevenbeeckman/iotbe-njugbe/

Page 16: Arduino & node.js

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.

Page 17: Arduino & node.js
Page 18: Arduino & node.js

Some codevar 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/

Page 19: Arduino & node.js

Writing to your TempoDBvar 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);

});

}

}

});

Page 20: Arduino & node.js

Writing to your TempoDBvar 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.

Page 21: Arduino & node.js

Writing to your TempoDBvar 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...

Page 22: Arduino & node.js

Writing to your TempoDBvar 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!

Page 23: Arduino & node.js

Heroku+

node.js+

hapi.js+

TempoDB

add-on

photoresistor Arduino Uno

Node.js +

Johnny Five +

request+

forever

TempoDB web app

ADC http httpusb

Page 24: Arduino & node.js
Page 25: Arduino & node.js
Page 26: Arduino & node.js

MacBooks crash too

hard drive failure

Page 28: Arduino & node.js

Questions?@stevenbeeckman #iotbe #njugbe