0.1.8 • Published 8 years ago

sensor-canon v0.1.8

Weekly downloads
-
License
MIT
Repository
github
Last release
8 years ago

sensor-canon

Join the chat at https://gitter.im/sensor-canon/Lobby

Fire a scheduled time series of (johnny-five) sensor data against any RESTful API.

johnny-fire

NPM

Install

$ npm install --save sensor-canon

Why this module?

Thanks to fantastic johnny-five, collecting sensor data with JavaScript/Node.js is a piece of cake. However, I found myself struggling to turn the sensor data into a scheduled time series which can be efficiently stored in a database. The sensor-canon wraps this functionality in a single class. It generates a scheduled time series of POST and/or PUT requests carrying the sensor data as payload in .json format. The idea is to fire these requests against POST/PUT endpoints wired up to a object-oriented database like MongoDB.

Currently, the sensor-canon can fire in two different modes:

  • POST only (when passing only a POST frequency to the canon - see description below): Data from each scheduled sensor read is send as POST request and (on the receiving end) can be inserted as a separate database document. This approach should be efficient enough for most applications.

  • POST and PUT (when passing a POST and a PUT frequency): The canon first sends a POST requests carrying appropriately shaped placeholder data for pre-allocation to the database. Subsequently, PUT requests carrying real sensor data for updating the pre-allocated document are send. This approach can drastically increases database performance (when using MongoDB for example) and allows applications involving thousands of sensors as well as high update and query frequencies. Check out this post by Sandeep Parikh and Kelly Stirman and these talks to get an example.

The frequencies for both, pre-allocation (POST) and update (PUT) requests are set using cron expressions. The sensor-canon uses cron-parser and node-schedule for generation of correctly shaped pre-allocation data and for scheduling.

Usage

const five = require('johnny-five')
const SensorCanon = require('sensor-canon')

const board = new five.Board()

board.on('ready', function () {
  // a simple sensor of the Sensor class, no valueAs needed
  const photoresistor = new five.Sensor({
    id: 'photoresistor',
    pin: 'A1'
  })

  // a second, more specific sensor. valueAs has to be set!:
  const thermometer = new five.Thermometer({
    id: 'thermometer',
    controller: "HTU21D",
    valueAs: 'celsius' // also possible: kelvin, fahrenheit
  })

  const sensorArray = [photoresistor, thermometer]

  const sensorCanon = new SensorCanon({
    sensors: sensorArray,
    targetUrl: 'endpoint_wired_up_to_database',
    postFreq: '* * * * *',
    putFreq: '* * * * * *' // optional; set only when preallocation is desired
  })

  // The canon is now ready to fire:
  sensorCanon.continuousFire()
  // for testing you can also do:
  // sensorCanon.preallocate()
  // sensorCanon.fire()
})

First, require johnny-five and the sensor-canon and instantiate a new board. Next, instantiate a single (or a bunch of) johnny-five sensors as usual but mind the following:

Give each sensor a unique id (photoresistor and thermometer in the example). It will be part of the compound index that the canon generates for each future database document! Also: pass a valueAs parameter specifying the variable name that the sensor data gets assigned by johnny-five - kelvin, celsius or fahrenheit in case of the thermometer used in the example. Without it the canon won't be able to read the generated data! Last, when using more than one sensor, put the sensors into an array.

Subsequently, instantiate an new canon and pass an options object specifying the sensors (a single sensor or an array of them), a targetUrl as well as cron expressions for setting a postFreq and (if preallocation is desired) a putFreq.

The canon is then ready and you can use one of three methods to fire it: preallocate(), fire() and continuousFire(). preallocate() sends a single POST request with preallocation data. Works only when both postFreq and putFreq are set. fire() sends a single POST or PUT request depending on the options passed to the canon. continuousFire() continuously sends POST requests only or POST followed by PUT requests - again depending on the options passed to the canon.

In the example above, for each sensor a POST request with pre-allocation data is send every minute '* * * * *' and a PUT request carrying real sensor data is send every second '* * * * * *'. Consequently the pre-allocation data in the POST request contains placeholders for 60 datapoints and would have the following structure for the photoresistor from the above example:

{
  _id: 'photoresistor:201606071510',  
  data: [
  {
    time: NaN,
    value: NaN
  },
  //... 60 times!
  ]
}

The _id is a compound index of the unique sensor id and a date string specifying the current minute. The data array contains 60 placeholder objects (time: NaN, value: NaN} which should be included in the document that gets pre-allocated to the database. Sensor data for updating this document (PUT payload) would be structured like this:

{
  _id: 'photoresistor:201606071510',  // used to find the document in the db!
  data: {
    time: '20160607151023', // here: with resolution down to the second
    value: 423
  }
}

Please note: The sensor-canon currently accepts only simple cron expressions with '*' in each position) when both a POST and a PUT frequency are set. The full range of cron expressions is supported when POSTing only.

Todos

  • Add tests
  • Support a wider range of cron-expressions

Copyright and license

Copyright 2016 Matthias Munder.
Licensed under the MIT license.

js-standard-style

0.1.8

8 years ago

0.1.6

8 years ago

0.1.5

8 years ago

0.1.4

8 years ago

0.1.3

8 years ago

0.1.2

8 years ago

0.1.1

8 years ago

0.1.0

8 years ago