diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..c8f50f7c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +npm-debug.log diff --git a/99-sample.html.demo b/99-sample.html.demo index e26197aa..06092b03 100644 --- a/99-sample.html.demo +++ b/99-sample.html.demo @@ -1,5 +1,5 @@ - +
{led:3,state:0}
to set LED3 off.
+
+Requires the WiringPi gpio command in order to work.
diff --git a/hardware/PiLiter/package.json b/hardware/PiLiter/package.json
new file mode 100644
index 00000000..d30df82d
--- /dev/null
+++ b/hardware/PiLiter/package.json
@@ -0,0 +1,23 @@
+{
+ "name" : "node-red-node-piliter",
+ "version" : "0.0.3",
+ "description" : "A Node-RED node to drive a Raspberry Pi Pi-LITEr 8 LED board.",
+ "dependencies" : {
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/hardware/PiLiter"
+ },
+ "license": "Apache",
+ "keywords": [ "node-red", "piliter" ],
+ "node-red" : {
+ "nodes" : {
+ "rpi-piliter": "39-rpi-piliter.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/hardware/Pi/38-rpi-pibrella.html b/hardware/Pibrella/38-rpi-pibrella.html
similarity index 60%
rename from hardware/Pi/38-rpi-pibrella.html
rename to hardware/Pibrella/38-rpi-pibrella.html
index ffbe3ac8..c5ea4adf 100644
--- a/hardware/Pi/38-rpi-pibrella.html
+++ b/hardware/Pibrella/38-rpi-pibrella.html
@@ -16,9 +16,9 @@
@@ -41,11 +47,12 @@
diff --git a/hardware/Pibrella/38-rpi-pibrella.js b/hardware/Pibrella/38-rpi-pibrella.js
new file mode 100644
index 00000000..1ee55643
--- /dev/null
+++ b/hardware/Pibrella/38-rpi-pibrella.js
@@ -0,0 +1,181 @@
+/**
+ * Copyright 2014 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.
+ **/
+
+module.exports = function(RED) {
+ "use strict";
+ var util = require("util");
+ var exec = require('child_process').exec;
+ var fs = require('fs');
+
+ if (!fs.existsSync("/dev/ttyAMA0")) { // unlikely if not on a Pi
+ throw "Info : Ignoring Raspberry Pi specific node.";
+ }
+
+ if (!fs.existsSync("/usr/local/bin/gpio")) { // gpio command not installed
+ throw "Info : Can't find Raspberry Pi wiringPi gpio command.";
+ }
+
+ // Map physical P1 pins to Gordon's Wiring-Pi Pins (as they should be V1/V2 tolerant)
+ var pintable = {
+ // Physical : WiringPi
+ "Amber LED":"0",
+ "Buzzer ":"1",
+ "Red LED":"2",
+ "Out E":"3",
+ "Out F":"4",
+ "Out G":"5",
+ "Out H":"6",
+ "Green LED":"7",
+ "In C":"10",
+ "In B":"11",
+ "In D":"12",
+ "In A":"13",
+ "Red Button":"14",
+ }
+ var tablepin = {
+ // WiringPi : Physical
+ "0":"Amber",
+ "1":"Buzzer",
+ "2":"Red",
+ "3":"E",
+ "4":"F",
+ "5":"G",
+ "6":"H",
+ "7":"Green",
+ "10":"C",
+ "11":"B",
+ "12":"D",
+ "13":"A",
+ "14":"R",
+ }
+
+ function PibrellaIn(n) {
+ RED.nodes.createNode(this,n);
+ this.buttonState = -1;
+ this.pin = pintable[n.pin];
+ this.read = n.read || false;
+ if (this.read) { this.buttonState = -2; }
+ var node = this;
+
+ if (node.pin) {
+ exec("gpio mode "+node.pin+" in", function(err,stdout,stderr) {
+ if (err) { node.error(err); }
+ else {
+ node._interval = setInterval( function() {
+ exec("gpio read "+node.pin, function(err,stdout,stderr) {
+ if (err) { node.error(err); }
+ else {
+ if (node.buttonState !== Number(stdout)) {
+ var previousState = node.buttonState;
+ node.buttonState = Number(stdout);
+ if (previousState !== -1) {
+ var msg = {topic:"pibrella/"+tablepin[node.pin], payload:node.buttonState};
+ node.send(msg);
+ }
+ }
+ }
+ });
+ }, 200);
+ }
+ });
+ }
+ else {
+ node.error("Invalid GPIO pin: "+node.pin);
+ }
+
+ node.on("close", function() {
+ clearInterval(node._interval);
+ });
+ }
+
+ function PibrellaOut(n) {
+ RED.nodes.createNode(this,n);
+ this.pin = pintable[n.pin];
+ this.set = n.set || false;
+ this.level = n.level || 0;
+ var node = this;
+
+ if (node.pin == "1") {
+ exec("gpio mode 1 pwm");
+ process.nextTick(function() {
+ exec("gpio pwm-ms");
+ node.on("input", function(msg) {
+ var out = Number(msg.payload);
+ if (out == 1) { // fixed buzz
+ exec("gpio pwm 1 511");
+ exec("gpio pwmc 100");
+ }
+ else if ((out >= 2) && (out <= 9999)) { // set buzz to a value
+ exec("gpio pwm 1 511");
+ exec("gpio pwmc "+out);
+ }
+ else { exec("gpio pwm 1 0"); } // turn it off
+ });
+ });
+ }
+ else if (node.pin) {
+ exec("gpio mode "+node.pin+" out", function(err,stdout,stderr) {
+ if (err) { node.error(err); }
+ else {
+ if (node.set) {
+ exec("gpio write "+node.pin+" "+node.level, function(err,stdout,stderr) {
+ if (err) { node.error(err); }
+ });
+ }
+ node.on("input", function(msg) {
+ if (msg.payload === "true") { msg.payload = true; }
+ if (msg.payload === "false") { msg.payload = false; }
+ var out = Number(msg.payload);
+ if ((out === 0)|(out === 1)) {
+ exec("gpio write "+node.pin+" "+out, function(err,stdout,stderr) {
+ if (err) { node.error(err); }
+ });
+ }
+ else { node.warn("Invalid input - not 0 or 1"); }
+ });
+ }
+ });
+ }
+ else {
+ node.error("Invalid GPIO pin: "+node.pin);
+ }
+
+ node.on("close", function() {
+ exec("gpio mode "+node.pin+" in");
+ });
+ }
+
+ //exec("gpio mode 0 out",function(err,stdout,stderr) {
+ //if (err) {
+ //util.log('[36-rpi-gpio.js] Error: "gpio" command failed for some reason.');
+ //}
+ //exec("gpio mode 1 out");
+ //exec("gpio mode 2 out");
+ //exec("gpio mode 3 out");
+ //exec("gpio mode 4 out");
+ //exec("gpio mode 5 out");
+ //exec("gpio mode 6 out");
+ //exec("gpio mode 7 out");
+ //exec("gpio mode 10 in");
+ //exec("gpio mode 11 in");
+ //exec("gpio mode 12 in");
+ //exec("gpio mode 13 in");
+ //exec("gpio mode 14 in");
+ //});
+
+ RED.nodes.registerType("rpi-pibrella in",PibrellaIn);
+ RED.nodes.registerType("rpi-pibrella out",PibrellaOut);
+}
diff --git a/hardware/Pibrella/LICENSE b/hardware/Pibrella/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/hardware/Pibrella/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/hardware/Pibrella/README.md b/hardware/Pibrella/README.md
new file mode 100644
index 00000000..2004ef96
--- /dev/null
+++ b/hardware/Pibrella/README.md
@@ -0,0 +1,38 @@
+node-red-node-pibrella
+======================
+A Node-RED node to control a Pibrella add-on board for a Raspberry-Pi.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-pibrella
+
+
+Pre-reqs
+--------
+
+Requires the WiringPi gpio command to be installed in order to work. See the WiringPi site for details on how to do this.
+
+
+Usage
+-----
+
+A pair of input and output Node-RED nodes for the Raspberry Pi Pibrella from Pimoroni.
+
+###Output
+
+The output node will set the selected output high (on) or low (off) depending on the value passed in. Expects a msg.payload with either a 0 or 1 (or true or false).
+
+The Buzzer is a divider so low numbers are high notes. 0 is off, and the sensible lowest note is around 250-300. 2 is the highest note. 1 is just a buzz - so you can use 0/1 type inputs.
+
+**Note:** Using the buzzer is known to "kill" audio output via the 3.5mm socket.
+
+###Input
+
+The input node generates a msg.payload with either a 0 or 1 depending on the state of the input pin.
+
+The msg.topic is set to pibrella/{the pin id} - which will be A, B, C, D or R.
+
+Note: This node currently polls the pin every 250mS. This is not ideal as it loads the cpu.
diff --git a/hardware/Pibrella/package.json b/hardware/Pibrella/package.json
new file mode 100644
index 00000000..0345e00f
--- /dev/null
+++ b/hardware/Pibrella/package.json
@@ -0,0 +1,23 @@
+{
+ "name" : "node-red-node-pibrella",
+ "version" : "0.0.4",
+ "description" : "A Node-RED node to read from and write to a Pibrella Raspberry Pi add-on board",
+ "dependencies" : {
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/hardware/Pibrella"
+ },
+ "license": "Apache",
+ "keywords": [ "node-red", "pibrella" ],
+ "node-red" : {
+ "nodes" : {
+ "pibrella": "38-rpi-pibrella.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/hardware/blink/76-blinkstick.html b/hardware/blink/76-blinkstick.html
deleted file mode 100644
index 1bef4306..00000000
--- a/hardware/blink/76-blinkstick.html
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
-
diff --git a/hardware/blink/76-blinkstick.js b/hardware/blink/76-blinkstick.js
deleted file mode 100644
index ebbdacc7..00000000
--- a/hardware/blink/76-blinkstick.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Copyright 2013 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 RED = require(process.env.NODE_RED_HOME+"/red/red");
-var blinkstick = require("blinkstick");
-
-Object.size = function(obj) {
- var size = 0, key;
- for (key in obj) { if (obj.hasOwnProperty(key)) size++; }
- return size;
-};
-
-function BlinkStick(n) {
- RED.nodes.createNode(this,n);
- var p1 = /^\#[A-Fa-f0-9]{6}$/
- var p2 = /[0-9]+,[0-9]+,[0-9]+/
- this.led = blinkstick.findFirst(); // maybe try findAll() (one day)
- var node = this;
-
- this.on("input", function(msg) {
- if (msg != null) {
- if (Object.size(node.led) !== 0) {
- try {
- if (p2.test(msg.payload)) {
- var rgb = msg.payload.split(",");
- node.led.setColor(parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255);
- }
- else {
- node.led.setColor(msg.payload.toLowerCase().replace(/\s+/g,''));
- }
- }
- catch (err) {
- node.warn("BlinkStick missing ?");
- node.led = blinkstick.findFirst();
- }
- }
- else {
- //node.warn("No BlinkStick found");
- node.led = blinkstick.findFirst();
- }
- }
- });
- if (Object.size(node.led) === 0) {
- node.error("No BlinkStick found");
- }
-
-}
-
-RED.nodes.registerType("blinkstick",BlinkStick);
diff --git a/hardware/blink/77-blink1.js b/hardware/blink/77-blink1.js
deleted file mode 100644
index 474164d9..00000000
--- a/hardware/blink/77-blink1.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * Copyright 2013 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 RED = require(process.env.NODE_RED_HOME+"/red/red");
-var Blink1 = require("node-blink1");
-// create a single global blink1 object
-// all blink1 nodes affect the same (single) led
-var blink1 = null;
-
-function Blink1Node(n) {
- RED.nodes.createNode(this,n);
- this.fade = Number(n.fade) || 0;
- var node = this;
-
- try {
- var p1 = /^\#[A-Fa-f0-9]{6}$/
- var p2 = /[0-9]+,[0-9]+,[0-9]+/
- this.on("input", function(msg) {
- blink1 = blink1 || new Blink1.Blink1();
- if (blink1) {
- try {
- if (p1.test(msg.payload)) {
- // if it is a hex colour string
- var r = parseInt(msg.payload.slice(1,3),16);
- var g = parseInt(msg.payload.slice(3,5),16);
- var b = parseInt(msg.payload.slice(5),16);
- if (node.fade == 0) { blink1.setRGB( r, g, b ); }
- else { blink1.fadeToRGB(node.fade, r, g, b ); }
- }
- else if (p2.test(msg.payload)) {
- // if it is a r,g,b triple
- var rgb = msg.payload.split(',');
- if (node.fade == 0) { blink1.setRGB(parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255); }
- else { blink1.fadeToRGB(node.fade, parseInt(rgb[0])&255, parseInt(rgb[1])&255, parseInt(rgb[2])&255); }
- }
- else {
- // you can add fancy colours by name here if you want...
- // these are the @cheerlight ones.
- var colors = {"red":"#FF0000","green":"#008000","blue":"#0000FF","cyan":"#00FFFF","white":"#FFFFFF","warmwhite":"#FDF5E6",
- "purple":"#800080","magenta":"#FF00FF","yellow":"#FFFF00","amber":"#FFD200","orange":"#FFA500","black":"#000000"}
- if (msg.payload.toLowerCase() in colors) {
- var c = colors[msg.payload.toLowerCase()];
- var r = parseInt(c.slice(1,3),16);
- var g = parseInt(c.slice(3,5),16);
- var b = parseInt(c.slice(5),16);
- if (node.fade == 0) { blink1.setRGB( r, g, b ); }
- else { blink1.fadeToRGB(node.fade, r, g, b ); }
- }
- else {
- node.warn("Blink1 : invalid msg : "+msg.payload);
- }
- }
- } catch (e) { node.warn("Blink1 : error"); blink1 = null; }
- }
- else {
- node.warn("Blink1 : not found");
- }
- });
- this.on("close", function() {
- if (blink1 && typeof blink1.close == "function") {
- //blink1.close(); //This ought to work but seems to cause more hangs on closing than not...
- }
- blink1 = null;
- });
- }
- catch(e) {
- node.error("No Blink1 found (" + e + ")");
- }
-}
-RED.nodes.registerType("blink1",Blink1Node);
diff --git a/hardware/blink/77-blink1.html b/hardware/blink1/77-blink1.html
similarity index 88%
rename from hardware/blink/77-blink1.html
rename to hardware/blink1/77-blink1.html
index 14efa87a..48a40b6a 100644
--- a/hardware/blink/77-blink1.html
+++ b/hardware/blink1/77-blink1.html
@@ -16,11 +16,11 @@
@@ -28,6 +28,7 @@
+
+
+
+
diff --git a/hardware/blinkstick/76-blinkstick.js b/hardware/blinkstick/76-blinkstick.js
new file mode 100644
index 00000000..54c1485e
--- /dev/null
+++ b/hardware/blinkstick/76-blinkstick.js
@@ -0,0 +1,258 @@
+/**
+ * Copyright 2013-2014 Agile Innovative Ltd.
+ * Based on code written by Dave Conway-Jones, 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.
+ **/
+
+module.exports = function(RED) {
+ "use strict";
+ var blinkstick = require("blinkstick");
+
+ var availableTasks = ["set_color", "blink", "pulse", "morph"];
+
+ Object.size = function(obj) {
+ var size = 0;
+ for (var key in obj) { if (obj.hasOwnProperty(key)) { size++; } }
+ return size;
+ };
+
+ //Helper function to convert decimal number to hex with padding
+ function decimalToHex(d, padding) {
+ var hex = Number(d).toString(16);
+ padding = typeof (padding) === "undefined" || padding === null ? padding = 2 : padding;
+
+ while (hex.length < padding) {
+ hex = "0" + hex;
+ }
+
+ return hex;
+ }
+
+ function validateInt(value, defaultValue) {
+ return typeof (value) === "undefined" || value === null ? value = defaultValue : parseInt(value);
+ }
+
+ function validate(value, defaultValue) {
+ return typeof (value) === "undefined" || value === null ? value = defaultValue : value;
+ }
+
+ function validatePayloadObject (obj) {
+ var
+ task = validate(obj.task),
+ delay = validateInt(obj.delay),
+ repeats = validateInt(obj.repeats),
+ duration = validateInt(obj.duration),
+ steps = validateInt(obj.steps),
+ repeat = validate(obj.repeat),
+ color = validate(obj.color);
+
+ if (typeof(task) !== 'undefined' && availableTasks.indexOf(task) === -1) {
+ return "Task is invalid";
+ }
+
+ if (typeof(color) === 'undefined') {
+ return "Color parameter is not set";
+ }
+
+ return { 'task': task, 'delay': delay, 'repeats': repeats, 'duration': duration, 'steps': steps,
+ 'repeat': repeat, 'color': color };
+ }
+
+ function BlinkStick(n) {
+ RED.nodes.createNode(this,n);
+
+ this.name = n.name;
+ this.serial = n.serial;
+ this.task = n.task || "set_color";
+ this.delay = n.delay || 500;
+ this.repeats = n.repeats || 1;
+ this.duration = n.duration || 1000;
+ this.steps = n.steps || 50;
+ this.repeat = n.repeat;
+ this.closing = false;
+ this.color = '';
+ this.previousColor = '';
+
+ var p1 = /[0-9]+,[0-9]+,[0-9]+/;
+ var node = this;
+ //Keeps track for active animations
+ var animationComplete = true;
+
+ //Find BlinkStick based on serial number if supplied, otherwise look for first
+ //Blinkstick in the USB device list
+ var findBlinkStick = function (callback) {
+ if (typeof(node.serial) == 'string' && node.serial.replace(/\s+/g,'') !== '') {
+ blinkstick.findBySerial(node.serial, function (device) {
+ node.led = device;
+
+ if (Object.size(node.led) === 0) {
+ node.status({fill:"red",shape:"ring",text:"disconnected"});
+ node.error("BlinkStick with serial number " + node.serial + " not found");
+ } else {
+ node.status({fill:"green",shape:"dot",text:"connected"});
+ if (callback) callback();
+ }
+ });
+ } else {
+ node.led = blinkstick.findFirst();
+
+ if (Object.size(node.led) === 0) {
+ node.status({fill:"red",shape:"ring",text:"disconnected"});
+ node.error("No BlinkStick found");
+ } else {
+ node.status({fill:"green",shape:"dot",text:"connected"});
+ if (callback) callback();
+ }
+ }
+ };
+
+ //Check if repeat is enabled. Works only for pulse and blink tasks
+ var canRepeat = function () {
+ return node.task == "pulse" || node.task == "blink";
+ };
+
+ //Event handler for all animation complete events
+ var blinkstickAnimationComplete = function (err) {
+ if (typeof(err) !== 'undefined') {
+ node.warn(err);
+
+ if (typeof(err.name) === 'undefined' || err.name !== 'ReferenceError') {
+ //USB error occurred when BlinkStick was animating
+ node.led.close(function (err) {
+ node.led = undefined;
+ findBlinkStick();
+ });
+ }
+ }
+
+ animationComplete = true;
+
+ //Apply queued color animation
+ if (!node.closing && node.color !== '') {
+ //Apply new color only if there was no error or queued color is different from the previous color
+ if (typeof(err) === 'undefined' || typeof(err) !== 'undefined' && node.color != node.previousColor) {
+ applyColor();
+ }
+ }
+ };
+
+ var applyColor = function () {
+ animationComplete = false;
+
+ //Store the value of color to check if it has changed
+ node.previousColor = node.color;
+
+ try {
+ //Select animation to perform
+ if (node.task == "pulse") {
+ node.led.pulse(node.color, {'duration': node.duration, 'steps': node.steps }, blinkstickAnimationComplete);
+ } else if (node.task == "morph") {
+ node.led.morph(node.color, {'duration': node.duration, 'steps': node.steps }, blinkstickAnimationComplete);
+ } else if (node.task == "blink") {
+ node.led.blink(node.color,{'repeats': node.repeats, 'delay': node.delay }, blinkstickAnimationComplete);
+ } else {
+ node.led.setColor(node.color, blinkstickAnimationComplete);
+ }
+ } catch (err) {
+ if (err.toString().indexOf("setColor") !== -1) {
+ node.led.setColour(node.color, blinkstickAnimationComplete);
+ node.warn("Old version - please upgrade Blinkstick npm");
+ }
+ else {
+ node.warn("BlinkStick missing ? " + err);
+ }
+ console.log(err);
+ //Reset animation
+ animationComplete = true;
+ //Clear color
+ node.color = '';
+ //Look for a BlinkStick
+ findBlinkStick();
+ return;
+ }
+
+ //Clear color value until next one is received, unless repeat option is set to true
+ if (!node.repeat || !canRepeat()) {
+ node.color = '';
+ }
+ };
+
+ findBlinkStick();
+
+ this.on("input", function(msg) {
+ if (typeof(msg.payload) === 'object' ) {
+ var data = validatePayloadObject(msg.payload);
+
+ if (typeof(data) === 'object') {
+ node.task = data.task ? data.task : node.task;
+ node.delay = data.delay ? data.delay : node.delay;
+ node.repeats = data.repeats ? data.repeats : node.repeats;
+ node.duration = data.duration ? data.duration : node.duration;
+ node.steps = data.steps ? data.steps : node.steps;
+ node.repeat = data.repeat ? data.repeat : node.repeat;
+ node.color = data.color ? data.color : node.color;
+ } else {
+ node.error(data);
+ return;
+ }
+
+ } else if (p1.test(msg.payload)) {
+ //Color value is represented as "red,green,blue" string of bytes
+ var rgb = msg.payload.split(",");
+
+ //Convert color value back to HEX string for easier implementation
+ node.color = "#" + decimalToHex(parseInt(rgb[0])&255) +
+ decimalToHex(parseInt(rgb[1])&255) + decimalToHex(parseInt(rgb[2])&255);
+ } else {
+ //Sanitize color value
+ node.color = msg.payload.toLowerCase().replace(/\s+/g,'');
+ }
+
+ if (Object.size(node.led) !== 0) {
+ //Start color animation, otherwise the color is queued until current animation completes
+ if (animationComplete) {
+ applyColor();
+ }
+ } else {
+ //Attempt to find BlinkStick and start animation if it's found
+ findBlinkStick(function() {
+ if (animationComplete) {
+ applyColor();
+ }
+ });
+ }
+ });
+
+ this.on("close", function() {
+ //Set the flag to finish all animations
+ this.closing = true;
+
+ if (Object.size(node.led) !== 0) {
+ //Close device and stop animations
+ if (typeof this.led.close === "function") { this.led.close(); }
+ else { node.warn("Please upgrade blinkstick npm"); }
+ }
+ });
+ }
+
+ RED.nodes.registerType("blinkstick",BlinkStick);
+
+ RED.httpAdmin.get("/blinksticklist",function(req,res) {
+ blinkstick.findAllSerials(function(serials) {
+ res.writeHead(200, {'Content-Type': 'application/json'});
+ res.write(JSON.stringify(serials));
+ res.end();
+ });
+ });
+};
diff --git a/hardware/blinkstick/LICENSE b/hardware/blinkstick/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/hardware/blinkstick/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/hardware/blinkstick/README.md b/hardware/blinkstick/README.md
new file mode 100644
index 00000000..e47fd168
--- /dev/null
+++ b/hardware/blinkstick/README.md
@@ -0,0 +1,32 @@
+node-red-node-blinkstick
+========================
+
+A Node-RED node to control a BlinkStick.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install:
+
+ npm install node-red-node-blinkstick
+
+
+Usage
+-----
+
+BlinkStick output node. Expects a msg.payload with one of:
+
+* A hex string "#rrggbb" triple
+* "red,green,blue" three 0-255 values as a string
+* "random" will generate a random color
+* Standard HTML color name
+* object can override any of the parameters
+
+An object payload can override any of the settings on the node. Omitted parameters are left intact. For example:
+
+ { 'color': 'blue' }
+ { 'task': 'blink', 'color': 'red' }
+ { 'task': 'pulse', 'color': 'gree', 'duration': 500 }
+ { 'task': 'morph', 'color': 'orange', 'duration': 500, 'steps': 20 }
+
+For more information see BlinkStick tutorials or the node module documentation.
diff --git a/hardware/blinkstick/package.json b/hardware/blinkstick/package.json
new file mode 100644
index 00000000..7bc2b1ad
--- /dev/null
+++ b/hardware/blinkstick/package.json
@@ -0,0 +1,31 @@
+{
+ "name" : "node-red-node-blinkstick",
+ "version" : "0.1.1",
+ "description" : "A Node-RED node to control a Blinkstick",
+ "dependencies" : {
+ "blinkstick" : "1.1.*"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/hardware/blinkstick"
+ },
+ "license": "Apache",
+ "keywords": [ "node-red", "blinkstick" ],
+ "node-red" : {
+ "nodes" : {
+ "blinkstick": "76-blinkstick.js"
+ }
+ },
+ "author": {
+ "name": "Arvydas Juskevicius",
+ "email": "arvydas@agileinnovative.co.uk",
+ "url": "http://www.blinkstick.com"
+ },
+ "contributors": [
+ {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+ ]
+}
diff --git a/hardware/digiRGB/78-digiRGB.html b/hardware/digiRGB/78-digiRGB.html
index bbb2a128..2f811d90 100644
--- a/hardware/digiRGB/78-digiRGB.html
+++ b/hardware/digiRGB/78-digiRGB.html
@@ -16,7 +16,7 @@
+
+
+
+
diff --git a/hardware/heatmiser/100-heatmiser-in.js b/hardware/heatmiser/100-heatmiser-in.js
new file mode 100644
index 00000000..44eb1396
--- /dev/null
+++ b/hardware/heatmiser/100-heatmiser-in.js
@@ -0,0 +1,191 @@
+/**
+ * Copyright 2014 Sean Bedford
+ *
+ * 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 RED = require(process.env.NODE_RED_HOME+"/red/red");
+
+var Heatmiser = require("heatmiser");
+var util = require('util');
+
+function HeatmiserInputNode(n) {
+ // TODO - holiday and hot water cases when confirmed working
+ var DEBUG = false;
+ RED.nodes.createNode(this,n);
+ this.ip = n.ip || "192.168.0.1";
+ this.pin = n.pin || "1234";
+ this.multiWriteFunc = undefined;
+ hminnode = this;
+ this.pollIntervalRef = undefined;
+
+ this.hm = new Heatmiser(this.ip, this.pin);
+
+ this.hm.on('success', function(data) {
+ if (DEBUG) {
+ util.log("[100-heatmiser-in.js] - Successfully wrote data. Response : " + JSON.stringify(data));
+ }
+ hminnode.currentStatus = data.dcb;
+ if (hminnode.multiWriteFunc) {
+ hminnode.multiWriteFunc();
+ hminnode.multiWriteFunc = undefined;
+ return;
+ }
+ hminnode.send({topic: "", payload:JSON.stringify(data.dcb)});
+ });
+ this.hm.on('error', function(data) {
+ if (DEBUG) {
+ util.log("[100-heatmiser-in.js] - Error during data setting : " + JSON.stringify(data));
+ }
+ hminnode.send(data);
+ });
+
+ this.on("close", function() {
+ if (this.pollIntervalRef) {
+ clearInterval(this.pollIntervalRef);
+ this.pollIntervalRef = undefined;
+ }
+ });
+
+ this.read = function() {
+ if (hminnode.hm) {
+ hminnode.hm.read_device();
+ }
+ };
+
+ if (!this.currentStatus) {
+ this.read();
+ this.pollIntervalRef = setInterval(this.read, 30*60*1000);
+ }
+
+ this.write = function(dcb) {
+ if (hminnode.hm) {
+ hminnode.hm.write_device(dcb);
+ }
+ };
+
+ this.validateAndWrite = function(message) {
+ for (var key in message.payload) {
+ // Ensure our valid keys contain valid values
+ switch(key) {
+ case "runmode" :
+ if (DEBUG) {
+ util.log("[100-heatmiser-in.js] Hit the runmode case");
+ }
+ if (message.payload[key] !== "frost" && message.payload[key] !== "heating") {
+ util.log("[100-heatmiser-in.js] Warning: Unsupported 'runmode' value passed!");
+ return;
+ }
+ break;
+
+ // case "holiday" :
+ // if (DEBUG) {
+ // util.log("[100-heatmiser-in.js] Hit the holiday case");
+ // }
+ // if (!('enabled' in message.payload[key]) && !('time' in message.payload[key])) {
+ // util.log("[100-heatmiser-in.js] Warning: Unsupported 'holiday' value passed!");
+ // return;
+ // }
+ // var time = message.payload[key].time;
+ // // Ensure hminnode time is a date
+ // if (typeof(time) == "string") {
+ // util.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);
+ // util.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) {
+ // util.log("[100-heatmiser-in.js] Hit the hotwater case");
+ // }
+ // if (message.payload[key] !== "on" && message.payload[key] !== "boost" && message.payload[key] !== "off") {
+ // util.log("[100-heatmiser-in.js] Warning: Unsupported 'hotwater' value passed!");
+ // return;
+ // }
+ // break;
+
+ case "heating" :
+ // Ensure heating stays last! It's got a multi write scenario
+ if (DEBUG) {
+ util.log("[100-heatmiser-in.js] Hit the heating case");
+ }
+ if (!('target' in message.payload[key]) && !('hold' in message.payload[key])) {
+ util.log("[100-heatmiser-in.js] Warning: Unsupported 'heating' value passed!");
+ return;
+ }
+ // 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;
+
+ // Ensure hminnode runmode == heating first
+ if (hminnode.currentStatus.run_mode === "frost_protection") {
+ // Use the multiWriteFunc as a callback in our success case
+ hminnode.multiWriteFunc = function() {
+ hminnode.write(message.payload);
+ }
+ hminnode.write({"runmode" : "heating"});
+ // End the flow here to ensure no double-writing
+ return;
+ }
+ break;
+
+ default :
+ break;
+ }
+ }
+ // Valid set of key messages, construct DCB and write
+ var dcb = message.payload;
+ if (DEBUG) {
+ util.log("[100-heatmiser-in.js] Injecting " + JSON.stringify(dcb));
+ }
+ hminnode.write(dcb);
+ };
+
+ this.on("input", function(message) {
+ // Valid inputs are heating:{target:, hold:}, read:, runmode:frost/heating, holiday:{enabled:, time:}, hotwater:{'on':1/0 / 'boost':1/0}
+ if (message.payload) {
+ if (typeof(message.payload) === "string") {
+ message.payload = JSON.parse(message.payload);
+ }
+ // Compare message.payload data to confirm valid and send to thermostat
+ var validInputs = ["heating", "runmode"];
+ for (var key in message.payload) {
+ if (message.payload.hasOwnProperty(key)) {
+ if (validInputs.indexOf(key) < 0) {
+ util.log("[100-heatmiser-in.js] Warning: Unsupported key ("+key+") passed!");
+ return;
+ }
+ }
+ }
+ hminnode.validateAndWrite(message);
+ }
+ else {
+ util.log("[100-heatmiser-in.js] Warning: Invalid input passed!");
+ return;
+ }
+ });
+}
+RED.nodes.registerType("heatmiser-in",HeatmiserInputNode);
diff --git a/hardware/heatmiser/101-heatmiser-out.html b/hardware/heatmiser/101-heatmiser-out.html
new file mode 100644
index 00000000..fea925c2
--- /dev/null
+++ b/hardware/heatmiser/101-heatmiser-out.html
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
diff --git a/hardware/heatmiser/101-heatmiser-out.js b/hardware/heatmiser/101-heatmiser-out.js
new file mode 100644
index 00000000..a7ec6b07
--- /dev/null
+++ b/hardware/heatmiser/101-heatmiser-out.js
@@ -0,0 +1,91 @@
+/**
+ * Copyright 2014 Sean Bedford
+ *
+ * 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 RED = require(process.env.NODE_RED_HOME+"/red/red");
+
+var Heatmiser = require("heatmiser");
+var util = require('util');
+
+function HeatmiserOutputNode(n) {
+ // TODO - holiday and hot water cases when confirmed working
+ var DEBUG = false;
+ RED.nodes.createNode(this,n);
+ this.ip = n.ip || "192.168.0.1";
+ this.pin = n.pin || "1234";
+ this.pollTime = n.pollTime*60*1000 || 30*60*1000;
+ this.pollIntervalRef = undefined;
+ hmoutnode = this;
+
+ this.hm = new Heatmiser(this.ip, this.pin);
+
+ this.hm.on('success', function(data) {
+ if (DEBUG) {
+ util.log("[100-heatmiser-in.js] - Successfully wrote data. Response : " + JSON.stringify(data));
+ }
+ hmoutnode.send({topic: "", payload:JSON.stringify(data.dcb)});
+ });
+ this.hm.on('error', function(data) {
+ if (DEBUG) {
+ util.log("[100-heatmiser-in.js] - Error during data setting : " + JSON.stringify(data));
+ }
+ hmoutnode.send(data);
+ });
+
+ this.read = function() {
+ if (hmoutnode.hm) {
+ hmoutnode.hm.read_device();
+ }
+ };
+
+ if (!this.currentStatus) {
+ this.read();
+ this.pollIntervalRef = setInterval(this.read, this.pollTime);
+ }
+
+ this.on("close", function() {
+ if (this.pollIntervalRef) {
+ clearInterval(this.pollIntervalRef);
+ this.pollIntervalRef = undefined;
+ }
+ });
+
+ this.on("input", function(message) {
+ // Valid inputs are heating:{target:, hold:}, read:, runmode:frost/heating, holiday:{enabled:, time:}, hotwater:{'on':1/0 / 'boost':1/0}
+ if (message.payload == "undefined" || !message.payload) {
+ message.payload = {read : true};
+ }
+ if (typeof(message.payload) == "string") {
+ message.payload = JSON.parse(message.payload);
+ }
+ if (message.payload.read) {
+ hmoutnode.read();
+ }
+ else if (message.payload) {
+ // Compare message.payload data to confirm valid and send to thermostat
+ var validInputs = ["heating", "runmode"];
+ for (var key in message.payload) {
+ if (message.payload.hasOwnProperty(key)) {
+ if (validInputs.indexOf(key) < 0) {
+ util.log("[100-heatmiser.js] Warning: Unsupported key ("+key+") passed!");
+ return;
+ }
+ }
+ }
+ hmoutnode.validateAndWrite(message);
+ }
+ });
+}
+RED.nodes.registerType("heatmiser-out",HeatmiserOutputNode);
diff --git a/hardware/hue/103-hue_discover.html b/hardware/hue/103-hue_discover.html
index ac6c1d39..4d375d8a 100644
--- a/hardware/hue/103-hue_discover.html
+++ b/hardware/hue/103-hue_discover.html
@@ -18,11 +18,11 @@
diff --git a/hardware/hue/104-hue_manage.html b/hardware/hue/104-hue_manage.html
index d23f3973..99950970 100644
--- a/hardware/hue/104-hue_manage.html
+++ b/hardware/hue/104-hue_manage.html
@@ -18,17 +18,17 @@
diff --git a/hardware/makey/42-makey.html b/hardware/makey/42-makey.html
new file mode 100644
index 00000000..57949c14
--- /dev/null
+++ b/hardware/makey/42-makey.html
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
diff --git a/hardware/makey/42-makey.js b/hardware/makey/42-makey.js
new file mode 100644
index 00000000..e2125e81
--- /dev/null
+++ b/hardware/makey/42-makey.js
@@ -0,0 +1,86 @@
+/**
+ * Copyright 2014 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.
+ **/
+
+module.exports = function(RED) {
+ "use strict";
+ var hids = require('hidstream');
+
+ function MakeyNode(n) {
+ RED.nodes.createNode(this,n);
+ this.vid = 0x1b4f; // MakeyMakey vendor ID
+ this.pid = 0x2b75; // MakeyMakey product ID
+ var node = this;
+ var path = null;
+ var tout;
+ var click = false;
+ var keylookup = { "44":"space", "82":"up", "81":"down", "79":"right", "80":"left",
+ "26":"w", "4":"a", "22":"s", "7":"d", "9":"f", "10":"g" };
+
+ var findmakey = function() {
+ node.log("looking for MakeyMakey");
+ var devices = hids.getDevices();
+ for (var dev = 0; dev < devices.length; dev++) {
+ //node.log("Find:"+devices[dev].vendorId.toString(16)+":"+devices[dev].productId.toString(16));
+ if ((devices[dev].vendorId == node.vid) && (devices[dev].productId == node.pid)) {
+ path = devices[dev].path;
+ node.log("found MakeyMakey at: "+path); //path = "0003:0004:00";
+ break; // stop on first match
+ }
+ }
+ if (path === null) {
+ tout = setTimeout( function () {
+ findmakey();
+ },15000);
+ }
+ }
+ findmakey();
+
+ if (path != null) {
+ try {
+ node.makey = new hids.device(path);
+ node.makey.on("data", function(key) {
+ var msg = {payload:[]};
+ //console.log(key);
+ if (key.modKeys[0] === "shift") {
+ for (var keys = 0; keys < key.keyCodes.length; keys++) {
+ node.log(key.keyCodes[keys]+" : "+keylookup[key.keyCodes[keys].toString()]);
+ msg.payload.push(keylookup[key.keyCodes[keys].toString()]);
+ }
+ msg.payload = msg.payload.join();
+ node.send(msg);
+ }
+ else if (key.modKeys[0] === "ctrl") {
+ if (key.charCodes.length === 0) {
+ click = !click;
+ msg.payload = (click) ? "click" : "clock";
+ node.send(msg);
+ }
+ }
+ else { console.log(key); }
+ });
+ } catch(err) { node.warn("can't open MakeyMakey: Do you need root access ?"); }
+ }
+ else {
+ findmakey();
+ }
+
+ this.on("close", function() {
+ if (tout) { clearTimeout(tout); }
+ if (node.makey) { node.makey.device.close(); }
+ });
+ }
+ RED.nodes.registerType("makeymakey",MakeyNode);
+}
diff --git a/hardware/makey/42-makey.rules b/hardware/makey/42-makey.rules
new file mode 100644
index 00000000..1269f8a9
--- /dev/null
+++ b/hardware/makey/42-makey.rules
@@ -0,0 +1 @@
+SUBSYSTEM=="usb", ATTR{idVendor}=="1b4f", ATTR{idProduct}=="2b75", MODE="0666"
diff --git a/hardware/makey/LICENSE b/hardware/makey/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/hardware/makey/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/hardware/makey/README.md b/hardware/makey/README.md
new file mode 100644
index 00000000..20bbd99e
--- /dev/null
+++ b/hardware/makey/README.md
@@ -0,0 +1,37 @@
+node-red-node-makeymakey
+========================
+A Node-RED node to read from a MakeyMakey input device.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-makeymakey
+
+
+Pre-reqs
+--------
+
+As this requires an underlying npm this also requires it's pre-reqs, see Node-hid npm for more details.
+
+ - libudev-dev (Linux only)
+ - libusb-1.0-0-dev (Ubuntu versions missing libusb.h only)
+
+As this uses the raw HID strea mit often requires you to run Node-RED as root, unless you have correct priviliges.
+
+Usage
+-----
+
+Provides "keyboard" like input from a MakeyMakey device.
+
+This uses the hidstream npm module that by default only supports the basic keyboard keys and **NOT** the mouse inputs, fn keys, keypad keys, cursor keys etc. This means that the extra mouse emulation jumpers won't work.
+
+The MakeyMakey can of course be re-programmed to re-assign the keys - but this node doesn't know about that...
+
+Known Issues
+------------
+
+1) Every now and then something causes the MakeyMakey HID to become detached (lose focus) from this app and re-attach to another (the in focus) app... whereupon the emulated keys will end up in the wrong window... - Any ideas on how to stop this would be greatly appreciated - but I suspect it's a fundamental issue with the MakeyMakey pretending to be a HID.
+
+2) Default usage is such that you have to run as root. On Debian based systems you can copy the file 42-makey.rules to the /etc/udev/rules.d/
folder - this should let anyone then access the MakeyMakey. To restart udev use sudo udevadm control --reload-rulesdiff --git a/hardware/makey/package.json b/hardware/makey/package.json new file mode 100644 index 00000000..e4e573b1 --- /dev/null +++ b/hardware/makey/package.json @@ -0,0 +1,24 @@ +{ + "name" : "node-red-node-makeymakey", + "version" : "0.0.1", + "description" : "A Node-RED node to read from a MakeyMakey input device.", + "dependencies" : { + "hidstream": "0.0.3" + }, + "repository" : { + "type":"git", + "url":"https://github.com/node-red/node-red-nodes/tree/master/hardware/makey" + }, + "license": "Apache", + "keywords": [ "node-red", "makeymakey" ], + "node-red" : { + "nodes" : { + "makeymakey": "42-makey.js" + } + }, + "author": { + "name": "Dave Conway-Jones", + "email": "ceejay@vnet.ibm.com", + "url": "http://nodered.org" + } +} diff --git a/hardware/scanBLE/101-scanBLE.html b/hardware/scanBLE/101-scanBLE.html index 329d142c..8a718460 100644 --- a/hardware/scanBLE/101-scanBLE.html +++ b/hardware/scanBLE/101-scanBLE.html @@ -18,17 +18,17 @@ diff --git a/hardware/scanBLE/101-scanBLE.js b/hardware/scanBLE/101-scanBLE.js index 24532e37..bf07e549 100644 --- a/hardware/scanBLE/101-scanBLE.js +++ b/hardware/scanBLE/101-scanBLE.js @@ -37,29 +37,30 @@ function BleScan(n) { this.ble_name = n.ble_name; this.ble_uuid = n.ble_uuid; - this.on("input", function(msg){ - noble.startScanning(); - }); - noble.on('scanStart', function(msg) { - var msg = {}; + this.on("input", function(msg){ + noble.startScanning(); + }); + + noble.on('scanStart', function(msg) { + msg = {}; msg.topic = node.topic; msg.payload = "Scanning initiated..." //debugging - //console.log('scanning initiated...'); - node.send(msg); - }); - - noble.on('discover', function(peripheral) { + //console.log('scanning initiated...'); + node.send(msg); + }); + noble.on('discover', function(peripheral) { var msg = {}; - msg.topic = node.topic; + msg.topic = node.topic; msg.payload = "not found"; //check for the device name and the UUID (first one from the UUID list) if(peripheral.advertisement.localName==node.ble_name && peripheral.advertisement.serviceUuids[0]==node.ble_uuid) { msg.payload=peripheral.advertisement.localName; - noble.stopScanning(); } + noble.stopScanning(); + } node.send(msg); -}); + }); this.on("close", function() { try { noble.stopScanning(); } diff --git a/hardware/sensorTag/79-sensorTag.html b/hardware/sensorTag/79-sensorTag.html index 6e065d94..6f5db727 100644 --- a/hardware/sensorTag/79-sensorTag.html +++ b/hardware/sensorTag/79-sensorTag.html @@ -29,43 +29,43 @@
[{"id":"d2ccae00.2d335","type":"inject","name":"","topic":"","payload":"","payloadType":"none","repeat":"","crontab":"","once":false,"x":136,"y":99,"z":"385bdf8b.c7a42","wires":[["e03cae10.1fc35"]]},{"id":"b778ef09.48871","type":"base64","name":"","x":411.5,"y":160,"z":"385bdf8b.c7a42","wires":[["6295d1b1.9d6a3","46b597ba.b94a68"]]},{"id":"6295d1b1.9d6a3","type":"debug","name":"","active":true,"console":"false","complete":"false","x":610,"y":160,"z":"385bdf8b.c7a42","wires":[]},{"id":"ead9e7c9.152618","type":"debug","name":"","active":true,"console":"false","complete":"false","x":610,"y":240,"z":"385bdf8b.c7a42","wires":[]},{"id":"46b597ba.b94a68","type":"base64","name":"","x":411.5,"y":240,"z":"385bdf8b.c7a42","wires":[["ead9e7c9.152618"]]},{"id":"1c9124e9.e36edb","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":1775,"y":113,"z":"385bdf8b.c7a42","wires":[[]]},{"id":"48a892ea.b7576c","type":"debug","name":"","active":true,"console":"false","complete":"false","x":2171,"y":210,"z":"385bdf8b.c7a42","wires":[]},{"id":"e03cae10.1fc35","type":"function","name":"","func":"msg.payload = new Buffer(\"12345\");\nreturn msg;","outputs":1,"x":250,"y":160,"z":"385bdf8b.c7a42","wires":[["b778ef09.48871"]]}]
+
diff --git a/parsers/base64/package.json b/parsers/base64/package.json
new file mode 100644
index 00000000..ad7dbcdb
--- /dev/null
+++ b/parsers/base64/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-base64",
+ "version" : "0.0.1",
+ "description" : "A Node-RED node to pack and unpack objects to base64 format",
+ "dependencies" : {
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes.git",
+ "path": "/tree/master/parsers/base64"
+ },
+ "license": "Apache-2.0",
+ "keywords": [ "node-red", "base64" ],
+ "node-red" : {
+ "nodes" : {
+ "base64": "70-base64.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/parsers/geohash/70-geohash.html b/parsers/geohash/70-geohash.html
new file mode 100644
index 00000000..a1e483cc
--- /dev/null
+++ b/parsers/geohash/70-geohash.html
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
diff --git a/parsers/geohash/70-geohash.js b/parsers/geohash/70-geohash.js
new file mode 100644
index 00000000..24fd95da
--- /dev/null
+++ b/parsers/geohash/70-geohash.js
@@ -0,0 +1,93 @@
+/**
+ * Copyright 2014 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.
+ **/
+
+module.exports = function(RED) {
+ "use strict";
+ var geohash = require('ngeohash');
+
+ function GeohashNode(n) {
+ RED.nodes.createNode(this,n);
+ var node = this;
+
+ var round = function(value, decimals) {
+ return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
+ }
+
+ this.on("input", function(msg) {
+ if (msg.hasOwnProperty("location")) {
+ if (msg.location.hasOwnProperty("geohash")) {
+ var pos = geohash.decode(msg.location.geohash);
+ msg.location.lat = round(pos.latitude,5);
+ msg.location.lon = round(pos.longitude,5);
+ msg.location.error = { lat:round(pos.error.latitude,5), lon:round(pos.error.longitude,5) };
+ 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);
+ node.send(msg);
+ }
+ }
+ }
+ else if (typeof msg.payload === "string") {
+ // 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) };
+ node.send(msg);
+ }
+ else if (msg.payload.indexOf(",") !== -1) {
+ // has a comma so assume it's lat,lon(,precision)
+ var bits = msg.payload.split(",");
+ if (bits.length === 2) {
+ var la = Number(bits[0]);
+ if (la < -90) { la = -90; }
+ if (la > 90) { la = 90; }
+ var lo = Number(bits[1]);
+ if (lo < -180) { lo = -180; }
+ if (lo > 180) { la = 180; }
+ msg.payload = geohash.encode(la, lo);
+ node.send(msg);
+ }
+ else { node.warn("Unexpected string format - should be lat,lon"); }
+ }
+ else { node.warn("Unexpected string format - should either be lat,lon or geohash"); }
+ }
+ else if (typeof msg.payload === "object") {
+ var lat = msg.payload.lat || msg.payload.latitude;
+ var lon = msg.payload.lon || msg.payload.longitude;
+ var len = parseInt(msg.payload.precision || 9);
+ if (len < 1) { len = 1; }
+ if (len > 9) { len = 9; }
+ if (lat && lon) {
+ msg.payload.geohash = geohash.encode(lat, lon, len);
+ node.send(msg);
+ }
+ }
+ else {
+ node.warn("This node only expects strings or objects.");
+ }
+ });
+ }
+ RED.nodes.registerType("geohash",GeohashNode);
+}
diff --git a/parsers/geohash/LICENSE b/parsers/geohash/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/parsers/geohash/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/parsers/geohash/README.md b/parsers/geohash/README.md
new file mode 100644
index 00000000..76fc67f2
--- /dev/null
+++ b/parsers/geohash/README.md
@@ -0,0 +1,35 @@
+node-red-node-geohash
+=====================
+
+A Node-RED node to encode and decode lat,lon pairs to a [{"id":"60ebfc45.9f1404","type":"function","name":"","func":"msg.payload = {lat:51,lon:-1,precision:5};\nreturn msg;","outputs":1,"x":281,"y":485,"z":"385bdf8b.c7a42","wires":[["6f1c5357.90e3ac"]]},{"id":"6f1c5357.90e3ac","type":"geohash","name":"","x":415.5,"y":420,"z":"385bdf8b.c7a42","wires":[["71a94378.8e56bc"]]},{"id":"52763c46.ad89c4","type":"inject","name":"","topic":"","payload":"51.05,-1.05","payloadType":"string","repeat":"","crontab":"","once":false,"x":165.5,"y":337,"z":"385bdf8b.c7a42","wires":[["7b08247.f84f7dc"]]},{"id":"7b08247.f84f7dc","type":"geohash","name":"","x":360.5,"y":337,"z":"385bdf8b.c7a42","wires":[["6f1c5357.90e3ac","893e37b7.76c1c8"]]},{"id":"6fec77c4.901388","type":"inject","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":155,"y":397,"z":"385bdf8b.c7a42","wires":[["60ebfc45.9f1404"]]},{"id":"893e37b7.76c1c8","type":"debug","name":"","active":true,"console":"false","complete":"false","x":535,"y":337,"z":"385bdf8b.c7a42","wires":[]},{"id":"71a94378.8e56bc","type":"debug","name":"","active":true,"console":"false","complete":"false","x":590,"y":420,"z":"385bdf8b.c7a42","wires":[]}]
diff --git a/parsers/geohash/package.json b/parsers/geohash/package.json
new file mode 100644
index 00000000..94ccc4a5
--- /dev/null
+++ b/parsers/geohash/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-geohash",
+ "version" : "0.0.2",
+ "description" : "A Node-RED node to encode and decode lat,lon pairs to a geohash.",
+ "dependencies" : {
+ "ngeohash" : "0.6.0"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/parsers/geohash"
+ },
+ "license": "Apache-2.0",
+ "keywords": [ "node-red", "geohash" ],
+ "node-red" : {
+ "nodes" : {
+ "geohash": "70-geohash.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/parsers/msgpack/70-msgpack.html b/parsers/msgpack/70-msgpack.html
new file mode 100644
index 00000000..7a754d14
--- /dev/null
+++ b/parsers/msgpack/70-msgpack.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
diff --git a/parsers/msgpack/70-msgpack.js b/parsers/msgpack/70-msgpack.js
new file mode 100644
index 00000000..f50d276b
--- /dev/null
+++ b/parsers/msgpack/70-msgpack.js
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2014 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.
+ **/
+
+module.exports = function(RED) {
+ "use strict";
+ var msgpack = require('msgpack-js');
+
+ function MsgPackNode(n) {
+ RED.nodes.createNode(this,n);
+ var node = this;
+ this.on("input", function(msg) {
+ if (Buffer.isBuffer(msg.payload)) {
+ var l = msg.payload.length;
+ try {
+ msg.payload = msgpack.decode(msg.payload);
+ node.send(msg);
+ node.status({text:l +" b->o "+ JSON.stringify(msg.payload).length});
+ }
+ catch (e) {
+ node.warn("Bad decode: "+e);
+ node.status({text:"not a msgpack buffer"});
+ }
+ }
+ else {
+ var l = JSON.stringify(msg.payload).length;
+ msg.payload = msgpack.encode(msg.payload);
+ node.send(msg);
+ node.status({text:l +" o->b "+ msg.payload.length});
+ }
+ });
+ }
+ RED.nodes.registerType("msgpack",MsgPackNode);
+}
diff --git a/parsers/msgpack/LICENSE b/parsers/msgpack/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/parsers/msgpack/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/parsers/msgpack/README.md b/parsers/msgpack/README.md
new file mode 100644
index 00000000..49549236
--- /dev/null
+++ b/parsers/msgpack/README.md
@@ -0,0 +1,23 @@
+node-red-node-msgpack
+=====================
+
+A Node-RED node to pack and unpack objects to msgpack format buffers.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-msgpack
+
+
+Usage
+-----
+
+Uses the msgpack npm to pack and unpack msg.payload objects to msgpack format buffers.
+
+If the input is an object it converts it to a msgpack buffer.
+
+If the input is a msgpack buffer it converts it back to an object.
+
+Current only supports msg.payloads of type object.
diff --git a/parsers/msgpack/package.json b/parsers/msgpack/package.json
new file mode 100644
index 00000000..23a675b8
--- /dev/null
+++ b/parsers/msgpack/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-msgpack",
+ "version" : "0.0.3",
+ "description" : "A Node-RED node to pack and unpack objects to msgpack format",
+ "dependencies" : {
+ "msgpack-js" : "0.3.0"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/parsers/msgpack"
+ },
+ "license": "Apache-2.0",
+ "keywords": [ "node-red", "msgpack" ],
+ "node-red" : {
+ "nodes" : {
+ "msgpack": "70-msgpack.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/social/dweetio/55-dweetio.html b/social/dweetio/55-dweetio.html
new file mode 100644
index 00000000..a70fd841
--- /dev/null
+++ b/social/dweetio/55-dweetio.html
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/social/dweetio/55-dweetio.js b/social/dweetio/55-dweetio.js
new file mode 100644
index 00000000..4ef8c88b
--- /dev/null
+++ b/social/dweetio/55-dweetio.js
@@ -0,0 +1,70 @@
+/**
+ * Copyright 2014 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.
+ **/
+
+module.exports = function(RED) {
+ "use strict";
+ var DweetClient = require("node-dweetio");
+ var dweetio = null;
+
+ function DweetioOutNode(n) {
+ RED.nodes.createNode(this,n);
+ this.thing = n.thing;
+ if (dweetio == null) { dweetio = new DweetClient(); }
+ var node = this;
+
+ this.on("input",function(msg) {
+ //if (typeof(msg.payload) === 'object') {
+ var thing = node.thing || msg.thing;
+ try {
+ dweetio.dweet_for(thing, {payload:msg.payload}, function(err, dweet) {
+ //console.log(dweet.thing); // "my-thing"
+ //console.log(dweet.content); // The content of the dweet
+ //console.log(dweet.created); // The create date of the dweet
+ });
+ }
+ catch (err) {
+ node.log(err);
+ }
+ //} else { node.warn("Dweetio only sends payload objects."); }
+ });
+
+ }
+ RED.nodes.registerType("dweetio out",DweetioOutNode);
+
+ function DweetioInNode(n) {
+ RED.nodes.createNode(this,n);
+ this.thing = n.thing;
+ if (dweetio == null) { dweetio = new DweetClient(); }
+ var node = this;
+
+ dweetio.listen_for(node.thing, function(dweet){
+ // This will be called anytime there is a new dweet for my-thing
+ if (dweet.content.hasOwnProperty("payload")) {
+ dweet.payload=dweet.content.payload;
+ } else {
+ dweet.payload = dweet.content;
+ }
+ delete dweet.content;
+ node.send(dweet);
+ });
+
+ this.on("close", function() {
+ dweetio.stop_listening_for(node.thing);
+ });
+
+ }
+ RED.nodes.registerType("dweetio in",DweetioInNode);
+}
diff --git a/social/dweetio/LICENSE b/social/dweetio/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/social/dweetio/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/social/dweetio/README.md b/social/dweetio/README.md
new file mode 100644
index 00000000..657803a5
--- /dev/null
+++ b/social/dweetio/README.md
@@ -0,0 +1,44 @@
+node-red-node-dweetio
+=====================
+
+A Node-RED node to send and receive simple dweets.
+
+This node does **NOT** support private or "locked" dweets.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-dweetio
+
+
+Usage
+-----
+
+###Output
+
+Sends the **msg.payload** to Dweet.io
+
+
+Optionally uses **msg.thing** to set the thing id, if not already set in the properties.
+
+You need to make the thing id unique - you are recommended to use a GUID.
+
+###Input
+
+Listens for messages from Dweet.io
+
+The thing id should be globally unique as they are all public - you are recommended to use a GUID.
+
+The Thing ID is set into **msg.dweet**, and the timesamp into **msg.created**.
+
+
+For further info see the Dweet.io website
+
+
+###Sample Flow
+
+Cut the text below - then in Node-RED use Ctrl-I (Import) - Ctrl-V (Paste) to insert into your workspace.
+
+ [{"id":"58bfbfe.fa7404","type":"debug","name":"","active":true,"console":"false","complete":"false","x":401,"y":211,"z":"8f1399c1.70ec68","wires":[]},{"id":"bc69a077.43966","type":"dweetio out","thing":"not-very-random-big-string","name":"","x":409,"y":135,"z":"8f1399c1.70ec68","wires":[]},{"id":"aaad178a.5552e8","type":"dweetio in","thing":"not-very-random-big-string","name":"","x":153,"y":211,"z":"8f1399c1.70ec68","wires":[["58bfbfe.fa7404"]]},{"id":"db15a21f.24ea6","type":"inject","name":"","topic":"Ticktock","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":160,"y":136,"z":"8f1399c1.70ec68","wires":[["bc69a077.43966"]]}]
diff --git a/social/dweetio/package.json b/social/dweetio/package.json
new file mode 100644
index 00000000..ad23c5cf
--- /dev/null
+++ b/social/dweetio/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-dweetio",
+ "version" : "0.0.5",
+ "description" : "A Node-RED node to send and receive simple dweets",
+ "dependencies" : {
+ "node-dweetio" : "0.0.11"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/social/dweetio"
+ },
+ "license": "Apache-2.0",
+ "keywords": [ "node-red", "dweetio" ],
+ "node-red" : {
+ "nodes" : {
+ "dweetio": "55-dweetio.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/social/music/69-mpd.html b/social/music/69-mpd.html
index acfc07be..bfa11854 100644
--- a/social/music/69-mpd.html
+++ b/social/music/69-mpd.html
@@ -16,7 +16,7 @@
+
+
+
+
diff --git a/social/nma/57-nma.js b/social/nma/57-nma.js
new file mode 100644
index 00000000..3870a05b
--- /dev/null
+++ b/social/nma/57-nma.js
@@ -0,0 +1,88 @@
+/**
+ * Copyright 2014 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.
+ **/
+
+module.exports = function(RED) {
+ "use strict";
+ var nma = require('nma');
+
+ function NMANode(n) {
+ RED.nodes.createNode(this,n);
+ this.title = n.title;
+ var credentials = RED.nodes.getCredentials(n.id);
+ if ((credentials) && (credentials.hasOwnProperty("pushkey"))) { this.pushkey = credentials.pushkey; }
+ else { this.error("No NMA API key set"); }
+ var node = this;
+ this.on("input",function(msg) {
+ var titl = this.title||msg.topic||"Node-RED";
+ if (typeof(msg.payload) === 'object') {
+ msg.payload = JSON.stringify(msg.payload);
+ }
+ else { msg.payload = msg.payload.toString(); }
+ if (node.pushkey) {
+ nma({
+ "apikey": node.pushkey,
+ "application": "Node-RED",
+ "event": titl,
+ "description": msg.payload,
+ "priority": 0
+ }, function (error) {
+ if (error) {
+ node.warn("NMA error: " + error);
+ }
+ });
+ }
+ else {
+ node.warn("NMA credentials not set.");
+ }
+ });
+ }
+
+ RED.nodes.registerType("nma",NMANode);
+
+ var querystring = require('querystring');
+
+ RED.httpAdmin.get('/nma/:id',function(req,res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({hasPassword:(credentials.pushkey&&credentials.pushkey!=="")}));
+ } else {
+ res.send(JSON.stringify({}));
+ }
+ });
+
+ RED.httpAdmin.delete('/nma/:id',function(req,res) {
+ RED.nodes.deleteCredentials(req.params.id);
+ res.send(200);
+ });
+
+ RED.httpAdmin.post('/nma/:id',function(req,res) {
+ var body = "";
+ req.on('data', function(chunk) {
+ body+=chunk;
+ });
+ req.on('end', function(){
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id)||{};
+ if (newCreds.pushkey === "") {
+ delete credentials.pushkey;
+ } else {
+ credentials.pushkey = newCreds.pushkey||credentials.pushkey;
+ }
+ RED.nodes.addCredentials(req.params.id,credentials);
+ res.send(200);
+ });
+ });
+}
diff --git a/social/nma/LICENSE b/social/nma/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/social/nma/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/social/nma/README.md b/social/nma/README.md
new file mode 100644
index 00000000..2ae013cf
--- /dev/null
+++ b/social/nma/README.md
@@ -0,0 +1,23 @@
+node-red-node-nma
+=================
+
+A Node-RED node to send alerts via Notify-My-Android.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-nma
+
+
+Usage
+-----
+
+Uses Notify-My-Android (NMA) to push the **msg.payload** to an Android device that has Notify-My-Android app installed.
+
+Optionally uses **msg.topic** to set the title, if not already set in the properties.
+
+The API-key is stored in a separate credentials file.
+
+Uses Notify-My-Android. See this link for more details.
diff --git a/social/nma/icons/nma.png b/social/nma/icons/nma.png
new file mode 100644
index 00000000..902f90f4
Binary files /dev/null and b/social/nma/icons/nma.png differ
diff --git a/social/nma/package.json b/social/nma/package.json
new file mode 100644
index 00000000..07932d16
--- /dev/null
+++ b/social/nma/package.json
@@ -0,0 +1,28 @@
+{
+ "name" : "node-red-node-nma",
+ "version" : "0.0.2",
+ "description" : "A Node-RED node to send alerts via Notify-My-Android",
+ "dependencies" : {
+ "nma" : "0.2.2"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/social/nma"
+ },
+ "license": "Apache",
+ "keywords": [ "node-red", "nma", "notify my android" ],
+ "node-red" : {
+ "nodes" : {
+ "nma": "57-nma.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ },
+ "contributors": [{
+ "name": "Edwin Hermans",
+ "email": "edwin@madtech.cx"
+ }]
+}
diff --git a/social/notify/57-notify.html b/social/notify/57-notify.html
index fa820d31..96859100 100644
--- a/social/notify/57-notify.html
+++ b/social/notify/57-notify.html
@@ -16,11 +16,11 @@
diff --git a/social/notify/57-notify.js b/social/notify/57-notify.js
index b36d6b82..764effb7 100644
--- a/social/notify/57-notify.js
+++ b/social/notify/57-notify.js
@@ -14,26 +14,28 @@
* limitations under the License.
**/
-var RED = require(process.env.NODE_RED_HOME+"/red/red");
-var growl = require('growl');
-var imagefile = process.env.NODE_RED_HOME+"/public/node-red.png";
+module.exports = function(RED) {
+ "use strict";
+ var growl = require('growl');
+ var imagefile = process.env.NODE_RED_HOME+"/public/node-red.png";
-function NotifyNode(n) {
- RED.nodes.createNode(this,n);
- this.title = n.title;
- var node = this;
- this.on("input",function(msg) {
- var titl = this.title || msg.topic;
- if (typeof(msg.payload) == 'object') {
- msg.payload = JSON.stringify(msg.payload);
- }
- if (typeof(titl) != 'undefined') {
- growl(msg.payload, { title: titl, image: imagefile });
- }
- else {
- growl(msg.payload, { image: imagefile });
- }
- });
+ function NotifyNode(n) {
+ RED.nodes.createNode(this,n);
+ this.title = n.title;
+ var node = this;
+ this.on("input",function(msg) {
+ var titl = this.title || msg.topic;
+ if (typeof(msg.payload) == 'object') {
+ msg.payload = JSON.stringify(msg.payload);
+ }
+ if (typeof(titl) != 'undefined') {
+ growl(msg.payload, { title: titl, image: imagefile });
+ }
+ else {
+ growl(msg.payload, { image: imagefile });
+ }
+ });
+ }
+
+ RED.nodes.registerType("notify",NotifyNode);
}
-
-RED.nodes.registerType("notify",NotifyNode);
diff --git a/social/prowl/57-prowl.html b/social/prowl/57-prowl.html
index 6a897f79..bc90e6df 100644
--- a/social/prowl/57-prowl.html
+++ b/social/prowl/57-prowl.html
@@ -16,27 +16,32 @@
diff --git a/social/prowl/57-prowl.js b/social/prowl/57-prowl.js
index ee1791c2..a0f42f6e 100644
--- a/social/prowl/57-prowl.js
+++ b/social/prowl/57-prowl.js
@@ -14,54 +14,98 @@
* limitations under the License.
**/
-var RED = require(process.env.NODE_RED_HOME+"/red/red");
-var Prowl = require('node-prowl');
-var util = require('util');
+module.exports = function(RED) {
+ "use strict";
+ var Prowl = require('node-prowl');
-// Either add a line like this to settings.js
-// prowl: {prowlkey:'My-API-KEY'},
-// or create pushkey.js in dir ABOVE node-red, it just needs to be like
-// module.exports = {prowlkey:'My-API-KEY'}
+ // Either add a line like this to settings.js
+ // prowl: {prowlkey:'My-API-KEY'},
+ // or create pushkey.js in dir ABOVE node-red, it just needs to be like
+ // module.exports = {prowlkey:'My-API-KEY'}
-try {
- var pushkey = RED.settings.prowl || require(process.env.NODE_RED_HOME+"/../pushkey.js");
-}
-catch(err) {
- util.log("[57-prowl.js] Error: Failed to load Prowl credentials");
-}
+ try {
+ var pushkeys = RED.settings.prowl || require(process.env.NODE_RED_HOME+"/../pushkey.js");
+ }
+ catch(err) { }
-if (pushkey) {
- if (pushkey.prowlkey) { var prowl = new Prowl(pushkey.prowlkey); }
-}
-
-function ProwlNode(n) {
- RED.nodes.createNode(this,n);
- this.title = n.title;
- this.priority = parseInt(n.priority);
- if (this.priority > 2) this.priority = 2;
- if (this.priority < -2) this.priority = -2;
- var node = this;
- this.on("input",function(msg) {
- var titl = this.title||msg.topic||"Node-RED";
- var pri = msg.priority||this.priority;
- if (typeof(msg.payload) === 'object') {
- msg.payload = JSON.stringify(msg.payload);
+ function ProwlNode(n) {
+ RED.nodes.createNode(this,n);
+ this.title = n.title;
+ this.priority = parseInt(n.priority);
+ if (this.priority > 2) { this.priority = 2; }
+ if (this.priority < -2) { this.priority = -2; }
+ var credentials = RED.nodes.getCredentials(n.id);
+ if ((credentials) && (credentials.hasOwnProperty("pushkey"))) { this.pushkey = credentials.pushkey; }
+ else {
+ if (pushkeys) { this.pushkey = pushkeys.prowlkey; }
+ else { this.error("No Prowl credentials set."); }
}
- else { msg.payload = msg.payload.toString(); }
- if (pushkey.prowlkey) {
- try {
- prowl.push(msg.payload, titl, { priority: pri }, function(err, remaining) {
- if (err) node.error(err);
- node.log( remaining + ' calls to Prowl api during current hour.' );
- });
+ this.prowl = false;
+ if (this.pushkey) { this.prowl = new Prowl(this.pushkey); }
+ var node = this;
+
+ this.on("input",function(msg) {
+ var titl = this.title||msg.topic||"Node-RED";
+ var pri = msg.priority||this.priority;
+ if (typeof(msg.payload) === 'object') {
+ msg.payload = JSON.stringify(msg.payload);
}
- catch (err) {
- node.error(err);
+ else { msg.payload = msg.payload.toString(); }
+ if (node.pushkey) {
+ try {
+ node.prowl.push(msg.payload, titl, { priority: pri }, function(err, remaining) {
+ if (err) { node.error(err); }
+ node.log( remaining + ' calls to Prowl api during current hour.' );
+ });
+ }
+ catch (err) {
+ node.error(err);
+ }
}
+ else {
+ node.warn("Prowl credentials not set.");
+ }
+ });
+ }
+ RED.nodes.registerType("prowl",ProwlNode);
+
+ var querystring = require('querystring');
+
+ RED.httpAdmin.get('/prowl/:id',function(req,res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({hasPassword:(credentials.pushkey&&credentials.pushkey!=="")}));
+ }
+ else if (pushkeys && pushkeys.prowlkey) {
+ RED.nodes.addCredentials(req.params.id,{pushkey:pushkeys.prowlkey,global:true});
+ credentials = RED.nodes.getCredentials(req.params.id);
+ res.send(JSON.stringify({hasPassword:(credentials.pushkey&&credentials.pushkey!==""),global:credentials.global}));
}
else {
- node.warn("Prowl credentials not set/found. See node info.");
+ res.send(JSON.stringify({}));
}
});
+
+ RED.httpAdmin.delete('/prowl/:id',function(req,res) {
+ RED.nodes.deleteCredentials(req.params.id);
+ res.send(200);
+ });
+
+ RED.httpAdmin.post('/prowl/:id',function(req,res) {
+ var body = "";
+ req.on('data', function(chunk) {
+ body+=chunk;
+ });
+ req.on('end', function(){
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id)||{};
+ if (newCreds.pushkey === "") {
+ delete credentials.pushkey;
+ } else {
+ credentials.pushkey = newCreds.pushkey||credentials.pushkey;
+ }
+ RED.nodes.addCredentials(req.params.id,credentials);
+ res.send(200);
+ });
+ });
}
-RED.nodes.registerType("prowl",ProwlNode);
diff --git a/social/prowl/LICENSE b/social/prowl/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/social/prowl/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/social/prowl/README.md b/social/prowl/README.md
new file mode 100644
index 00000000..4736bbd5
--- /dev/null
+++ b/social/prowl/README.md
@@ -0,0 +1,23 @@
+node-red-node-prowl
+===================
+
+A Node-RED node to send alerts via Prowl.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-prowl
+
+
+Usage
+-----
+
+Uses Prowl to push the **msg.payload** to an Apple device that has the prowl app installed.
+
+Optionally uses **msg.topic** to set the title. You can also set **msg.priority** to confgure the urgency from -2 (low), through 0 (normal) to 2 (urgent).
+
+The API Key is stored in a separate credentials file.
+
+Uses Prowl. See this link for more details.
diff --git a/social/prowl/package.json b/social/prowl/package.json
new file mode 100644
index 00000000..5df611e1
--- /dev/null
+++ b/social/prowl/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-prowl",
+ "version" : "0.0.1",
+ "description" : "A Node-RED node to send alerts via Prowl",
+ "dependencies" : {
+ "node-prowl" : "0.1.7"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/social/prowl"
+ },
+ "license": "Apache",
+ "keywords": [ "node-red", "prowl"],
+ "node-red" : {
+ "nodes" : {
+ "prowl": "57-prowl.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/social/pushbullet/57-pushbullet.html b/social/pushbullet/57-pushbullet.html
index 4008321f..396b7e98 100644
--- a/social/pushbullet/57-pushbullet.html
+++ b/social/pushbullet/57-pushbullet.html
@@ -16,23 +16,37 @@
diff --git a/social/pushbullet/57-pushbullet.js b/social/pushbullet/57-pushbullet.js
index a172490d..86a69fd3 100644
--- a/social/pushbullet/57-pushbullet.js
+++ b/social/pushbullet/57-pushbullet.js
@@ -14,53 +14,112 @@
* limitations under the License.
**/
-var RED = require(process.env.NODE_RED_HOME+"/red/red");
-var PushBullet = require('pushbullet');
-var util = require('util');
+module.exports = function(RED) {
+ "use strict";
+ var PushBullet = require('pushbullet');
+ var util = require('util');
-// Either add a line like this to settings.js
-// pushbullet: {pushbullet:'My-API-KEY', deviceid:'12345'},
-// or create pushkey.js in dir ABOVE node-red, it just needs to be like
-// module.exports = {pushbullet:'My-API-KEY', deviceid:'12345'}
+ // Either create pushkey.js in dir ABOVE node-red, it just needs to be like
+ // module.exports = {pushbullet:'My-API-KEY', deviceid:'12345'}
+ // or set them per node in the edit dialog
-try {
- var pushkey = RED.settings.pushbullet || require(process.env.NODE_RED_HOME+"/../pushkey.js");
-}
-catch(err) {
- util.log("[57-pushbullet.js] Error: Failed to load PushBullet credentials");
-}
+ try {
+ var pushkeys = RED.settings.pushbullet || require(process.env.NODE_RED_HOME+"/../pushkey.js");
+ }
+ catch(err) {
+ //util.log("[57-pushbullet.js] Warning: Failed to load global PushBullet credentials");
+ }
-if (pushkey) {
- if (pushkey.pushbullet) { var pusher = new PushBullet(pushkey.pushbullet); }
- if (pushkey.deviceid) { var deviceId = pushkey.deviceid; }
-}
-
-function PushbulletNode(n) {
- RED.nodes.createNode(this,n);
- this.title = n.title;
- var node = this;
- this.on("input",function(msg) {
- var titl = this.title||msg.topic||"Node-RED";
- if (typeof(msg.payload) === 'object') {
- msg.payload = JSON.stringify(msg.payload);
+ function PushbulletNode(n) {
+ RED.nodes.createNode(this,n);
+ this.title = n.title;
+ this.chan = n.chan;
+ var credentials = RED.nodes.getCredentials(n.id);
+ if ((credentials) && (credentials.hasOwnProperty("pushkey"))) { this.pushkey = credentials.pushkey; }
+ else {
+ if (pushkeys) { this.pushkey = pushkeys.pushbullet; }
+ else { this.error("No Pushbullet API key set"); }
}
- else { msg.payload = msg.payload.toString(); }
- if (pushkey.pushbullet && pushkey.deviceid) {
- try {
- if (!isNaN(deviceId)) { deviceId = Number(deviceId); }
- pusher.note(deviceId, titl, msg.payload, function(err, response) {
- if (err) node.error("Pushbullet error: "+err);
- //console.log(response);
- });
+ if ((credentials) && (credentials.hasOwnProperty("deviceid"))) { this.deviceid = credentials.deviceid; }
+ else {
+ if (pushkeys) { this.deviceid = pushkeys.deviceid; }
+ else { this.warn("No deviceid set"); }
+ }
+ this.pusher = new PushBullet(this.pushkey);
+ var node = this;
+
+ this.on("input",function(msg) {
+ var titl = node.title || msg.topic || "Node-RED";
+ var dev = node.deviceid || msg.deviceid;
+ var channel = node.chan || msg.chan;
+ if (channel != undefined) {
+ dev = { channel_tag : channel };
+ } else {
+ if (!isNaN(dev)) { dev = Number(dev); }
}
- catch (err) {
- node.error(err);
+ if (typeof(msg.payload) === 'object') {
+ msg.payload = JSON.stringify(msg.payload);
}
+ else { msg.payload = msg.payload.toString(); }
+ if (node.pushkey && dev) {
+ try {
+ node.pusher.note(dev, titl, msg.payload, function(err, response) {
+ if (err) { node.error("Pushbullet error"); }
+ });
+ }
+ catch (err) {
+ node.error(err);
+ }
+ }
+ else {
+ node.warn("Pushbullet credentials not set/found. See node info.");
+ }
+ });
+ }
+ RED.nodes.registerType("pushbullet",PushbulletNode);
+
+ var querystring = require('querystring');
+
+ RED.httpAdmin.get('/pushbullet/:id',function(req,res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({deviceid:credentials.deviceid,hasPassword:(credentials.pushkey&&credentials.pushkey!=="")}));
+ }
+ else if (pushkeys && pushkeys.pushbullet && pushkeys.deviceid) {
+ RED.nodes.addCredentials(req.params.id,{pushkey:pushkeys.pushbullet,deviceid:pushkeys.deviceid,global:true});
+ credentials = RED.nodes.getCredentials(req.params.id);
+ res.send(JSON.stringify({deviceid:credentials.deviceid,global:credentials.global,hasPassword:(credentials.pushkey&&credentials.pushkey!=="")}));
}
else {
- node.warn("Pushbullet credentials not set/found. See node info.");
+ res.send(JSON.stringify({}));
}
});
-}
-RED.nodes.registerType("pushbullet",PushbulletNode);
+ RED.httpAdmin.delete('/pushbullet/:id',function(req,res) {
+ RED.nodes.deleteCredentials(req.params.id);
+ res.send(200);
+ });
+
+ RED.httpAdmin.post('/pushbullet/:id',function(req,res) {
+ var body = "";
+ req.on('data', function(chunk) {
+ body+=chunk;
+ });
+ req.on('end', function(){
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id)||{};
+ if (newCreds.deviceid === null || newCreds.deviceid === "") {
+ delete credentials.deviceid;
+ } else {
+ credentials.deviceid = newCreds.deviceid;
+ }
+ if (newCreds.pushkey === "") {
+ delete credentials.pushkey;
+ } else {
+ credentials.pushkey = newCreds.pushkey||credentials.pushkey;
+ }
+ RED.nodes.addCredentials(req.params.id,credentials);
+ res.send(200);
+ });
+ });
+}
diff --git a/social/pushbullet/LICENSE b/social/pushbullet/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/social/pushbullet/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/social/pushbullet/README.md b/social/pushbullet/README.md
new file mode 100644
index 00000000..4084eea1
--- /dev/null
+++ b/social/pushbullet/README.md
@@ -0,0 +1,21 @@
+node-red-node-pushbullet
+========================
+
+A Node-RED node to send alerts via Pushbullet.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-pushbullet
+
+
+Usage
+-----
+
+Uses PushBullet to push the msg.payload to a device that has the PushBullet app installed.
+
+Optionally uses msg.topic to set the title, if not already set in the properties.
+
+You need to configure both your API key and the target device ID. The device ID may be passed in as msg.deviceid. You can set these per node in the edit dialog.
diff --git a/social/pushbullet/package.json b/social/pushbullet/package.json
new file mode 100644
index 00000000..de4ed94d
--- /dev/null
+++ b/social/pushbullet/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-pushbullet",
+ "version" : "0.0.2",
+ "description" : "A Node-RED node to send alerts via Pushbullet",
+ "dependencies" : {
+ "pushbullet" : "1.4.*"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/hardware/pushbullet"
+ },
+ "license": "Apache",
+ "keywords": [ "node-red", "pushbullet" ],
+ "node-red" : {
+ "nodes" : {
+ "pushbullet": "57-pushbullet.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/social/pusher/114-pusher.html b/social/pusher/114-pusher.html
new file mode 100644
index 00000000..086a681d
--- /dev/null
+++ b/social/pusher/114-pusher.html
@@ -0,0 +1,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/social/pusher/114-pusher.js b/social/pusher/114-pusher.js
new file mode 100644
index 00000000..13bf5268
--- /dev/null
+++ b/social/pusher/114-pusher.js
@@ -0,0 +1,157 @@
+/**
+* pusher.js
+* Subscription module for the Pusher service (www.pusher.com)
+* Requires 'pusher' and 'pusher-client' modules.
+*
+* Copyright 2014 Charalampos Doukas, @BuildingIoT
+*
+* 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.
+**/
+module.exports = function(RED) {
+ "use strict";
+ var Pusher = require('pusher');
+ var PusherClient = require('pusher-client');
+
+ //node for subscribing to an event/channel
+ function PusherNode(n) {
+ // Create a RED node
+ RED.nodes.createNode(this,n);
+
+ var node = this;
+ var credentials = RED.nodes.getCredentials(n.id);
+
+ if ((credentials) && (credentials.hasOwnProperty("pusherappkey_sub"))) { this.appkey = credentials.pusherappkey_sub; }
+ else { this.error("No Pusher app key set for input node"); }
+
+ //get parameters from user
+ this.channel = n.channel;
+ this.eventname = n.eventname;
+
+ //create a subscription to the channel and event defined by user
+ var socket = new PusherClient(''+this.appkey);
+ var my_channel = socket.subscribe(''+this.channel);
+ socket.bind(''+this.eventname,
+ function(data) {
+ var msg = {};
+ if (data.hasOwnProperty("payload")) { msg.payload = data.payload; }
+ else { msg.payload = data; }
+ node.send(msg);
+ }
+ );
+
+ this.on("close", function() {
+ socket.disconnect();
+ });
+ }
+
+ //Node for sending Pusher events
+ function PusherNodeSend(n) {
+ // Create a RED node
+ RED.nodes.createNode(this,n);
+
+ var node = this;
+
+ var credentials = RED.nodes.getCredentials(n.id);
+
+ if ((credentials) && (credentials.hasOwnProperty("pusherappid"))) { this.appid = credentials.pusherappid; }
+ else { this.error("No Pusher api token set"); }
+ if ((credentials) && (credentials.hasOwnProperty("pusherappsecret"))) { this.appsecret = credentials.pusherappsecret; }
+ else { this.error("No Pusher user secret set"); }
+ if ((credentials) && (credentials.hasOwnProperty("pusherappkey"))) { this.appkey = credentials.pusherappkey; }
+ else { this.error("No Pusher user key set"); }
+
+ //get parameters from user
+ this.channel = n.channel;
+ this.eventname = n.eventname;
+
+ var pusher = new Pusher({
+ appId: this.appid,
+ key: this.appkey,
+ secret: this.appsecret
+ });
+
+ this.on("input", function(msg){
+ pusher.trigger(this.channel, this.eventname, {
+ "payload": msg.payload
+ });
+ });
+
+ this.on("close", function() {
+ });
+ }
+
+ //debugging on the output:
+ var displayResult = function(result) {
+ node.log(result);
+ };
+
+ var displayError = function(err) {
+ node.log("Error: "+err);
+ };
+
+ RED.nodes.registerType("pusher in",PusherNode);
+ RED.nodes.registerType("pusher out",PusherNodeSend);
+
+ var querystring = require('querystring');
+
+ RED.httpAdmin.get('/pusher/:id',function(req,res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({pusherappid:credentials.pusherappid,pusherappsecret:credentials.pusherappsecret, pusherappkey:credentials.pusherappkey, pusherappkey_sub:credentials.pusherappkey_sub}));
+ } else {
+ res.send(JSON.stringify({}));
+ }
+ });
+
+ RED.httpAdmin.delete('/pusher/:id',function(req,res) {
+ RED.nodes.deleteCredentials(req.params.id);
+ res.send(200);
+ });
+
+ RED.httpAdmin.post('/pusher/:id',function(req,res) {
+ var body = "";
+ req.on('data', function(chunk) {
+ body+=chunk;
+ });
+ req.on('end', function(){
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id)||{};
+
+ if (newCreds.pusherappid === null || newCreds.pusherappid === "") {
+ delete credentials.pusherappid;
+ } else {
+ credentials.pusherappid = newCreds.pusherappid;
+ }
+ if (newCreds.pusherappkey === "") {
+ delete credentials.pusherappkey;
+ } else {
+ credentials.pusherappkey = newCreds.pusherappkey||credentials.pusherappkey;
+ }
+
+ if (newCreds.pusherappsecret === "") {
+ delete credentials.pusherappsecret;
+ } else {
+ credentials.pusherappsecret = newCreds.pusherappsecret||credentials.pusherappsecret;
+ }
+
+ if (newCreds.pusherappkey_sub === "") {
+ delete credentials.pusherappkey_sub;
+ } else {
+ credentials.pusherappkey_sub = newCreds.pusherappkey_sub||credentials.pusherappkey_sub;
+ }
+
+ RED.nodes.addCredentials(req.params.id,credentials);
+ res.send(200);
+ });
+ });
+}
diff --git a/social/pusher/icons/pusher.png b/social/pusher/icons/pusher.png
new file mode 100644
index 00000000..04bc1635
Binary files /dev/null and b/social/pusher/icons/pusher.png differ
diff --git a/social/pushover/57-pushover.html b/social/pushover/57-pushover.html
new file mode 100644
index 00000000..02329b7c
--- /dev/null
+++ b/social/pushover/57-pushover.html
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
diff --git a/social/pushover/57-pushover.js b/social/pushover/57-pushover.js
new file mode 100644
index 00000000..d309260f
--- /dev/null
+++ b/social/pushover/57-pushover.js
@@ -0,0 +1,112 @@
+/**
+ * Copyright 2014 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.
+ **/
+
+module.exports = function(RED) {
+ "use strict";
+ var PushOver = require('pushover-notifications');
+ var util = require('util');
+
+ function PushoverNode(n) {
+ RED.nodes.createNode(this,n);
+ this.title = n.title;
+ this.priority = n.priority;
+ var credentials = RED.nodes.getCredentials(n.id);
+ if ((credentials) && (credentials.hasOwnProperty("pushkey"))) { this.pushkey = credentials.pushkey; }
+ else { this.error("No Pushover api token set"); }
+ if ((credentials) && (credentials.hasOwnProperty("deviceid"))) { this.deviceid = credentials.deviceid; }
+ else { this.error("No Pushover user key set"); }
+ var pusher = false;
+ if (this.pushkey && this.deviceid) {
+ pusher = new PushOver({
+ user: this.deviceid,
+ token: this.pushkey,
+ onerror: function(err) {
+ util.log('[57-pushover.js] Error: '+err);
+ }
+ });
+ }
+ var node = this;
+
+ this.on("input",function(msg) {
+ var titl = this.title || msg.topic || "Node-RED";
+ var pri = this.priority || msg.priority || 0;
+ if (isNaN(pri)) {pri=0;}
+ if (pri > 2) {pri = 2;}
+ if (pri < -1) {pri = -1;}
+ if (typeof(msg.payload) === 'object') {
+ msg.payload = JSON.stringify(msg.payload);
+ }
+ else { msg.payload = msg.payload.toString(); }
+ if (pusher) {
+ var pushmsg = {
+ message: msg.payload,
+ title: titl,
+ priority: pri,
+ retry: 30,
+ expire: 600
+ };
+ //console.log("Sending",pushmsg);
+ pusher.send( pushmsg, function(err, response) {
+ if (err) { node.error("Pushover Error: "+err); }
+ //console.log(response);
+ });
+ }
+ else {
+ node.warn("Pushover credentials not set.");
+ }
+ });
+ }
+ RED.nodes.registerType("pushover",PushoverNode);
+
+ var querystring = require('querystring');
+
+ RED.httpAdmin.get('/pushover/:id',function(req,res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({deviceid:credentials.deviceid,hasPassword:(credentials.pushkey&&credentials.pushkey!=="")}));
+ } else {
+ res.send(JSON.stringify({}));
+ }
+ });
+
+ RED.httpAdmin.delete('/pushover/:id',function(req,res) {
+ RED.nodes.deleteCredentials(req.params.id);
+ res.send(200);
+ });
+
+ RED.httpAdmin.post('/pushover/:id',function(req,res) {
+ var body = "";
+ req.on('data', function(chunk) {
+ body+=chunk;
+ });
+ req.on('end', function(){
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id)||{};
+ if (newCreds.deviceid === null || newCreds.deviceid === "") {
+ delete credentials.deviceid;
+ } else {
+ credentials.deviceid = newCreds.deviceid;
+ }
+ if (newCreds.pushkey === "") {
+ delete credentials.pushkey;
+ } else {
+ credentials.pushkey = newCreds.pushkey||credentials.pushkey;
+ }
+ RED.nodes.addCredentials(req.params.id,credentials);
+ res.send(200);
+ });
+ });
+}
diff --git a/social/pushover/LICENSE b/social/pushover/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/social/pushover/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/social/pushover/README.md b/social/pushover/README.md
new file mode 100644
index 00000000..3ff18ebc
--- /dev/null
+++ b/social/pushover/README.md
@@ -0,0 +1,23 @@
+node-red-node-pushover
+======================
+
+A Node-RED node to send alerts via Pushover.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-pushover
+
+
+Usage
+-----
+
+Uses Pushover to push the msg.payload to a device that has the Pushover app installed.
+
+Optionally uses **msg.topic** to set the title, and **msg.priority** to set the priority, if not already set in the properties.
+
+The User-key and API-token are stored in a separate credentials file.
+
+Uses Pushover. See Pushover.net for more details.
diff --git a/social/pushover/icons/pushover.png b/social/pushover/icons/pushover.png
new file mode 100644
index 00000000..faeb8be6
Binary files /dev/null and b/social/pushover/icons/pushover.png differ
diff --git a/social/pushover/package.json b/social/pushover/package.json
new file mode 100644
index 00000000..c33c8418
--- /dev/null
+++ b/social/pushover/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-pushover",
+ "version" : "0.0.1",
+ "description" : "A Node-RED node to send alerts via Pushover",
+ "dependencies" : {
+ "pushover-notifications" : "0.2.0"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/social/pushover"
+ },
+ "license": "Apache",
+ "keywords": [ "node-red", "pushover" ],
+ "node-red" : {
+ "nodes" : {
+ "pushover": "57-pushover.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/social/snapchat/79-snapchat.html b/social/snapchat/79-snapchat.html
index f1fb9a74..62ba94a9 100644
--- a/social/snapchat/79-snapchat.html
+++ b/social/snapchat/79-snapchat.html
@@ -1,12 +1,12 @@
diff --git a/social/twilio/56-twilio.js b/social/twilio/56-twilio.js
index 5db40726..92bfb7b0 100644
--- a/social/twilio/56-twilio.js
+++ b/social/twilio/56-twilio.js
@@ -1,5 +1,5 @@
/**
- * Copyright 2013 Andrew D Lindsay @AndrewDLindsay
+ * Copyright 2014 Andrew D Lindsay @AndrewDLindsay
* http://blog.thiseldo.co.uk
*
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,100 +15,116 @@
* limitations under the License.
**/
-var RED = require(process.env.NODE_RED_HOME+"/red/red");
-var util = require('util');
-var twilio = require('twilio');
+module.exports = function(RED) {
+ "use strict";
+ var twilio = require('twilio');
-try {
- var twiliokey = RED.settings.twilio || require(process.env.NODE_RED_HOME+"/../twiliokey.js");
-}
-catch(err) {
-}
-
-var querystring = require('querystring');
-
-RED.httpAdmin.get('/twilio-api/global',function(req,res) {
- res.send(JSON.stringify({hasToken:!(twiliokey && twiliokey.account && twiliokey.authtoken)}));
-});
-RED.httpAdmin.get('/twilio-api/:id',function(req,res) {
- var credentials = RED.nodes.getCredentials(req.params.id);
- if (credentials) {
- res.send(JSON.stringify({hasToken:(credentials.token&&credentials.token!="")}));
- } else {
- res.send(JSON.stringify({}));
+ try {
+ var twiliokey = RED.settings.twilio || require(process.env.NODE_RED_HOME+"/../twiliokey.js");
+ }
+ catch(err) {
}
-});
-RED.httpAdmin.delete('/twilio-api/:id',function(req,res) {
- RED.nodes.deleteCredentials(req.params.id);
- res.send(200);
-});
+ var querystring = require('querystring');
-RED.httpAdmin.post('/twilio-api/:id',function(req,res) {
- var body = "";
- req.on('data', function(chunk) {
- body+=chunk;
+ RED.httpAdmin.get('/twilio-api/global',function(req,res) {
+ res.send(JSON.stringify({hasToken:!(twiliokey && twiliokey.account && twiliokey.authtoken)}));
});
- req.on('end', function(){
- var newCreds = querystring.parse(body);
- var credentials = RED.nodes.getCredentials(req.params.id)||{};
- if (newCreds.token == "") {
- delete credentials.token;
+ RED.httpAdmin.get('/twilio-api/:id',function(req,res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({hasToken:(credentials.token&&credentials.token!=="")}));
} else {
- credentials.token = newCreds.token;
+ res.send(JSON.stringify({}));
}
- RED.nodes.addCredentials(req.params.id,credentials);
+ });
+
+ RED.httpAdmin.delete('/twilio-api/:id',function(req,res) {
+ RED.nodes.deleteCredentials(req.params.id);
res.send(200);
});
-});
-function TwilioAPINode(n) {
- RED.nodes.createNode(this,n);
- this.sid = n.sid;
- this.from = n.from;
- this.name = n.name;
- var credentials = RED.nodes.getCredentials(n.id);
- if (credentials) {
- this.token = credentials.token;
- }
-}
-RED.nodes.registerType("twilio-api",TwilioAPINode);
-
-
-function TwilioOutNode(n) {
- RED.nodes.createNode(this,n);
- this.number = n.number;
-
- this.api = RED.nodes.getNode(n.twilio);
-
- if (this.api) {
- this.twilioClient = twilio(this.api.sid,this.api.token);
- this.fromNumber = this.api.from;
- } else if (twiliokey) {
- this.twilioClient = twilio(twiliokey.account, twiliokey.authtoken);
- this.fromNumber = twiliokey.from;
- } else {
- this.error("missing twilio credentials");
- return;
- }
-
- var node = this;
- this.on("input",function(msg) {
- if (typeof(msg.payload) == 'object') {
- msg.payload = JSON.stringify(msg.payload);
- }
- try {
- // Send SMS
- var tonum = node.number || msg.topic;
- node.twilioClient.sendMessage( {to: tonum, from: node.fromNumber, body: msg.payload}, function(err, response) {
- if (err) {
- node.error(err);
- }
- //console.log(response);
- });
- } catch (err) {
- node.error(err);
- }
+ RED.httpAdmin.post('/twilio-api/:id',function(req,res) {
+ var body = "";
+ req.on('data', function(chunk) {
+ body+=chunk;
+ });
+ req.on('end', function(){
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id)||{};
+ if (newCreds.token == "") {
+ delete credentials.token;
+ } else {
+ credentials.token = newCreds.token;
+ }
+ RED.nodes.addCredentials(req.params.id,credentials);
+ res.send(200);
+ });
});
+
+ function TwilioAPINode(n) {
+ RED.nodes.createNode(this,n);
+ this.sid = n.sid;
+ this.from = n.from;
+ this.name = n.name;
+ var credentials = RED.nodes.getCredentials(n.id);
+ if (credentials) {
+ this.token = credentials.token;
+ }
+ }
+ RED.nodes.registerType("twilio-api",TwilioAPINode);
+
+
+ function TwilioOutNode(n) {
+ RED.nodes.createNode(this,n);
+ this.number = n.number;
+
+ this.api = RED.nodes.getNode(n.twilio);
+
+ if (this.api) {
+ this.twilioClient = twilio(this.api.sid,this.api.token);
+ this.fromNumber = this.api.from;
+ } else if (twiliokey) {
+ this.twilioClient = twilio(twiliokey.account, twiliokey.authtoken);
+ this.fromNumber = twiliokey.from;
+ } else {
+ this.error("missing twilio credentials");
+ return;
+ }
+
+ this.twilioType = n.twilioType;
+ this.url = n.url;
+ var node = this;
+ this.on("input",function(msg) {
+ if (typeof(msg.payload) == 'object') {
+ msg.payload = JSON.stringify(msg.payload);
+ }
+ try {
+ // decide if we are to Send SMS
+ var tonum = node.number || msg.topic;
+ if( this.twilioType == "call" ) {
+ // Make a call
+ var twimlurl = node.url || msg.payload;
+ node.twilioClient.makeCall( {to: tonum, from: node.fromNumber, url: twimlurl}, function(err, response) {
+ if (err) {
+ node.error(err.message);
+ }
+ //console.log(response);
+ });
+ } else {
+ // Send SMS
+ node.twilioClient.sendMessage( {to: tonum, from: node.fromNumber, body: msg.payload}, function(err, response) {
+ if (err) {
+ node.error(err.message);
+ }
+ //console.log(response);
+ });
+ }
+
+ } catch (err) {
+ node.error(err);
+ }
+ });
+ }
+ RED.nodes.registerType("twilio out",TwilioOutNode);
}
-RED.nodes.registerType("twilio out",TwilioOutNode);
diff --git a/social/twilio/LICENSE b/social/twilio/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/social/twilio/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/social/twilio/README.md b/social/twilio/README.md
new file mode 100644
index 00000000..3e7b315a
--- /dev/null
+++ b/social/twilio/README.md
@@ -0,0 +1,26 @@
+node-red-node-twilio
+====================
+
+A Node-RED node to send SMS messages via the Twilio service.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-twilio
+
+
+Usage
+-----
+
+Sends an SMS message or make a voice call using the Twilio service.
+
+The Twilio out node is configured to send SMS or make call, depending on the option selected you enter the phone number or phone number and a URL to create the TWiML response file.
+
+msg.payload is used as the body of the message. The node can be configured with the number
+ to send the message to. Alternatively, if the number is left blank, it can be set using msg.topic. The payload can also be the URL to create the TWiML response file.
+
+You must have an account with Twilio to use this node. You can register for one here.
+
+There is an example of using this node to create a simple IVR here.
diff --git a/social/twilio/icons/twilio.png b/social/twilio/icons/twilio.png
index ada41a2c..f8f91a59 100644
Binary files a/social/twilio/icons/twilio.png and b/social/twilio/icons/twilio.png differ
diff --git a/social/twilio/package.json b/social/twilio/package.json
new file mode 100644
index 00000000..ab4b7bd7
--- /dev/null
+++ b/social/twilio/package.json
@@ -0,0 +1,23 @@
+{
+ "name" : "node-red-node-twilio",
+ "version" : "0.0.4",
+ "description" : "A Node-RED node to send SMS messages via the Twilio service.",
+ "dependencies" : {
+ "twilio" : "1.6.0"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/social/twilio"
+ },
+ "license": "Apache-v2.0",
+ "keywords": [ "node-red", "twilio", "sms" ],
+ "node-red" : {
+ "nodes" : {
+ "twilio": "56-twilio.js"
+ }
+ },
+ "contributors": [
+ {"name": "Andrew Lindsay"},
+ {"name": "Dave Conway-Jones"}
+ ]
+}
diff --git a/social/xmpp/92-xmpp.html b/social/xmpp/92-xmpp.html
index b16f4c5a..5b9b8c9c 100644
--- a/social/xmpp/92-xmpp.html
+++ b/social/xmpp/92-xmpp.html
@@ -1,5 +1,5 @@
-
+
+
+
+
+
+
-
+
+
+
+
diff --git a/social/xmpp/92-xmpp.js b/social/xmpp/92-xmpp.js
index f7755bc3..06373a6e 100644
--- a/social/xmpp/92-xmpp.js
+++ b/social/xmpp/92-xmpp.js
@@ -1,5 +1,5 @@
/**
- * Copyright 2013 IBM Corp.
+ * Copyright 2013,2014 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,48 +14,92 @@
* limitations under the License.
**/
-var orig=console.warn;
-console.warn=(function() { // suppress warning from stringprep when not needed)
- var orig=console.warn;
- return function() {
- //orig.apply(console, arguments);
- };
-})();
+module.exports = function(RED) {
+"use strict";
+var XMPP = require('simple-xmpp');
-var RED = require(process.env.NODE_RED_HOME+"/red/red");
-var xmpp = require('simple-xmpp');
-console.warn = orig;
+try { var xmppkey = RED.settings.xmpp || require(process.env.NODE_RED_HOME+"/../xmppkeys.js"); }
+catch(err) { }
-try {
- var xmppkey = RED.settings.xmpp || require(process.env.NODE_RED_HOME+"/../xmppkeys.js");
-} catch(err) {
- throw new Error("Failed to load XMPP credentials");
-}
-
-function XmppNode(n) {
+function XMPPServerNode(n) {
RED.nodes.createNode(this,n);
this.server = n.server;
this.port = n.port;
+ this.nickname = n.nickname;
+ var credentials = RED.nodes.getCredentials(n.id);
+ if (credentials) {
+ this.username = credentials.user;
+ this.password = credentials.password;
+ }
+}
+RED.nodes.registerType("xmpp-server",XMPPServerNode);
+
+var querystring = require('querystring');
+
+RED.httpAdmin.get('/xmpp-server/:id',function(req,res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!=="")}));
+ } else if (xmppkey && xmppkey.jid && xmppkey.password) {
+ RED.nodes.addCredentials(req.params.id,{user:xmppkey.jid, password:xmppkey.password, global:true});
+ credentials = RED.nodes.getCredentials(req.params.id);
+ res.send(JSON.stringify({user:credentials.user,global:credentials.global,hasPassword:(credentials.password&&credentials.password!=="")}));
+ } else {
+ res.send(JSON.stringify({}));
+ }
+});
+
+RED.httpAdmin.delete('/xmpp-server/:id',function(req,res) {
+ RED.nodes.deleteCredentials(req.params.id);
+ res.send(200);
+});
+
+RED.httpAdmin.post('/xmpp-server/:id',function(req,res) {
+ var body = "";
+ req.on('data', function(chunk) {
+ body+=chunk;
+ });
+ req.on('end', function(){
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id)||{};
+ if (newCreds.user == null || newCreds.user === "") {
+ delete credentials.user;
+ } else {
+ credentials.user = newCreds.user;
+ }
+ if (newCreds.password === "") {
+ delete credentials.password;
+ } else {
+ credentials.password = newCreds.password||credentials.password;
+ }
+ RED.nodes.addCredentials(req.params.id,credentials);
+ res.send(200);
+ });
+});
+
+
+function XmppInNode(n) {
+ RED.nodes.createNode(this,n);
+ this.server = n.server;
+
+ this.serverConfig = RED.nodes.getNode(this.server);
+ this.host = this.serverConfig.server;
+ this.port = this.serverConfig.port;
+ this.nick = this.serverConfig.nickname || "Node-RED";
+ this.userid = this.serverConfig.username;
+ this.password = this.serverConfig.password;
+
this.join = n.join || false;
- this.nick = n.nick || "Node-RED";
this.sendAll = n.sendObject;
this.to = n.to || "";
var node = this;
- setTimeout(function() {
- xmpp.connect({
- jid : xmppkey.jid,
- password : xmppkey.password,
- host : this.server,
- port : this.port,
- skipPresence : true,
- reconnect : false
- });
- }, 5000);
+ var xmpp = new XMPP.SimpleXMPP();
xmpp.on('online', function() {
- node.log('connected to '+node.server);
- xmpp.setPresence('online', node.nick+' online');
+ node.log('connected to '+node.host+":"+node.port);
+ node.status({fill:"green",shape:"dot",text:"connected"});
+ //xmpp.setPresence('online', node.nick+' online');
if (node.join) {
xmpp.join(node.to+'/'+node.nick);
}
@@ -84,39 +128,126 @@ function XmppNode(n) {
});
xmpp.on('error', function(err) {
- console.error(err);
+ console.error("error",err);
});
xmpp.on('close', function(err) {
node.log('connection closed');
+ node.status({fill:"red",shape:"ring",text:"not connected"});
});
xmpp.on('subscribe', function(from) {
xmpp.acceptSubscription(from);
});
- this.on("input", function(msg) {
- var to = msg.topic;
- if (node.to != "") { to = node.to; }
- if (node.sendAll) {
- xmpp.send(to, JSON.stringify(msg), node.join);
- }
- else {
- xmpp.send(to, msg.payload, node.join);
- }
- });
+ // Now actually make the connection
+ try {
+ xmpp.connect({
+ jid : node.userid,
+ password : node.password,
+ host : node.host,
+ port : node.port,
+ skipPresence : true,
+ reconnect : false
+ });
+ } catch(e) {
+ node.error("Bad xmpp configuration");
+ node.status({fill:"red",shape:"ring",text:"not connected"});
+ }
- this.on("close", function() {
- xmpp.setPresence('offline');
- try {
- xmpp.disconnect();
- // TODO - DCJ NOTE... this is not good. It leaves the connection up over a restart - which will end up with bad things happening...
- // (but requires the underlying xmpp lib to be fixed, which does have an open bug request on fixing the close method - and a work around.
- // see - https://github.com/simple-xmpp/node-simple-xmpp/issues/12 for the fix
- } catch(e) {
- this.warn("Due to an underlying bug in the xmpp library this does not disconnect old sessions. This is bad... A restart would be better.");
- }
+ node.on("close", function(done) {
+ //xmpp.setPresence('offline');
+ if (xmpp.conn) { xmpp.conn.end(); }
+ xmpp = null;
+ done();
});
}
+RED.nodes.registerType("xmpp in",XmppInNode);
-RED.nodes.registerType("xmpp",XmppNode);
+function XmppOutNode(n) {
+ RED.nodes.createNode(this,n);
+ this.server = n.server;
+
+ this.serverConfig = RED.nodes.getNode(this.server);
+ this.host = this.serverConfig.server;
+ this.port = this.serverConfig.port;
+ this.nick = this.serverConfig.nickname || "Node-RED";
+ this.userid = this.serverConfig.username;
+ this.password = this.serverConfig.password;
+
+ this.join = n.join || false;
+ this.sendAll = n.sendObject;
+ this.to = n.to || "";
+ var node = this;
+
+ var xmpp = new XMPP.SimpleXMPP();
+
+ xmpp.on('online', function() {
+ node.log('connected to '+node.host+":"+node.port);
+ node.status({fill:"green",shape:"dot",text:"connected"});
+ xmpp.setPresence('online', node.nick+' online');
+ if (node.join) {
+ xmpp.join(node.to+'/'+node.nick);
+ }
+ });
+
+ xmpp.on('error', function(err) {
+ console.error("error",err);
+ });
+
+ xmpp.on('close', function(err) {
+ node.log('connection closed');
+ node.status({fill:"red",shape:"ring",text:"not connected"});
+ });
+
+ xmpp.on('subscribe', function(from) {
+ xmpp.acceptSubscription(from);
+ });
+
+ // Now actually make the connection
+ try {
+ xmpp.connect({
+ jid : node.userid,
+ password : node.password,
+ host : node.host,
+ port : node.port,
+ skipPresence : true,
+ reconnect : false
+ });
+ } catch(e) {
+ node.error("Bad xmpp configuration");
+ node.status({fill:"red",shape:"ring",text:"not connected"});
+ }
+
+ node.on("input", function(msg) {
+ if (msg.presence) {
+ if (['away', 'dnd', 'xa','chat'].indexOf(msg.presence) > -1 ) {
+ xmpp.setPresence(msg.presence, msg.payload);
+ }
+ else { node.warn("Can't set presence - invalid value"); }
+ }
+ else {
+ var to = msg.topic;
+ if (node.to !== "") { to = node.to; }
+ if (node.sendAll) {
+ xmpp.send(to, JSON.stringify(msg), node.join);
+ }
+ else if (msg.payload) {
+ if (typeof(msg.payload) === "object") {
+ xmpp.send(to, JSON.stringify(msg.payload), node.join);
+ } else {
+ xmpp.send(to, msg.payload.toString(), node.join);
+ }
+ }
+ }
+ });
+
+ node.on("close", function() {
+ xmpp.setPresence('offline');
+ if (xmpp.conn) { xmpp.conn.end(); }
+ xmpp = null;
+ });
+}
+RED.nodes.registerType("xmpp out",XmppOutNode);
+
+}
diff --git a/social/xmpp/LICENSE b/social/xmpp/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/social/xmpp/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/social/xmpp/README.md b/social/xmpp/README.md
new file mode 100644
index 00000000..e9aed75e
--- /dev/null
+++ b/social/xmpp/README.md
@@ -0,0 +1,44 @@
+node-red-node-xmpp
+==================
+
+A Node-RED node to talk to an XMPP server.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-xmpp
+
+
+Usage
+-----
+
+Provides two nodes - one to send messages, and one to receive.
+
+###Receive
+
+Connects to an XMPP server to receive messages.
+
+The Buddy field is the id of the buddy or room you want to receive messages from.
+
+Incoming messages will appear as msg.payload on the first output, while msg.topic will contain who it is from.
+
+The second output will show the presence and status of a user in msg.payload. Again msg.topic will hold the user.
+
+###Send
+
+Connects to an XMPP server to send messages.
+
+The To field is optional. If not set the msg.topic property of the message is used to set that value.
+
+If you are joining a chat room then the To field must be filled in with the room name.
+
+You may also send a msg with msg.presence to set your presence to one of
+
+ 1. chat
+ 2. away
+ 3. dnd
+ 4. xa
+
+If you do so then the msg.payload is used to set your status message.
diff --git a/social/xmpp/icons/xmpp.png b/social/xmpp/icons/xmpp.png
index 57e43fc4..636847e3 100644
Binary files a/social/xmpp/icons/xmpp.png and b/social/xmpp/icons/xmpp.png differ
diff --git a/social/xmpp/package.json b/social/xmpp/package.json
new file mode 100644
index 00000000..0da9298d
--- /dev/null
+++ b/social/xmpp/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-xmpp",
+ "version" : "0.0.2",
+ "description" : "A Node-RED node to talk to an XMPP server",
+ "dependencies" : {
+ "simple-xmpp" : "0.1.19"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/social/xmpp"
+ },
+ "license": "Apache-2.0",
+ "keywords": [ "node-red", "xmpp" ],
+ "node-red" : {
+ "nodes" : {
+ "xmpp": "92-xmpp.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/storage/ddb/69-ddbout.html b/storage/ddb/69-ddbout.html
index 3f0859bd..e8db2edd 100644
--- a/storage/ddb/69-ddbout.html
+++ b/storage/ddb/69-ddbout.html
@@ -16,19 +16,19 @@
diff --git a/storage/ddb/69-ddbout.js b/storage/ddb/69-ddbout.js
index 939d7d23..1d803bb9 100644
--- a/storage/ddb/69-ddbout.js
+++ b/storage/ddb/69-ddbout.js
@@ -21,6 +21,7 @@ var attrWrapper = require("dynamodb-data-types").AttributeValue;
function DDBOutNode(n) {
RED.nodes.createNode(this, n);
+ this.warn("This node has been deprecated and will be deleted in a future release. Please update your flow to use the version from npm. Note: you cannot have both this and the npm version installed at the same time.");
this.credentials = RED.nodes.getNode(n.credentials);
this.region = n.region || "us-east-1";
this.table = n.table;
@@ -32,13 +33,11 @@ function DDBOutNode(n) {
var ddb = new aws.DynamoDB();
this.on("input", function(msg) {
- if (msg != null) {
- ddb.putItem({ "TableName": this.table,
- "Item": attrWrapper.wrap(msg.payload) },
+ ddb.putItem({ "TableName": this.table,
+ "Item": attrWrapper.wrap(msg.payload) },
function(err, data) {
- err && util.log(err);
- });
- }
+ if (err) { util.log(err); }
+ });
});
}
RED.nodes.registerType("ddb out", DDBOutNode);
diff --git a/storage/ddb/aws.html b/storage/ddb/aws.html
index 5c26c904..8d6aeb87 100644
--- a/storage/ddb/aws.html
+++ b/storage/ddb/aws.html
@@ -16,11 +16,11 @@
diff --git a/storage/leveldb/67-leveldb.html b/storage/leveldb/67-leveldb.html
index 72ead707..e889a15a 100644
--- a/storage/leveldb/67-leveldb.html
+++ b/storage/leveldb/67-leveldb.html
@@ -16,7 +16,7 @@
@@ -35,11 +35,11 @@
@@ -75,18 +75,18 @@
diff --git a/storage/leveldb/67-leveldb.js b/storage/leveldb/67-leveldb.js
index f4a91db6..9e1d56bf 100644
--- a/storage/leveldb/67-leveldb.js
+++ b/storage/leveldb/67-leveldb.js
@@ -14,81 +14,83 @@
* limitations under the License.
**/
-var RED = require(process.env.NODE_RED_HOME+"/red/red");
-var lvldb = require('level');
+module.exports = function(RED) {
+ "use strict";
+ var lvldb = require('level');
-function LevelNode(n) {
- RED.nodes.createNode(this,n);
- this.dbname = n.db;
- var node = this;
- lvldb(this.dbname, function(err, db) {
- if (err) node.error(err);
- node.db = db;
- });
- this.on('close', function() {
- if (node.db) { node.db.close(); }
- });
-}
-RED.nodes.registerType("leveldbase",LevelNode);
-
-
-function LevelDBNodeIn(n) {
- RED.nodes.createNode(this,n);
- this.level = n.level;
- this.levelConfig = RED.nodes.getNode(this.level);
-
- if (this.levelConfig) {
+ function LevelNode(n) {
+ RED.nodes.createNode(this,n);
+ this.dbname = n.db;
var node = this;
- node.on("input", function(msg) {
- if (typeof msg.topic === 'string') {
- node.levelConfig.db.get(msg.topic, function(err, value) {
- if (err) {
- //node.warn(err);
- // for some reason they treat nothing found as an error...
- msg.payload = null; // so we should return null
- }
- else { msg.payload = value; }
- node.send(msg);
- });
- }
- else {
- if (typeof msg.topic !== 'string') node.error("msg.topic (the key is not defined");
- }
+ lvldb(this.dbname, function(err, db) {
+ if (err) { node.error(err); }
+ node.db = db;
+ });
+ this.on('close', function() {
+ if (node.db) { node.db.close(); }
});
}
- else {
- this.error("LevelDB database name not configured");
- }
-}
-RED.nodes.registerType("leveldb in",LevelDBNodeIn);
+ RED.nodes.registerType("leveldbase",LevelNode);
-function LevelDBNodeOut(n) {
- RED.nodes.createNode(this,n);
- this.level = n.level;
- this.operation = n.operation;
- this.levelConfig = RED.nodes.getNode(this.level);
+ function LevelDBNodeIn(n) {
+ RED.nodes.createNode(this,n);
+ this.level = n.level;
+ this.levelConfig = RED.nodes.getNode(this.level);
- if (this.levelConfig) {
- var node = this;
- node.on("input", function(msg) {
- if (typeof msg.topic === 'string') {
- if (node.operation === "delete") {
- node.levelConfig.db.del(msg.topic);
- }
- else {
- node.levelConfig.db.put(msg.topic, msg.payload, function(err) {
- if (err) node.error(err);
+ if (this.levelConfig) {
+ var node = this;
+ node.on("input", function(msg) {
+ if (typeof msg.topic === 'string') {
+ node.levelConfig.db.get(msg.topic, function(err, value) {
+ if (err) {
+ //node.warn(err);
+ // for some reason they treat nothing found as an error...
+ msg.payload = null; // so we should return null
+ }
+ else { msg.payload = value; }
+ node.send(msg);
});
}
- }
- else {
- if (typeof msg.topic !== 'string') node.error("msg.topic (the key is not defined");
- }
- });
+ else {
+ if (typeof msg.topic !== 'string') { node.error("msg.topic (the key is not defined"); }
+ }
+ });
+ }
+ else {
+ this.error("LevelDB database name not configured");
+ }
}
- else {
- this.error("LevelDB database name not configured");
+ RED.nodes.registerType("leveldb in",LevelDBNodeIn);
+
+
+ function LevelDBNodeOut(n) {
+ RED.nodes.createNode(this,n);
+ this.level = n.level;
+ this.operation = n.operation;
+ this.levelConfig = RED.nodes.getNode(this.level);
+
+ if (this.levelConfig) {
+ var node = this;
+ node.on("input", function(msg) {
+ if (typeof msg.topic === 'string') {
+ if (node.operation === "delete") {
+ node.levelConfig.db.del(msg.topic);
+ }
+ else {
+ node.levelConfig.db.put(msg.topic, msg.payload, function(err) {
+ if (err) { node.error(err); }
+ });
+ }
+ }
+ else {
+ if (typeof msg.topic !== 'string') { node.error("msg.topic (the key is not defined"); }
+ }
+ });
+ }
+ else {
+ this.error("LevelDB database name not configured");
+ }
}
+ RED.nodes.registerType("leveldb out",LevelDBNodeOut);
}
-RED.nodes.registerType("leveldb out",LevelDBNodeOut);
diff --git a/storage/leveldb/LICENSE b/storage/leveldb/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/storage/leveldb/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/storage/leveldb/README.md b/storage/leveldb/README.md
new file mode 100644
index 00000000..7dbc770d
--- /dev/null
+++ b/storage/leveldb/README.md
@@ -0,0 +1,26 @@
+node-red-node-leveldb
+=====================
+A Node-RED node to read and write to a LevelDB database.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-leveldb
+
+
+Usage
+-----
+
+Allows basic access to a LevelDB database.
+
+Uses LevelDB for a simple key value pair database.
+
+There are two node to choose from...
+
+Use one node to either put (store) the msg.payload to the named database file, using msg.topic as the key, or to delete information select delete in the properties dialogue and again use msg.topic as the key..
+
+Use the other node to get, or retrieve the data already saved in the database.
+
+Again use msg.topic to hold the key for the database, and the result is returned in msg.payload. If nothing is found for the key then null is returned.
diff --git a/storage/leveldb/icons/leveldb.png b/storage/leveldb/icons/leveldb.png
new file mode 100644
index 00000000..55760c7d
Binary files /dev/null and b/storage/leveldb/icons/leveldb.png differ
diff --git a/storage/leveldb/package.json b/storage/leveldb/package.json
new file mode 100644
index 00000000..066c9362
--- /dev/null
+++ b/storage/leveldb/package.json
@@ -0,0 +1,24 @@
+{
+ "name" : "node-red-node-leveldb",
+ "version" : "0.0.1",
+ "description" : "A Node-RED node to read and write to a LevelDB database",
+ "dependencies" : {
+ "level" : "0.18.0"
+ },
+ "repository" : {
+ "type":"git",
+ "url":"https://github.com/node-red/node-red-nodes/tree/master/storage/leveldb"
+ },
+ "license": "Apache",
+ "keywords": [ "node-red", "leveldb" ],
+ "node-red" : {
+ "nodes" : {
+ "leveldb": "67-leveldb.js"
+ }
+ },
+ "author": {
+ "name": "Dave Conway-Jones",
+ "email": "ceejay@vnet.ibm.com",
+ "url": "http://nodered.org"
+ }
+}
diff --git a/storage/mysql/68-mysql.html b/storage/mysql/68-mysql.html
index a68e642b..aa66dc57 100644
--- a/storage/mysql/68-mysql.html
+++ b/storage/mysql/68-mysql.html
@@ -16,25 +16,29 @@
diff --git a/storage/mysql/68-mysql.js b/storage/mysql/68-mysql.js
index d4141130..c4f889ed 100644
--- a/storage/mysql/68-mysql.js
+++ b/storage/mysql/68-mysql.js
@@ -14,182 +14,155 @@
* limitations under the License.
**/
-var RED = require(process.env.NODE_RED_HOME+"/red/red");
-var reconnect = RED.settings.mysqlReconnectTime || 30000;
-var mysqldb = require('mysql');
-var querystring = require('querystring');
+module.exports = function(RED) {
+ "use strict";
+ var reconnect = RED.settings.mysqlReconnectTime || 30000;
+ var mysqldb = require('mysql');
+ var querystring = require('querystring');
-RED.httpAdmin.get('/MySQLdatabase/:id',function(req,res) {
- var credentials = RED.nodes.getCredentials(req.params.id);
- if (credentials) {
- res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!="")}));
- } else {
- res.send(JSON.stringify({}));
- }
-});
-
-RED.httpAdmin.delete('/MySQLdatabase/:id',function(req,res) {
- RED.nodes.deleteCredentials(req.params.id);
- res.send(200);
-});
-
-RED.httpAdmin.post('/MySQLdatabase/:id',function(req,res) {
- var body = "";
- req.on('data', function(chunk) {
- body+=chunk;
+ RED.httpAdmin.get('/MySQLdatabase/:id',function(req,res) {
+ var credentials = RED.nodes.getCredentials(req.params.id);
+ if (credentials) {
+ res.send(JSON.stringify({user:credentials.user,hasPassword:(credentials.password&&credentials.password!=="")}));
+ } else {
+ res.send(JSON.stringify({}));
+ }
});
- req.on('end', function(){
- var newCreds = querystring.parse(body);
- var credentials = RED.nodes.getCredentials(req.params.id)||{};
- if (newCreds.user == null || newCreds.user == "") {
- delete credentials.user;
- } else {
- credentials.user = newCreds.user;
- }
- if (newCreds.password == "") {
- delete credentials.password;
- } else {
- credentials.password = newCreds.password||credentials.password;
- }
- RED.nodes.addCredentials(req.params.id,credentials);
+
+ RED.httpAdmin.delete('/MySQLdatabase/:id',function(req,res) {
+ RED.nodes.deleteCredentials(req.params.id);
res.send(200);
});
-});
+
+ RED.httpAdmin.post('/MySQLdatabase/:id',function(req,res) {
+ var body = "";
+ req.on('data', function(chunk) {
+ body+=chunk;
+ });
+ req.on('end', function(){
+ var newCreds = querystring.parse(body);
+ var credentials = RED.nodes.getCredentials(req.params.id)||{};
+ if (newCreds.user == null || newCreds.user === "") {
+ delete credentials.user;
+ } else {
+ credentials.user = newCreds.user;
+ }
+ if (newCreds.password === "") {
+ delete credentials.password;
+ } else {
+ credentials.password = newCreds.password||credentials.password;
+ }
+ RED.nodes.addCredentials(req.params.id,credentials);
+ res.send(200);
+ });
+ });
-function MySQLNode(n) {
- RED.nodes.createNode(this,n);
- this.host = n.host;
- this.port = n.port;
+ function MySQLNode(n) {
+ RED.nodes.createNode(this,n);
+ this.host = n.host;
+ this.port = n.port;
+ this.tz = n.tz || "local";
- this.connected = false;
- this.connecting = false;
+ this.connected = false;
+ this.connecting = false;
- if (n.user) {
var credentials = {};
- credentials.user = n.user;
- credentials.password = n.pass;
- RED.nodes.addCredentials(n.id,credentials);
- this.user = n.user;
- this.password = n.pass;
- } else {
- var credentials = RED.nodes.getCredentials(n.id);
- if (credentials) {
- this.user = credentials.user;
- this.password = credentials.password;
- }
- }
-
- this.dbname = n.db;
- var node = this;
-
- function doConnect() {
- node.connecting = true;
- node.connection = mysqldb.createConnection({
- host : node.host,
- port : node.port,
- user : node.user,
- password : node.password,
- database : node.dbname,
- insecureAuth: true
- });
-
- node.connection.connect(function(err) {
- node.connecting = false;
- if (err) {
- node.warn(err);
- node.tick = setTimeout(doConnect, reconnect);
- } else {
- node.connected = true;
+ if (n.user) {
+ credentials.user = n.user;
+ credentials.password = n.pass;
+ RED.nodes.addCredentials(n.id,credentials);
+ this.user = n.user;
+ this.password = n.pass;
+ } else {
+ credentials = RED.nodes.getCredentials(n.id);
+ if (credentials) {
+ this.user = credentials.user;
+ this.password = credentials.password;
}
- });
-
- node.connection.on('error', function(err) {
- node.connected = false;
- if (err.code === 'PROTOCOL_CONNECTION_LOST') {
- doConnect(); // silently reconnect...
- } else {
- node.error(err);
- doConnect();
- }
- });
- }
-
- this.connect = function() {
- if (!this.connected && !this.connecting) {
- doConnect();
}
- }
- this.on('close', function () {
- if (this.tick) { clearTimeout(this.tick); }
- if (this.connection) {
- node.connection.end(function(err) {
- if (err) node.error(err);
+ this.dbname = n.db;
+ var node = this;
+
+ function doConnect() {
+ node.connecting = true;
+ node.connection = mysqldb.createConnection({
+ host : node.host,
+ port : node.port,
+ user : node.user,
+ password : node.password,
+ database : node.dbname,
+ timezone : node.tz,
+ insecureAuth: true
+ });
+
+ node.connection.connect(function(err) {
+ node.connecting = false;
+ if (err) {
+ node.warn(err);
+ node.tick = setTimeout(doConnect, reconnect);
+ } else {
+ node.connected = true;
+ }
+ });
+
+ node.connection.on('error', function(err) {
+ node.connected = false;
+ if (err.code === 'PROTOCOL_CONNECTION_LOST') {
+ doConnect(); // silently reconnect...
+ } else {
+ node.error(err);
+ doConnect();
+ }
});
}
- });
-}
-RED.nodes.registerType("MySQLdatabase",MySQLNode);
-
-function MysqlDBNodeIn(n) {
- RED.nodes.createNode(this,n);
- this.mydb = n.mydb;
- this.mydbConfig = RED.nodes.getNode(this.mydb);
-
- if (this.mydbConfig) {
- this.mydbConfig.connect();
- var node = this;
- node.on("input", function(msg) {
- if (typeof msg.topic === 'string') {
- //console.log("query:",msg.topic);
- node.mydbConfig.connection.query(msg.topic, function(err, rows) {
- if (err) { node.warn(err); }
- else {
- msg.payload = rows;
- node.send(msg);
- }
- });
+ this.connect = function() {
+ if (!this.connected && !this.connecting) {
+ doConnect();
}
- else {
- if (typeof msg.topic !== 'string') node.error("msg.topic : the query is not defined as a string");
+ }
+
+ this.on('close', function () {
+ if (this.tick) { clearTimeout(this.tick); }
+ if (this.connection) {
+ node.connection.end(function(err) {
+ if (err) { node.error(err); }
+ });
}
});
}
- else {
- this.error("MySQL database not configured");
+ RED.nodes.registerType("MySQLdatabase",MySQLNode);
+
+
+ function MysqlDBNodeIn(n) {
+ RED.nodes.createNode(this,n);
+ this.mydb = n.mydb;
+ this.mydbConfig = RED.nodes.getNode(this.mydb);
+
+ if (this.mydbConfig) {
+ this.mydbConfig.connect();
+ var node = this;
+ node.on("input", function(msg) {
+ if (typeof msg.topic === 'string') {
+ //console.log("query:",msg.topic);
+ node.mydbConfig.connection.query(msg.topic, function(err, rows) {
+ if (err) { node.warn(err); }
+ else {
+ msg.payload = rows;
+ node.send(msg);
+ }
+ });
+ }
+ else {
+ if (typeof msg.topic !== 'string') { node.error("msg.topic : the query is not defined as a string"); }
+ }
+ });
+ }
+ else {
+ this.error("MySQL database not configured");
+ }
}
+ RED.nodes.registerType("mysql",MysqlDBNodeIn);
}
-RED.nodes.registerType("mysql",MysqlDBNodeIn);
-
-
-//function MysqlDBNodeOut(n) {
- //RED.nodes.createNode(this,n);
- //this.level = n.level;
- //this.operation = n.operation;
- //this.levelConfig = RED.nodes.getNode(this.level);
-
- //if (this.levelConfig) {
- //var node = this;
- //node.on("input", function(msg) {
- //if (typeof msg.topic === 'string') {
- //if (node.operation === "delete") {
- //node.levelConfig.db.del(msg.topic);
- //}
- //else {
- //node.levelConfig.db.put(msg.topic, msg.payload, function(err) {
- //if (err) node.error(err);
- //});
- //}
- //}
- //else {
- //if (typeof msg.topic !== 'string') node.error("msg.topic : the key is not defined");
- //}
- //});
- //}
- //else {
- //this.error("MySQL database not configured");
- //}
-//}
-//RED.nodes.registerType("mysql out",MysqlDBNodeOut);
diff --git a/storage/mysql/LICENSE b/storage/mysql/LICENSE
new file mode 100644
index 00000000..f433b1a5
--- /dev/null
+++ b/storage/mysql/LICENSE
@@ -0,0 +1,177 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
diff --git a/storage/mysql/README.md b/storage/mysql/README.md
new file mode 100644
index 00000000..a2be5cb0
--- /dev/null
+++ b/storage/mysql/README.md
@@ -0,0 +1,29 @@
+node-red-node-mysql
+========================
+A Node-RED node to read and write to a MySQL database.
+
+Install
+-------
+
+Run the following command in the root directory of your Node-RED install
+
+ npm install node-red-node-mysql
+
+
+Usage
+-----
+
+Allows basic access to a MySQL database.
+
+This node uses the query operation against the configured database. This does allow both INSERTS and DELETES.
+
+By it's very nature it allows SQL injection... so be careful out there...
+
+The msg.topic must hold the query for the database, and the result is returned in msg.payload.
+
+Typically the returned payload will be an array of the result rows.
+
+If nothing is found for the key then null is returned.
+
+The reconnect retry timeout in milliseconds can be changed by adding a line to settings.js
+ mysqlReconnectTime: 30000,diff --git a/storage/mysql/package.json b/storage/mysql/package.json new file mode 100644 index 00000000..3bd6818e --- /dev/null +++ b/storage/mysql/package.json @@ -0,0 +1,24 @@ +{ + "name" : "node-red-node-mysql", + "version" : "0.0.4", + "description" : "A Node-RED node to read and write to a MySQL database", + "dependencies" : { + "mysql" : "2.3.*" + }, + "repository" : { + "type":"git", + "url":"https://github.com/node-red/node-red-nodes/tree/master/storage/mysql" + }, + "license": "Apache", + "keywords": [ "node-red", "mysql" ], + "node-red" : { + "nodes" : { + "mysql": "68-mysql.js" + } + }, + "author": { + "name": "Dave Conway-Jones", + "email": "ceejay@vnet.ibm.com", + "url": "http://nodered.org" + } +} diff --git a/storage/postgres/110-postgres.html b/storage/postgres/110-postgres.html index 6fae6ac1..399a574d 100644 --- a/storage/postgres/110-postgres.html +++ b/storage/postgres/110-postgres.html @@ -16,19 +16,19 @@ @@ -86,11 +86,11 @@ + + + + + + + + + diff --git a/storage/sqlite/sqlite.js b/storage/sqlite/sqlite.js new file mode 100644 index 00000000..9a7e3b34 --- /dev/null +++ b/storage/sqlite/sqlite.js @@ -0,0 +1,80 @@ +/** + * Copyright 2014 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. + **/ + +module.exports = function(RED) { + "use strict"; + var reconnect = RED.settings.sqliteReconnectTime || 20000; + var sqlite3 = require('sqlite3'); + + function SqliteNodeDB(n) { + RED.nodes.createNode(this,n); + + this.dbname = n.db; + var node = this; + + node.doConnect = function() { + node.db = new sqlite3.Database(node.dbname); + node.db.on('open',function(err) { + if (node.tick) { clearTimeout(node.tick); } + node.log("opened "+node.dbname+" ok"); + }); + node.db.on('error', function(err) { + node.warn(err); + node.log("failed to open "+node.dbname); + node.tick = setTimeout(doConnect, reconnect); + }); + } + + node.on('close', function () { + if (node.tick) { clearTimeout(node.tick); } + if (node.db) { node.db.close(); } + }); + } + RED.nodes.registerType("sqlitedb",SqliteNodeDB); + + + function SqliteNodeIn(n) { + RED.nodes.createNode(this,n); + this.mydb = n.mydb; + this.mydbConfig = RED.nodes.getNode(this.mydb); + + if (this.mydbConfig) { + this.mydbConfig.doConnect(); + var node = this; + node.on("input", function(msg) { + if (typeof msg.topic === 'string') { + //console.log("query:",msg.topic); + node.mydbConfig.db.all(msg.topic, function(err, row) { + if (err) { node.warn(err); } + else { + msg.payload = row; + node.send(msg); + } + }); + } + else { + if (typeof msg.topic !== 'string') { + node.error("msg.topic : the query is not defined as a string"); + } + } + }); + } + else { + this.error("Sqlite database not configured"); + } + } + RED.nodes.registerType("sqlite",SqliteNodeIn); +} diff --git a/test/utility/exif/94-exif_spec.js b/test/utility/exif/94-exif_spec.js new file mode 100644 index 00000000..30087415 --- /dev/null +++ b/test/utility/exif/94-exif_spec.js @@ -0,0 +1,76 @@ +/** + * Copyright 2014 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 sinon = require('sinon'); +var fs = require("fs"); + +var exifNode = require("../../../utility/exif/94-exif.js"); + +var helper = require('../../../../node-red/test/nodes/helper.js'); + +describe('exif node', function() { + + beforeEach(function(done) { + helper.startServer(done); + }); + + afterEach(function(done) { + helper.unload(); + helper.stopServer(done); + }); + + it('extracts location data from Exif data of JPEG', function(done) { + + var exif = require('exif'); + var ExifImage = exif.ExifImage; + + // the jpg file is a single black dot but it was originally a photo taken at IBM Hursley + var data = fs.readFileSync("./exif_test_image.jpg", null); // extracting genuine exif data to be fed back as the result of the stubbed ExifImage constructor + + var eD; + + new ExifImage({ image : data }, function (error, exifData) { + if(error) { + done(error); + } else { + eD = exifData; + } + + var flow = [{id:"exifNode1", type:"exif", wires:[["helperNode1"]]}, + {id:"helperNode1", type:"helper"}]; + + helper.load(exifNode, flow, function() { + var exifNode1 = helper.getNode("exifNode1"); + var helperNode1 = helper.getNode("helperNode1"); + + helperNode1.on("input", function(msg) { + msg.location.lat.should.equal(50.95624); // this data is stored in the jpg file + msg.location.lon.should.equal(-1.36701); + done(); + }); + + var stub = sinon.stub(ExifImage.prototype, 'loadImage', function(error, callback) { + stub.restore(); + callback(null, eD); + }); + + exifNode1.receive({payload:data}); + }); + }); + + }); +}); diff --git a/test/utility/exif/Gruntfile.js b/test/utility/exif/Gruntfile.js new file mode 100644 index 00000000..80a4296e --- /dev/null +++ b/test/utility/exif/Gruntfile.js @@ -0,0 +1,57 @@ +/** + * Copyright 2013, 2014 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. + **/ + +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + simplemocha: { + options: { + globals: ['expect'], + timeout: 3000, + ignoreLeaks: false, + ui: 'bdd', + reporter: 'spec' + }, + all: { src: ['./*_spec.js'] }, + }, + jshint: { + options: { + // http://www.jshint.com/docs/options/ + "asi": true, // allow missing semicolons + "curly": true, // require braces + "eqnull": true, // ignore ==null + "forin": true, // require property filtering in "for in" loops + "immed": true, // require immediate functions to be wrapped in ( ) + "nonbsp": true, // warn on unexpected whitespace breaking chars + //"strict": true, // commented out for now as it causes 100s of warnings, but want to get there eventually + "loopfunc": true, // allow functions to be defined in loops + "sub": true // don't warn that foo['bar'] should be written as foo.bar + }, + all: { + src: ['../../../utility/exif/*.js'] + }, + } + }); + + grunt.loadNpmTasks('grunt-simple-mocha'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-lint-inline'); + + grunt.registerTask('default', + ['jshint:all', 'simplemocha:all']); + +}; diff --git a/test/utility/exif/exif_test_image.jpg b/test/utility/exif/exif_test_image.jpg new file mode 100644 index 00000000..4ce96b3c Binary files /dev/null and b/test/utility/exif/exif_test_image.jpg differ diff --git a/time/79-suncalc.html b/time/79-suncalc.html index 7e595f86..191057cc 100644 --- a/time/79-suncalc.html +++ b/time/79-suncalc.html @@ -1,5 +1,5 @@ + + + + + + diff --git a/utility/daemon/daemon.js b/utility/daemon/daemon.js new file mode 100644 index 00000000..704d7f5e --- /dev/null +++ b/utility/daemon/daemon.js @@ -0,0 +1,106 @@ +/** + * Copyright 2014 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. + **/ + +module.exports = function(RED) { + "use strict"; + var spawn = require('child_process').spawn; + + function DaemonNode(n) { + RED.nodes.createNode(this,n); + this.cmd = n.command; + this.args = n.args.split(" ") || []; + this.cr = n.cr; + this.op = n.op; + this.redo = n.redo; + this.running = false; + var node = this; + + function inputlistener(msg) { + if (msg != null) { + if (!Buffer.isBuffer(msg.payload)) { + if (typeof msg.payload === "object") { msg.payload = JSON.stringify(msg.payload); } + if (typeof msg.payload !== "string") { msg.payload = msg.payload.toString(); } + if (node.cr === true) { msg.payload += "\n"; } + } + if (RED.settings.verbose) { node.log("inp: "+msg.payload); } + if (node.child !== null) { node.child.stdin.write(msg.payload); } + else { node.warn("Command not running"); } + } + } + + function runit() { + node.child = spawn(node.cmd, node.args); + if (RED.settings.verbose) { node.log(node.cmd+" "+JSON.stringify(node.args)); } + node.status({fill:"green",shape:"dot",text:"running"}); + node.running = true; + + node.on("input", inputlistener); + + node.child.stdout.on('data', function (data) { + if (node.op == "string") { data = data.toString(); } + if (node.op == "number") { data = Number(data); } + if (RED.settings.verbose) { node.log("out: "+data); } + if (data && data.trim() !== "") { + var msg = {payload:data}; + node.send([msg,null,null]); + } + }); + + node.child.stderr.on('data', function (data) { + if (node.op == "string") { data = data.toString(); } + if (node.op == "number") { data = Number(data); } + if (RED.settings.verbose) { node.log("err: "+data); } + var msg = {payload:data}; + node.send([null,msg,null]); + }); + + node.child.on('close', function (code) { + if (RED.settings.verbose) { node.log("ret: "+code); } + var msg = {payload:code}; + node.send([null,null,msg]); + node.child = null; + node.running = false; + node.status({fill:"red",shape:"ring",text:"stopped"}); + }); + + node.child.on('error', function (err) { + if (err.errno === "ENOENT") { node.warn('Command not found'); } + else if (err.errno === "EACCES") { node.warn('Command not executable'); } + else { node.log('error: ' + err); } + node.status({fill:"grey",shape:"dot",text:"error"}); + }); + } + + if (node.redo === true) { + var loop = setInterval( function() { + if (!node.running) { + node.removeListener('input', inputlistener); + node.warn("Restarting : " + node.cmd); + runit(); + } + }, 10000); // Restart after 10 secs if required + } + + node.on("close", function() { + if (node.child != null) { node.child.kill('SIGKILL'); } + if (RED.settings.verbose) { node.log(node.cmd+" stopped"); } + clearInterval(loop); + }); + + runit(); + } + RED.nodes.registerType("daemon",DaemonNode); +} diff --git a/utility/daemon/package.json b/utility/daemon/package.json new file mode 100644 index 00000000..8c5dbc84 --- /dev/null +++ b/utility/daemon/package.json @@ -0,0 +1,23 @@ +{ + "name" : "node-red-node-daemon", + "version" : "0.0.1", + "description" : "A Node-RED node that runs and monitors a long running system command.", + "dependencies" : { + }, + "repository" : { + "type":"git", + "url":"https://github.com/node-red/node-red-nodes/tree/master/utility/daemon" + }, + "license": "Apache-v2.0", + "keywords": [ "node-red", "daemon", "shell", "exec" ], + "node-red" : { + "nodes" : { + "daemon": "daemon.js" + } + }, + "author": { + "name": "Dave Conway-Jones", + "email": "ceejay@vnet.ibm.com", + "url": "http://nodered.org" + } +} diff --git a/utility/exif/94-exif.html b/utility/exif/94-exif.html new file mode 100644 index 00000000..689c290c --- /dev/null +++ b/utility/exif/94-exif.html @@ -0,0 +1,49 @@ + + + + + + + diff --git a/utility/exif/94-exif.js b/utility/exif/94-exif.js new file mode 100644 index 00000000..eb7140c7 --- /dev/null +++ b/utility/exif/94-exif.js @@ -0,0 +1,124 @@ +/** + * Copyright 2014 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. + **/ + +module.exports = function(RED) { + "use strict"; + var ExifImage = require('exif').ExifImage; + + function convertDegreesMinutesSecondsToDecimals(degrees, minutes, seconds) { + var result; + result = degrees + (minutes / 60) + (seconds / 3600); + return result; + } + + /*** + * Extracts GPS location information from Exif data. If enough information is + * provided, convert the Exif data into a pair of single floating point number + * latitude/longitude data pairs. Populates msg.location with these. + * Assumes that the msg object will always have exifData available as msg.exif. + * Assume that the GPS data saved into Exif provides a valid value + */ + function addMsgLocationDataFromExifGPSData(msg) { + if(msg.exif.gps) { + var gpsData = msg.exif.gps; // declaring variable purely to make checks more readable + if(gpsData.GPSAltitude) { + if(!msg.location) { + msg.location = {}; + } + msg.location.alt = gpsData.GPSAltitude; + } + if(gpsData.GPSLatitudeRef && gpsData.GPSLatitude && gpsData.GPSLongitudeRef && gpsData.GPSLongitude) { // location can be determined, OK + // The data provided in Exif is in degrees, minutes, seconds, this is to be converted into a single floating point degree + if(gpsData.GPSLatitude.length === 3) { // OK to convert latitude + if(gpsData.GPSLongitude.length === 3) { // OK to convert longitude + var latitude = convertDegreesMinutesSecondsToDecimals(gpsData.GPSLatitude[0], gpsData.GPSLatitude[1], gpsData.GPSLatitude[2]); + latitude = Math.round(latitude * 100000)/100000; + + // (N)orth means positive latitude + // (S)outh means negative latitude + // (E)ast means positive longitude + // (W)est means negative longitude + if(gpsData.GPSLatitudeRef.toString() === 'S' || gpsData.GPSLatitudeRef.toString() === 's') { + latitude = latitude * -1; + } + + var longitude = convertDegreesMinutesSecondsToDecimals(gpsData.GPSLongitude[0], gpsData.GPSLongitude[1], gpsData.GPSLongitude[2]); + longitude = Math.round(longitude * 100000)/100000; + + if(gpsData.GPSLongitudeRef.toString() === 'W' || gpsData.GPSLongitudeRef.toString() === 'w') { + longitude = longitude * -1; + } + if(!msg.location) { + msg.location = {}; + } + msg.location.lat = latitude; + msg.location.lon = longitude; + return; + } else { + node.log("Invalid longitude data, no location information has been added to the message."); + } + } else { + node.log("Invalid latitude data, no location information has been added to the message."); + } + } else { + node.log("The location of this image cannot be determined safely so no location information has been added to the message."); + } + } else { + node.log("No location info found in this image."); + } + } + + function ExifNode(n) { + RED.nodes.createNode(this,n); + var node = this; + this.on("input", function(msg) { + try { + + if(msg.payload) { + var isBuffer = Buffer.isBuffer(msg.payload); + if(isBuffer === true) { + new ExifImage({ image : msg.payload }, function (error, exifData) { + if (error) { + node.error('Failed to extract Exif data from image.'); + node.log('Failed to extract Exif data from image. '+ error); + } else { + //msg.payload remains the same buffer + if(exifData) { + msg.exif = exifData; + addMsgLocationDataFromExifGPSData(msg); + } else { + node.warn("The incoming buffer did not contain Exif data, nothing to do. "); + } + } + node.send(msg); + }); + } else { + node.error("Invalid payload received, the Exif node cannot proceed, no messages sent."); + return; + } + } else { + node.error("No payload received, the Exif node cannot proceed, no messages sent."); + return; + } + } catch (error) { + node.error("An error occurred while extracting Exif information. Please check the log for details."); + node.log('Error: '+error.message); + return; + } + }); + } + RED.nodes.registerType("exif",ExifNode); +} diff --git a/utility/exif/LICENSE b/utility/exif/LICENSE new file mode 100644 index 00000000..f433b1a5 --- /dev/null +++ b/utility/exif/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/utility/exif/README.md b/utility/exif/README.md new file mode 100644 index 00000000..47d14f7a --- /dev/null +++ b/utility/exif/README.md @@ -0,0 +1,23 @@ +node-red-node-exif +================== + +A Node-RED node to extract Exif information from JPEG images. + +Install +------- + +Run the following command in the root directory of your Node-RED install + + npm install node-red-node-exif + + +Usage +----- + +Extracts Exif information from JPEG images. + +This node expects an incoming JPEG image as a buffer. If Exif data is present, it extracts the data into a **msg.exif** object. + +If the Exif data also contains location information this is extracted as **msg.location**. + +**msg.payload** retains the original, unmodified image buffer. diff --git a/utility/exif/package.json b/utility/exif/package.json new file mode 100644 index 00000000..ba12c7d0 --- /dev/null +++ b/utility/exif/package.json @@ -0,0 +1,23 @@ +{ + "name" : "node-red-node-exif", + "version" : "0.0.1", + "description" : "A Node-RED node that extracts Exif information from JPEG image buffers.", + "dependencies" : { + "exif": "0.4.0" + }, + "repository" : { + "type":"git", + "url":"https://github.com/node-red/node-red-nodes/tree/master/utility/exif" + }, + "license": "Apache-v2.0", + "keywords": [ "node-red", "exif"], + "node-red" : { + "nodes" : { + "exif": "94-exif.js" + } + }, + "contributors": [ + {"name": "Dave Conway-Jones"}, + {"name": "Zoltan Balogh"} + ] +}