Skip to content

Instantly share code, notes, and snippets.

@eni23
Created December 27, 2015 19:05
Show Gist options
  • Save eni23/8ec35d3ce5fb418c0ada to your computer and use it in GitHub Desktop.
Save eni23/8ec35d3ce5fb418c0ada to your computer and use it in GitHub Desktop.
/*******************************************************************************
*
* flower-power device abstraction
*
* deps:
* npm install flower-power
*
* author: cyrillvw
*
* usage example:
*
* var fp = new fpdevice(device);
* fp.set_num_measurements(4);
* fp.read(function(average, median, data){
* console.log(average, median, data);
* });
*
*******************************************************************************/
var fpdevice = function(device) {
var num_measurements = 3;
var measurement_ready = [];
var live_read_count = live_read_data = {};
var disable_lock = false;
var ready_callback = function(){};
// PUBLIC read all aviable data on device. takes about 1 sec * num_measurements
this.read = function(callback){
live_read_count = []
measurement_ready = [];
live_read_count = [];
live_read_data = {};
disable_lock = false;
device.connectAndSetUp(function(){
device.enableLiveMode();
device.enableCalibratedLiveMode();
device.readBatteryLevel(function(error, data) {
live_read_data.battery = [data];
});
if (callback){
ready_callback = callback;
}
});
}
// PUBLIC set number of single measurements per read
this.set_num_measurements = function(num){
num_measurements = num;
}
// init devices and bind events
function init(){
device.on('soilTemperatureChange', event_data.bind('temp_soil') );
device.on('calibratedAirTemperatureChange', event_data.bind('temp_air') );
device.on('calibratedSunlightChange', event_data.bind('sunlight') );
device.on('calibratedSoilMoistureChange', event_data.bind('soil_moisture') );
device.on('calibratedEaChange', event_data.bind('soil_ea') );
device.on('calibratedEcbChange', event_data.bind('soil_ecb') );
device.on('calibratedEcPorousChange', event_data.bind('soil_ec_porous') );
device.on('soilElectricalConductivityChange', event_data.bind('soil_conductivity') );
}
// gets triggered when an event occured aka measurement data
function event_data(data) {
if (!live_read_data[this]){
live_read_data[this] = [];
live_read_count[this] = [0];
measurement_ready[this] = false;
}
if (!measurement_ready[this]){
live_read_count[this]++;
live_read_data[this].push(data);
if (live_read_count[this] > (num_measurements-1) ) {
measurement_ready[this] = true;
check_ready(this);
}
}
else {
check_ready(this);
}
}
// checks if all measurements are ready
function check_ready(){
var arr_ready = true;
for (item of measurement_ready){
var chk = measurement_ready[item];
if (!measurement_ready[item]){
arr_ready = false;
}
}
if (arr_ready == true && disable_lock == false){
disable_lock = true;
device.disableLiveMode(function(){
device.disableCalibratedLiveMode(function(){
device.disconnect(function(){
disable_lock = false;
calculate_result();
});
});
});
}
}
// calculate average
function arr_average(values){
var num = values.reduce(function(a, b) {
return parseFloat(a) + parseFloat(b);
});
return (num / values.length);
}
// calculate median
function arr_median(values) {
values.sort( function(a,b) {return a - b;} );
var half = Math.floor(values.length/2);
if(values.length % 2){
return values[half];
}
else {
return (values[half-1] + values[half]) / 2.0;
}
}
// calculate result and trigger callback
function calculate_result(){
var average = {};
var median = {};
for (item in live_read_data){
average[item] = arr_average(live_read_data[item]);
median[item] = arr_median(live_read_data[item]);
}
ready_callback(average, median, live_read_data);
}
init();
return this;
}
module.exports = fpdevice;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment