From d511ee69fb167aad2e7a4d1696c7aacb04879d6a Mon Sep 17 00:00:00 2001 From: dceejay Date: Thu, 26 Mar 2015 18:55:03 +0000 Subject: [PATCH] lots of little node edits to clean up jsHint "errors" --- hardware/BBB/145-BBB-hardware.js | 11 +- hardware/BBB/package.json | 2 +- hardware/HummingboardGPIO/hb-gpio.js | 3 +- hardware/blinkstick/76-blinkstick.js | 22 +- hardware/digiRGB/78-digiRGB.js | 2 +- hardware/heatmiser/100-heatmiser.js | 93 +++--- hardware/heatmiser/package.json | 2 +- hardware/hue/103-hue_discover.js | 13 +- hardware/hue/104-hue_manage.js | 12 +- io/emoncms/88-emoncms.js | 124 ++++---- io/emoncms/package.json | 2 +- io/snmp/package.json | 2 +- io/snmp/snmp.js | 19 +- parsers/geohash/70-geohash.js | 20 +- parsers/geohash/package.json | 2 +- social/pushbullet/57-pushbullet.js | 65 ++--- test/function/rbe/rbe_spec.js | 131 +++++++++ test/social/pushbullet/57-pushbullet_spec.js | 281 +++++++++---------- 18 files changed, 478 insertions(+), 328 deletions(-) create mode 100644 test/function/rbe/rbe_spec.js diff --git a/hardware/BBB/145-BBB-hardware.js b/hardware/BBB/145-BBB-hardware.js index 8befc2fc..f98b660f 100755 --- a/hardware/BBB/145-BBB-hardware.js +++ b/hardware/BBB/145-BBB-hardware.js @@ -49,7 +49,7 @@ module.exports = function (RED) { setPinMode = function (pin, direction, callback) { bonescript.pinMode(pin, direction, undefined, undefined, undefined, callback); } - } catch (e) { + } catch (er) { throw "Info : Ignoring Beaglebone specific node."; } } @@ -119,10 +119,11 @@ module.exports = function (RED) { this.topic = n.topic; // the topic is not currently used this.pin = n.pin; // The Beaglebone Black pin identifying string this._pin = adjustName(this.pin); // Adjusted for Octal if necessary - if (n.activeLow) // Set the 'active' state 0 or 1 as appropriate + if (n.activeLow) { // Set the 'active' state 0 or 1 as appropriate this.activeState = 0; - else + } else { this.activeState = 1; + } this.updateInterval = n.updateInterval*1000; // How often to send totalActiveTime messages this.debounce = n.debounce; // Enable switch contact debouncing algorithm if (n.outputOn === "rising") { @@ -229,7 +230,7 @@ module.exports = function (RED) { // payload, if possible. Otherwise clear the totalActiveTime (so we start counting // from zero again) var inputCallback = function (ipMsg) { - if (String(ipMsg.topic).search(/load/i) < 0 || isFinite(ipMsg.payload) == false) { + if (String(ipMsg.topic).search(/load/i) < 0 || isFinite(ipMsg.payload) === false) { node.totalActiveTime = 0; } else { node.totalActiveTime = Number(ipMsg.payload); @@ -327,7 +328,7 @@ module.exports = function (RED) { // insensitive) and the payload is a valid number, set the count to that // number, otherwise set it to zero var inputCallback = function (msg) { - if (String(msg.topic).search(/load/i) < 0 || isFinite(msg.payload) == false) { + if (String(msg.topic).search(/load/i) < 0 || isFinite(msg.payload) === false) { node.pulseCount = 0; } else { node.pulseCount = Number(msg.payload); diff --git a/hardware/BBB/package.json b/hardware/BBB/package.json index 8075418c..5796cb12 100644 --- a/hardware/BBB/package.json +++ b/hardware/BBB/package.json @@ -1,6 +1,6 @@ { "name" : "node-red-node-beaglebone", - "version" : "0.0.6", + "version" : "0.0.7", "description" : "A set of Node-RED nodes to interface to the GPIO pins of a Beaglebone Black board", "dependencies" : { }, diff --git a/hardware/HummingboardGPIO/hb-gpio.js b/hardware/HummingboardGPIO/hb-gpio.js index 88cc61db..71a81e63 100644 --- a/hardware/HummingboardGPIO/hb-gpio.js +++ b/hardware/HummingboardGPIO/hb-gpio.js @@ -147,7 +147,8 @@ module.exports = function(RED) { this.level = n.level || 0; this.out = n.out || "out"; var node = this; - (node.out === "pwm") ? (node.op = "pwm") : (node.op = "write"); + if (node.out === "pwm") { node.op = "pwm"; } + else { node.op = "write"; } if (node.pin !== undefined) { exec(gpioCommand+" mode "+node.pin+" "+node.out, function(err,stdout,stderr) { diff --git a/hardware/blinkstick/76-blinkstick.js b/hardware/blinkstick/76-blinkstick.js index 94a00cc1..a388b541 100644 --- a/hardware/blinkstick/76-blinkstick.js +++ b/hardware/blinkstick/76-blinkstick.js @@ -101,7 +101,7 @@ module.exports = function(RED) { node.error("BlinkStick with serial number " + node.serial + " not found"); } else { node.status({fill:"green",shape:"dot",text:"connected"}); - if (callback) callback(); + if (callback) { callback(); } } }); } else { @@ -112,7 +112,7 @@ module.exports = function(RED) { node.error("No BlinkStick found"); } else { node.status({fill:"green",shape:"dot",text:"connected"}); - if (callback) callback(); + if (callback) { callback(); } } } }; @@ -197,26 +197,26 @@ module.exports = function(RED) { if (Array.isArray(msg.payload)) { if (Object.size(node.led) !== 0) { node.led.setMode(2); // put it into ws2812B LED mode - var data = []; + var dat = []; for (var i = 0; i < msg.payload.length; i++) { if (typeof msg.payload[i] === "string") { // if string then assume must be colour names var params = node.led.interpretParameters(msg.payload[i]); // lookup colour code from name if (params) { - data.push(params.green); - data.push(params.red); - data.push(params.blue); + dat.push(params.green); + dat.push(params.red); + dat.push(params.blue); } else { node.warn("invalid colour: "+msg.payload[i]); } } else { // otherwise lets use numbers 0-255 - data.push(msg.payload[i+1]); - data.push(msg.payload[i]); - data.push(msg.payload[i+2]); + dat.push(msg.payload[i+1]); + dat.push(msg.payload[i]); + dat.push(msg.payload[i+2]); i += 2; } } - if ((data.length % 3) === 0) { // by now length must be a multiple of 3 - node.led.setColors(0, data, function(err) { + if ((dat.length % 3) === 0) { // by now length must be a multiple of 3 + node.led.setColors(0, dat, function(err) { if (err) { node.log(err); } }); } diff --git a/hardware/digiRGB/78-digiRGB.js b/hardware/digiRGB/78-digiRGB.js index e8fc247c..735652b6 100644 --- a/hardware/digiRGB/78-digiRGB.js +++ b/hardware/digiRGB/78-digiRGB.js @@ -15,7 +15,7 @@ **/ module.exports = function(RED) { - //"use strict"; + "use strict"; var HID = require('node-hid'); var device; var node; diff --git a/hardware/heatmiser/100-heatmiser.js b/hardware/heatmiser/100-heatmiser.js index d439bedd..fc9bcd98 100644 --- a/hardware/heatmiser/100-heatmiser.js +++ b/hardware/heatmiser/100-heatmiser.js @@ -144,9 +144,9 @@ module.exports = function(RED) { } }; - this.validateAndWrite = function(message) { for (var key in message.payload) { + if (message.payload.hasOwnProperty(key)) { // Ensure our valid keys contain valid values switch(key) { case "runmode" : @@ -159,40 +159,40 @@ module.exports = function(RED) { } break; - // case "holiday" : - // if (DEBUG) { - // hminnode.log("Hit the holiday case"); - // } - // if (!('enabled' in message.payload[key]) && !('time' in message.payload[key])) { - // hminnode.log("Warning: Unsupported 'holiday' value passed!"); - // return; - // } - // var time = message.payload[key].time; - // // Ensure hminnode time is a date - // if (typeof(time) == "string") { - // hminnode.log("Typeof time was " +typeof(message.payload[key].time)); - // // message.payload[key].time = new Date(message.payload[key].time); - // message.payload[key].time = new Date(2014, 02, 15, 12, 0, 0); - // hminnode.log("Typeof time is now " +typeof(message.payload[key].time)); - // } - // // Also add in away mode (for hot water) if we're on hols - // if (message.payload[key].time) { - // message.payload.away_mode = 1; - // } - // else { - // message.payload.away_mode = 0; - // } - // break; + //case "holiday" : + //if (DEBUG) { + //hminnode.log("Hit the holiday case"); + //} + //if (!('enabled' in message.payload[key]) && !('time' in message.payload[key])) { + //hminnode.log("Warning: Unsupported 'holiday' value passed!"); + //eturn; + //} + //var time = message.payload[key].time; + //// Ensure hminnode time is a date + //if (typeof(time) == "string") { + //hminnode.log("Typeof time was " +typeof(message.payload[key].time)); + //// message.payload[key].time = new Date(message.payload[key].time); + //message.payload[key].time = new Date(2014, 02, 15, 12, 0, 0); + //hminnode.log("Typeof time is now " +typeof(message.payload[key].time)); + //} + //// Also add in away mode (for hot water) if we're on hols + //if (message.payload[key].time) { + //message.payload.away_mode = 1; + //} + //else { + //message.payload.away_mode = 0; + //} + //break; - // case "hotwater" : - // if (DEBUG) { - // hminnode.log("Hit the hotwater case"); - // } - // if (message.payload[key] !== "on" && message.payload[key] !== "boost" && message.payload[key] !== "off") { - // hminnode.log("Warning: Unsupported 'hotwater' value passed!"); - // return; - // } - // break; + //case "hotwater" : + //if (DEBUG) { + //hminnode.log("Hit the hotwater case"); + //} + //if (message.payload[key] !== "on" && message.payload[key] !== "boost" && message.payload[key] !== "off") { + //hminnode.log("Warning: Unsupported 'hotwater' value passed!"); + //return; + //} + //break; case "heating" : // Ensure heating stays last! It's got a multi write scenario @@ -206,10 +206,14 @@ module.exports = function(RED) { // Set sane temp and time ranges and sanitise to float/int var target = parseFloat(message.payload[key].target); var hold = parseInt(message.payload[key].hold); - (target > 30.0) ? message.payload[key].target = 30.0 : message.payload[key].target = target; - (hold > 1440) ? message.payload[key].hold = 1440 : message.payload[key].hold = hold; - (target <= 10.0) ? message.payload[key].target = 10.0 : message.payload[key].target = target; - (hold <= 0) ? message.payload[key].hold = 0 : message.payload[key].hold = hold; + if (target > 30.0) { message.payload[key].target = 30.0; } + else { message.payload[key].target = target; } + if (hold > 1440) { message.payload[key].hold = 1440; } + else { message.payload[key].hold = hold; } + if (target <= 10.0) { message.payload[key].target = 10.0; } + else { message.payload[key].target = target; } + if (hold <= 0) { message.payload[key].hold = 0; } + else { message.payload[key].hold = hold; } // Ensure hminnode runmode == heating first if (hminnode.currentStatus.run_mode === "frost_protection") { @@ -226,13 +230,14 @@ module.exports = function(RED) { default : break; } + // Valid set of key messages, construct DCB and write + var dcb = message.payload; + if (DEBUG) { + hminnode.log("Injecting " + JSON.stringify(dcb)); + } + hminnode.write(dcb); } - // Valid set of key messages, construct DCB and write - var dcb = message.payload; - if (DEBUG) { - hminnode.log("Injecting " + JSON.stringify(dcb)); - } - hminnode.write(dcb); + } }; this.on("input", function(message) { diff --git a/hardware/heatmiser/package.json b/hardware/heatmiser/package.json index 0a09bdaf..eaa24d3c 100644 --- a/hardware/heatmiser/package.json +++ b/hardware/heatmiser/package.json @@ -1,6 +1,6 @@ { "name" : "node-red-contrib-heatmiser", - "version" : "0.0.1", + "version" : "0.0.2", "description" : "A Node-RED node to control and poll a HeatMiser thermostat.", "dependencies" : { "heatmiser" : "2.0.0" diff --git a/hardware/hue/103-hue_discover.js b/hardware/hue/103-hue_discover.js index 4106aeff..b48294ec 100644 --- a/hardware/hue/103-hue_discover.js +++ b/hardware/hue/103-hue_discover.js @@ -40,17 +40,17 @@ function HueNodeDiscovery(n) { //get username from user input this.username = n.username; - + // Store local copies of the node configuration (as defined in the .html) this.topic = n.topic; this.on("input", function(msg){ - + //start with detecting the IP address of the Hue gateway in the local network: hue.locateBridges(function(err, result) { var msg = {}; - if (err) throw err; + if (err) { throw err; } //check for found bridges if(result[0]!=null) { //save the IP address of the 1st bridge found @@ -61,17 +61,16 @@ function HueNodeDiscovery(n) { var api = new HueApi(this.gw_ipaddress, node.username); api.lights(function(err, lights) { var msg2 = {}; - if (err) throw err; + if (err) { throw err; } var lights_discovered = JSON.stringify(lights, null, 2); msg2.topic = "Lights"; msg2.payload = lights_discovered; node.send([msg, msg2]); - }); } else { //bridge not found: - var msg = {}; + msg = {}; msg.payload = "Bridge not found!"; node.send(msg); } @@ -102,4 +101,4 @@ var displayError = function(err) { // Register the node by name. This must be called before overriding any of the // Node functions. -RED.nodes.registerType("Discover",HueNodeDiscovery); \ No newline at end of file +RED.nodes.registerType("Discover",HueNodeDiscovery); diff --git a/hardware/hue/104-hue_manage.js b/hardware/hue/104-hue_manage.js index 5f79fcc4..fbd564c3 100644 --- a/hardware/hue/104-hue_manage.js +++ b/hardware/hue/104-hue_manage.js @@ -91,16 +91,18 @@ function setLights(node, myMsg) { } else { //set lamp according to node settings - if(node.lamp_status=="ON") + if(node.lamp_status=="ON") { api.setLightState(node.lamp_id, state.on().rgb(hexToRgb(node.color).r,hexToRgb(node.color).g,hexToRgb(node.color).b).brightness(node.brightness)).then(displayResult).fail(displayError).done(); - else + } else { api.setLightState(node.lamp_id, state.off()).then(displayResult).fail(displayError).done(); + } } - if(lamp!=-1) + if(lamp!=-1) { msg2.payload = 'Light with ID: '+lamp+ ' was set to '+myMsg.payload; - else + } else { msg2.payload = 'Light with ID: '+node.lamp_id+ ' was set to '+node.lamp_status; + } node.send(msg2); } @@ -138,7 +140,7 @@ function HueNode(n) { hue.locateBridges(function(err, result) { - if (err) throw err; + if (err) { throw err; } //check for found bridges if(result[0]!=null) { //save the IP address of the 1st bridge found diff --git a/io/emoncms/88-emoncms.js b/io/emoncms/88-emoncms.js index a2904a37..ae3e9d94 100644 --- a/io/emoncms/88-emoncms.js +++ b/io/emoncms/88-emoncms.js @@ -14,68 +14,70 @@ * the License. */ -var RED = require(process.env.NODE_RED_HOME+"/red/red"); -//The Server Definition - this opens (and closes) the connection -function EmoncmsServerNode(n) { - RED.nodes.createNode(this,n); - this.server = n.server; - this.name = n.name; -} -RED.nodes.registerType("emoncms-server",EmoncmsServerNode,{ - credentials: { - apikey: {type:"text"} +module.exports = function(RED) { + "use strict"; + //The Server Definition - this opens (and closes) the connection + function EmoncmsServerNode(n) { + RED.nodes.createNode(this,n); + this.server = n.server; + this.name = n.name; } -}); - -function Emoncms(n) { - RED.nodes.createNode(this,n); - this.emonServer = n.emonServer; - var sc = RED.nodes.getNode(this.emonServer); - - this.baseurl = sc.server; - this.apikey = sc.credentials.apikey; - - this.nodegroup = n.nodegroup || ""; - var node = this; - if (this.baseurl.substring(0,5) === "https") { var http = require("https"); } - else { var http = require("http"); } - this.on("input", function(msg) { - this.url = this.baseurl + '/input/post.json?'; - if(msg.payload.indexOf(':') > -1){ - this.url += 'json={' + msg.payload + '}'; - } else { - this.url += 'csv='+msg.payload; + RED.nodes.registerType("emoncms-server",EmoncmsServerNode,{ + credentials: { + apikey: {type:"text"} } - this.url += '&apikey='+this.apikey; - var nodegroup = this.nodegroup || msg.nodegroup; - if(nodegroup != ""){ - this.url += '&node=' + nodegroup; - } - if(typeof msg.time !== 'undefined'){ - this.url += '&time=' + msg.time; - } - node.log("[emoncms] "+this.url); - http.get(this.url, function(res) { - node.log("Http response: " + res.statusCode); - msg.rc = res.statusCode; - msg.payload = ""; - if ((msg.rc != 200) && (msg.rc != 404)) { - node.send(msg); - } - res.setEncoding('utf8'); - res.on('data', function(chunk) { - msg.payload += chunk; - }); - res.on('end', function() { - node.send(msg); - }); - }).on('error', function(e) { - // node.error(e); - msg.rc = 503; - msg.payload = e; - node.send(msg); - }); }); -} -RED.nodes.registerType("emoncms",Emoncms); + function Emoncms(n) { + RED.nodes.createNode(this,n); + this.emonServer = n.emonServer; + var sc = RED.nodes.getNode(this.emonServer); + + this.baseurl = sc.server; + this.apikey = sc.credentials.apikey; + + this.nodegroup = n.nodegroup || ""; + var node = this; + var http; + if (this.baseurl.substring(0,5) === "https") { http = require("https"); } + else { http = require("http"); } + this.on("input", function(msg) { + this.url = this.baseurl + '/input/post.json?'; + if(msg.payload.indexOf(':') > -1){ + this.url += 'json={' + msg.payload + '}'; + } else { + this.url += 'csv='+msg.payload; + } + this.url += '&apikey='+this.apikey; + var nodegroup = this.nodegroup || msg.nodegroup; + if(nodegroup !== ""){ + this.url += '&node=' + nodegroup; + } + if(typeof msg.time !== 'undefined'){ + this.url += '&time=' + msg.time; + } + node.log("[emoncms] "+this.url); + http.get(this.url, function(res) { + node.log("Http response: " + res.statusCode); + msg.rc = res.statusCode; + msg.payload = ""; + if ((msg.rc != 200) && (msg.rc != 404)) { + node.send(msg); + } + res.setEncoding('utf8'); + res.on('data', function(chunk) { + msg.payload += chunk; + }); + res.on('end', function() { + node.send(msg); + }); + }).on('error', function(e) { + // node.error(e); + msg.rc = 503; + msg.payload = e; + node.send(msg); + }); + }); + } + RED.nodes.registerType("emoncms",Emoncms); +} diff --git a/io/emoncms/package.json b/io/emoncms/package.json index 7c6dd87a..7526198e 100644 --- a/io/emoncms/package.json +++ b/io/emoncms/package.json @@ -1,6 +1,6 @@ { "name" : "node-red-node-emoncms", - "version" : "0.0.2", + "version" : "0.0.3", "description" : "A Node-RED node to send energy data to emoncms.org.", "dependencies" : { }, diff --git a/io/snmp/package.json b/io/snmp/package.json index bcafecfd..494ec0f5 100644 --- a/io/snmp/package.json +++ b/io/snmp/package.json @@ -1,6 +1,6 @@ { "name" : "node-red-node-snmp", - "version" : "0.0.1", + "version" : "0.0.2", "description" : "A Node-RED node that looks for SNMP oids.", "dependencies" : { "net-snmp" : "1.1.13" diff --git a/io/snmp/snmp.js b/io/snmp/snmp.js index 03a3e504..a821cb8b 100644 --- a/io/snmp/snmp.js +++ b/io/snmp/snmp.js @@ -15,6 +15,7 @@ **/ module.exports = function(RED) { + "use strict"; var snmp = require ("net-snmp"); function SnmpNode(n) { @@ -67,9 +68,9 @@ module.exports = function(RED) { var maxRepetitions = 20; function sortInt (a, b) { - if (a > b) return 1; - else if (b > a) return -1; - else return 0; + if (a > b) { return 1; } + else if (b > a) { return -1; } + else { return 0; } } function responseCb (error, table) { @@ -77,11 +78,19 @@ module.exports = function(RED) { console.error (error.toString ()); } else { var indexes = []; - for (index in table) { indexes.push (parseInt (index)); } + for (var index in table) { + if (table.hasOwnProperty(index)) { + indexes.push (parseInt (index)); + } + } indexes.sort (sortInt); for (var i = 0; i < indexes.length; i++) { var columns = []; - for (column in table[indexes[i]]) { columns.push(parseInt (column)); } + for (var column in table[indexes[i]]) { + if (table[indexes[i]].hasOwnProperty(column)) { + columns.push(parseInt (column)); + } + } columns.sort(sortInt); console.log ("row index = " + indexes[i]); for (var j = 0; j < columns.length; j++) { diff --git a/parsers/geohash/70-geohash.js b/parsers/geohash/70-geohash.js index 24fd95da..1aa1ba25 100644 --- a/parsers/geohash/70-geohash.js +++ b/parsers/geohash/70-geohash.js @@ -36,13 +36,13 @@ module.exports = function(RED) { node.send(msg); } else { - var lat = msg.location.lat; - var lon = msg.location.lon; - var len = parseInt(msg.location.precision || msg.location.payload || 9); - if (len < 1) { len = 1; } - if (len > 9) { len = 9; } - if (lat && lon) { - msg.location.geohash = geohash.encode(lat, lon, len); + var lt = msg.location.lat; + var ln = msg.location.lon; + var le = parseInt(msg.location.precision || msg.location.payload || 9); + if (le < 1) { le = 1; } + if (le > 9) { le = 9; } + if (lt && ln) { + msg.location.geohash = geohash.encode(lt, ln, le); node.send(msg); } } @@ -51,9 +51,9 @@ module.exports = function(RED) { // try to decode it... var regexp = new RegExp('^[a-z0-9]{1,9}$'); // can only contain a-z or 0-9 and length 1-9 if (regexp.test(msg.payload)) { - var pos = geohash.decode(msg.payload); - msg.payload = { lat:round(pos.latitude,5), lon:round(pos.longitude,5) }; - msg.payload.error = { lat:round(pos.error.latitude,5), lon:round(pos.error.longitude,5) }; + var po = geohash.decode(msg.payload); + msg.payload = { lat:round(po.latitude,5), lon:round(po.longitude,5) }; + msg.payload.error = { lat:round(po.error.latitude,5), lon:round(po.error.longitude,5) }; node.send(msg); } else if (msg.payload.indexOf(",") !== -1) { diff --git a/parsers/geohash/package.json b/parsers/geohash/package.json index 94ccc4a5..8bc8ff60 100644 --- a/parsers/geohash/package.json +++ b/parsers/geohash/package.json @@ -1,6 +1,6 @@ { "name" : "node-red-node-geohash", - "version" : "0.0.2", + "version" : "0.0.3", "description" : "A Node-RED node to encode and decode lat,lon pairs to a geohash.", "dependencies" : { "ngeohash" : "0.6.0" diff --git a/social/pushbullet/57-pushbullet.js b/social/pushbullet/57-pushbullet.js index c0303517..030a1146 100644 --- a/social/pushbullet/57-pushbullet.js +++ b/social/pushbullet/57-pushbullet.js @@ -105,7 +105,7 @@ module.exports = function(RED) { apikey: {type: "password"} } }); - + PushbulletConfig.prototype.onConfig = function(type, cb) { this.emitter.on(type, cb); } @@ -120,7 +120,7 @@ module.exports = function(RED) { } else if(res.type === 'push') { self.pushMsg(res.push); - } + } }); stream.on('connect', function() { self.emitter.emit('stream_connected'); @@ -143,7 +143,7 @@ module.exports = function(RED) { this.last = when.promise(function(resolve) { when(lastprom).then(function(last) { self.pusher.history({modified_after: last}, function(err, res) { - if(err) { + if(err) { resolve(last); return onError(err); } @@ -155,8 +155,8 @@ module.exports = function(RED) { } catch(ex) { resolve(last); } - }); - }); + }); + }); }); } }; @@ -246,18 +246,18 @@ module.exports = function(RED) { var cred = RED.nodes.getCredentials(n.id); // get old apikey - if(cred && cred.hasOwnProperty("pushkey")) { - apikey = cred.pushkey; + if(cred && cred.hasOwnProperty("pushkey")) { + apikey = cred.pushkey; } else if(pushkeys) { apikey = pushkeys.pushbullet; } // get old device - if (cred && cred.hasOwnProperty("deviceid")) { - deviceid = cred.deviceid; + if (cred && cred.hasOwnProperty("deviceid")) { + deviceid = cred.deviceid; } - else if (pushkeys) { - deviceid = pushkeys.deviceid; + else if (pushkeys) { + deviceid = pushkeys.deviceid; } if(apikey) { @@ -268,7 +268,7 @@ module.exports = function(RED) { name: n.name, _migrate: true, _apikey: apikey, - }); + }); } if(!(apikey || deviceid)) { @@ -285,7 +285,7 @@ module.exports = function(RED) { id: newid }; } - return false; + return false; } function PushbulletOut(n) { @@ -308,7 +308,7 @@ module.exports = function(RED) { else { this.status({}); configNode = RED.nodes.getNode(n.config); - try { + try { this.deviceid = this.credentials.deviceid; } catch(err){} @@ -331,17 +331,17 @@ module.exports = function(RED) { msg.payload = JSON.stringify(msg.payload); } else if(msg.payload) { - msg.payload = msg.payload.toString(); - } + msg.payload = msg.payload.toString(); + } if(['delete', 'dismissal', 'updatelist', '_rawupdate_'].indexOf(pushtype) === -1) { if (channel) { deviceid = { channel_tag : channel }; - } + } else if(deviceid === "") { try { when(configNode.me).then(function(me) { - deviceid = me.email; + deviceid = me.email; self.pushMsg(pushtype, deviceid, title, msg); }); return; @@ -351,8 +351,8 @@ module.exports = function(RED) { } } else if (!isNaN(deviceid)) { - deviceid = Number(deviceid); - } + deviceid = Number(deviceid); + } } self.pushMsg(pushtype, deviceid, title, msg); }); @@ -367,18 +367,18 @@ module.exports = function(RED) { PushbulletOut.prototype.pushMsg = function(pushtype, deviceid, title, msg) { var self = this; if (this.pusher) { - var handleErr = function(msg){ + var handleErr = function(msg){ return function(err) { if(err) { self.error(msg); - onError(err, self); + onError(err, self); } } } if(deviceid) { if(pushtype === 'note') { - this.pusher.note(deviceid, title, msg.payload, handleErr('Unable to push note')); + this.pusher.note(deviceid, title, msg.payload, handleErr('Unable to push note')); } else if(pushtype === 'address') { this.pusher.address(deviceid, title, msg.payload, handleErr('Unable to push address')); @@ -391,7 +391,7 @@ module.exports = function(RED) { type: 'link', title: title, body: msg.message, - url: msg.payload + url: msg.payload }, handleErr('Unable to push link')); } else if(pushtype === 'file') { @@ -407,7 +407,7 @@ module.exports = function(RED) { this.pusher.push(deviceid, msg.raw, handleErr('Unable to push raw data')); } } - + if(msg.data && msg.data.iden) { if(pushtype === 'delete') { this.pusher.deletePush(msg.data.iden, handleErr('Unable to delete push')); @@ -461,6 +461,7 @@ module.exports = function(RED) { RED.httpAdmin.get('/pushbullet/:id/devices', function(req, res) { var config = RED.nodes.getNode(req.params.id); var cred = RED.nodes.getCredentials(req.params.id); + var pb; if(config && config.pusher) { config.pusher.devices(function(err, chans) { @@ -469,27 +470,27 @@ module.exports = function(RED) { return onError(err, config); } res.send(JSON.stringify(chans.devices)); - }); + }); } else if(cred && cred.apikey) { - var pb = new PushBullet(cred.apikey); + pb = new PushBullet(cred.apikey); pb.devices(function(err, chans) { if(err) { res.send("[]"); return onError(err, config); } res.send(JSON.stringify(chans.devices)); - }); + }); } else if(req.query.apikey) { - var pb = new PushBullet(req.query.apikey); + pb = new PushBullet(req.query.apikey); pb.devices(function(err, chans) { if(err) { res.send("[]"); return onError(err, config); } res.send(JSON.stringify(chans.devices)); - }); + }); } else { res.send("[]"); @@ -522,11 +523,11 @@ module.exports = function(RED) { filters: {value: []} } }); - + PushbulletIn.prototype.emitPush = function(msg) { try { if(this.credentials.filters.length > 0) { - if( (this.credentials.filters.indexOf(msg.data.source_device_iden) > -1) || + if( (this.credentials.filters.indexOf(msg.data.source_device_iden) > -1) || (this.credentials.filters.indexOf(msg.data.target_device_iden) > -1) || (!msg.data.target_device_iden && !msg.data.source_device_iden)) { /* All */ this.send(msg); diff --git a/test/function/rbe/rbe_spec.js b/test/function/rbe/rbe_spec.js new file mode 100644 index 00000000..9a885b52 --- /dev/null +++ b/test/function/rbe/rbe_spec.js @@ -0,0 +1,131 @@ +/** + * Copyright 2015 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + **/ + +var should = require("should"); +var helper = require('../../../test/helper.js'); +var testNode = require('../../../function/rbe/rbe.js'); + +describe('rbe node', function() { + "use strict"; + + beforeEach(function(done) { + helper.startServer(done); + }); + + afterEach(function(done) { + helper.unload().then(function() { + helper.stopServer(done); + }); + }); + + it("should be loaded with correct defaults", function(done) { + var flow = [{"id":"n1", "type":"rbe", "name":"rbe1", "wires":[[]]}]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + n1.should.have.property("name", "rbe1"); + n1.should.have.property("func", "rbe"); + n1.should.have.property("gap", 0); + done(); + }); + }); + + it('should only send output if payload changes', function(done) { + var flow = [{"id":"n1", "type":"rbe", func:"rbe", gap:0, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + if (c === 0) { + msg.should.have.a.property("payload", "a"); + c+=1; + } + else { + msg.should.have.a.property("payload", "b"); + done(); + } + }); + n1.emit("input", {payload:"a"}); + n1.emit("input", {payload:"a"}); + n1.emit("input", {payload:"a"}); + n1.emit("input", {payload:"a"}); + n1.emit("input", {payload:"a"}); + n1.emit("input", {payload:"b"}); + n1.emit("input", {payload:"b"}); + }); + }); + + it('should only send output if more than x away from original value', function(done) { + var flow = [{"id":"n1", "type":"rbe", func:"gap", gap:10, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + if (c === 0) { + msg.should.have.a.property("payload", 0); + } + else if (c === 1) { + msg.should.have.a.property("payload", 20); + } + else { + msg.should.have.a.property("payload", "5 deg"); + done(); + } + c += 1; + }); + n1.emit("input", {payload:0}); + n1.emit("input", {payload:2}); + n1.emit("input", {payload:4}); + n1.emit("input", {payload:"6 deg"}); + n1.emit("input", {payload:8}); + n1.emit("input", {payload:20}); + n1.emit("input", {payload:15}); + n1.emit("input", {payload:"5 deg"}); + }); + }); + + it('should warn if no number found in gap mode', function(done) { + var flow = [{"id":"n1", "type":"rbe", func:"gap", gap:10, wires:[["n2"]] }, + {id:"n2", type:"helper"} ]; + helper.load(testNode, flow, function() { + var n1 = helper.getNode("n1"); + var n2 = helper.getNode("n2"); + var c = 0; + n2.on("input", function(msg) { + c += 1; + }); + setTimeout( function() { + c.should.equal(0); + helper.log().called.should.be.true; + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "rbe"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().WARN); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'rbe'); + msg.should.have.property('msg', 'no number found in payload'); + done(); + },50); + n1.emit("input", {payload:"banana"}); + }); + }); + +}); diff --git a/test/social/pushbullet/57-pushbullet_spec.js b/test/social/pushbullet/57-pushbullet_spec.js index fe80ca9a..c6c7a634 100644 --- a/test/social/pushbullet/57-pushbullet_spec.js +++ b/test/social/pushbullet/57-pushbullet_spec.js @@ -605,179 +605,178 @@ describe('pushbullet node', function() { done(); }); }); + }); - describe('tickle', function() { - it('note', function(done) { - var flow = [{id:"n1", type:"pushbullet-config"}, - {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, - {id:"n3", type:"helper"}]; + describe('tickle', function() { + it('note', function(done) { + var flow = [{id:"n1", type:"pushbullet-config"}, + {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, + {id:"n3", type:"helper"}]; - helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { - helper.getNode("n3").on("input", function(msg) { - msg.should.have.property("pushtype", "note"); - msg.should.have.property("payload", "body"); - msg.should.have.property("topic", "title"); - msg.should.have.property("data"); - done(); - }); - var func = sinon.stub(currentPB, "history"); - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - func.yields(false, getPushReply('note')); + helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("pushtype", "note"); + msg.should.have.property("payload", "body"); + msg.should.have.property("topic", "title"); + msg.should.have.property("data"); + done(); }); + var func = sinon.stub(currentPB, "history"); + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + func.yields(false, getPushReply('note')); }); + }); - it('link', function(done) { - var flow = [{id:"n1", type:"pushbullet-config"}, - {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, - {id:"n3", type:"helper"}]; + it('link', function(done) { + var flow = [{id:"n1", type:"pushbullet-config"}, + {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, + {id:"n3", type:"helper"}]; - helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { - helper.getNode("n3").on("input", function(msg) { - msg.should.have.property("pushtype", "link"); - msg.should.have.property("payload", "url"); - msg.should.have.property("topic", "title"); - msg.should.have.property("data"); - done(); - }); - var func = sinon.stub(currentPB, "history"); - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - func.yields(false, getPushReply('link')); + helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("pushtype", "link"); + msg.should.have.property("payload", "url"); + msg.should.have.property("topic", "title"); + msg.should.have.property("data"); + done(); }); + var func = sinon.stub(currentPB, "history"); + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + func.yields(false, getPushReply('link')); }); + }); - it('address', function(done) { - var flow = [{id:"n1", type:"pushbullet-config"}, - {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, - {id:"n3", type:"helper"}]; + it('address', function(done) { + var flow = [{id:"n1", type:"pushbullet-config"}, + {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, + {id:"n3", type:"helper"}]; - helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { - helper.getNode("n3").on("input", function(msg) { - msg.should.have.property("pushtype", "address"); - msg.should.have.property("payload", "address"); - msg.should.have.property("topic", "title"); - msg.should.have.property("data"); - done(); - }); - var func = sinon.stub(currentPB, "history"); - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - func.yields(false, getPushReply('address')); + helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("pushtype", "address"); + msg.should.have.property("payload", "address"); + msg.should.have.property("topic", "title"); + msg.should.have.property("data"); + done(); }); + var func = sinon.stub(currentPB, "history"); + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + func.yields(false, getPushReply('address')); }); + }); - it('file', function(done) { - var flow = [{id:"n1", type:"pushbullet-config"}, - {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, - {id:"n3", type:"helper"}]; + it('file', function(done) { + var flow = [{id:"n1", type:"pushbullet-config"}, + {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, + {id:"n3", type:"helper"}]; - helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { - helper.getNode("n3").on("input", function(msg) { - msg.should.have.property("pushtype", "file"); - msg.should.have.property("payload", "fileurl"); - msg.should.have.property("topic", "filename"); - msg.should.have.property("data"); - done(); - }); - var func = sinon.stub(currentPB, "history"); - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - func.yields(false, getPushReply('file')); + helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("pushtype", "file"); + msg.should.have.property("payload", "fileurl"); + msg.should.have.property("topic", "filename"); + msg.should.have.property("data"); + done(); }); + var func = sinon.stub(currentPB, "history"); + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + func.yields(false, getPushReply('file')); }); + }); - it('list', function(done) { - var flow = [{id:"n1", type:"pushbullet-config"}, - {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, - {id:"n3", type:"helper"}]; + it('list', function(done) { + var flow = [{id:"n1", type:"pushbullet-config"}, + {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, + {id:"n3", type:"helper"}]; - helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { - helper.getNode("n3").on("input", function(msg) { - msg.should.have.property("pushtype", "list"); - msg.should.have.property("topic", "title"); - msg.should.have.property("payload").with.length(3); - msg.should.have.property("data"); - done(); - }); - var func = sinon.stub(currentPB, "history"); - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - func.yields(false, getPushReply('list')); + helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("pushtype", "list"); + msg.should.have.property("topic", "title"); + msg.should.have.property("payload").with.length(3); + msg.should.have.property("data"); + done(); }); + var func = sinon.stub(currentPB, "history"); + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + func.yields(false, getPushReply('list')); }); + }); - it('delete', function(done) { - var flow = [{id:"n1", type:"pushbullet-config"}, - {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, - {id:"n3", type:"helper"}]; + it('delete', function(done) { + var flow = [{id:"n1", type:"pushbullet-config"}, + {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, + {id:"n3", type:"helper"}]; - helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { - helper.getNode("n3").on("input", function(msg) { - msg.should.have.property("pushtype", "delete"); - msg.should.have.property("payload", "pjgzwwocCCy"); - msg.should.have.property("data"); - done(); - }); - var func = sinon.stub(currentPB, "history"); - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - func.yields(false, getPushReply('delete')); + helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("pushtype", "delete"); + msg.should.have.property("payload", "pjgzwwocCCy"); + msg.should.have.property("data"); + done(); }); + var func = sinon.stub(currentPB, "history"); + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + func.yields(false, getPushReply('delete')); }); + }); - it('dismissed', function(done) { - var flow = [{id:"n1", type:"pushbullet-config"}, - {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, - {id:"n3", type:"helper"}]; + it('dismissed', function(done) { + var flow = [{id:"n1", type:"pushbullet-config"}, + {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, + {id:"n3", type:"helper"}]; - helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { - helper.getNode("n3").on("input", function(msg) { - msg.should.have.property("pushtype", "dismissal"); - msg.should.have.property("payload", "xXxXxXxXxXxsjArqXRsaZM"); - msg.should.have.property("data"); - done(); - }); - var func = sinon.stub(currentPB, "history"); - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - var rep = getPushReply('note'); - rep.pushes[0].dismissed = true; - func.yields(false, rep); + helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}}, function() { + helper.getNode("n3").on("input", function(msg) { + msg.should.have.property("pushtype", "dismissal"); + msg.should.have.property("payload", "xXxXxXxXxXxsjArqXRsaZM"); + msg.should.have.property("data"); + done(); }); + var func = sinon.stub(currentPB, "history"); + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + var rep = getPushReply('note'); + rep.pushes[0].dismissed = true; + func.yields(false, rep); }); + }); - it('filter', function(done) { - var flow = [{id:"n1", type:"pushbullet-config"}, - {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, - {id:"n3", type:"helper"}]; + it('filter', function(done) { + var flow = [{id:"n1", type:"pushbullet-config"}, + {id:"n2", type:"pushbullet in", config: "n1", wires: [["n3"]]}, + {id:"n3", type:"helper"}]; - helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}, n2:{filters:['a', 'b']}}, function() { - var counter = sinon.spy(); - helper.getNode("n3").on("input", function(msg) { - counter(); - }); - - var func = sinon.stub(currentPB, "history"); - - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - var msg0 = getPushReply('link'); msg0.pushes[0].source_device_iden = 'a'; - func.onCall(0).yields(false, msg0); - - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - var msg1 = getPushReply('link'); msg1.pushes[0].source_device_iden = 'b'; - func.onCall(1).yields(false, msg1); - - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - var msg2 = getPushReply('link'); msg2.pushes[0].source_device_iden = 'c'; - func.onCall(2).yields(false, msg2); - - currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); - var msg3 = getPushReply('link'); - delete msg3.pushes[0].source_device_iden; - delete msg3.pushes[0].target_device_iden; - func.onCall(3).yields(false, msg3); - - setTimeout(function() { - counter.callCount.should.equal(3); - done(); - }, 100); + helper.load(pushbulletNode, flow, {n1:{apikey:"invalid"}, n2:{filters:['a', 'b']}}, function() { + var counter = sinon.spy(); + helper.getNode("n3").on("input", function(msg) { + counter(); }); - }); + var func = sinon.stub(currentPB, "history"); + + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + var msg0 = getPushReply('link'); msg0.pushes[0].source_device_iden = 'a'; + func.onCall(0).yields(false, msg0); + + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + var msg1 = getPushReply('link'); msg1.pushes[0].source_device_iden = 'b'; + func.onCall(1).yields(false, msg1); + + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + var msg2 = getPushReply('link'); msg2.pushes[0].source_device_iden = 'c'; + func.onCall(2).yields(false, msg2); + + currentPB.streamEmitter.emit("message", {type: "tickle", subtype: "push"}); + var msg3 = getPushReply('link'); + delete msg3.pushes[0].source_device_iden; + delete msg3.pushes[0].target_device_iden; + func.onCall(3).yields(false, msg3); + + setTimeout(function() { + counter.callCount.should.equal(3); + done(); + }, 100); + }); }); }); });