diff --git a/analysis/wordpos/72-wordpos.html b/analysis/wordpos/72-wordpos.html new file mode 100644 index 00000000..b50156ea --- /dev/null +++ b/analysis/wordpos/72-wordpos.html @@ -0,0 +1,57 @@ + + + + + + + diff --git a/analysis/wordpos/72-wordpos.js b/analysis/wordpos/72-wordpos.js new file mode 100644 index 00000000..0725cb1e --- /dev/null +++ b/analysis/wordpos/72-wordpos.js @@ -0,0 +1,34 @@ +/** + * 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("../../red/red"); +var util = require("util"); +var WordPos = require('wordpos'); + +var wordpos = new WordPos(); + +function WordPOSNode(n) { + RED.nodes.createNode(this,n); + this.on("input", function(msg) { + var node = this; + wordpos.getPOS(msg.payload, function (result) { + msg.pos = result; + node.send(msg); + }); + }); +} + +RED.nodes.registerType("wordpos",WordPOSNode); diff --git a/hardware/blink/76-blinkstick.html b/hardware/blink/76-blinkstick.html new file mode 100644 index 00000000..1bef4306 --- /dev/null +++ b/hardware/blink/76-blinkstick.html @@ -0,0 +1,50 @@ + + + + + + + diff --git a/hardware/blink/76-blinkstick.js b/hardware/blink/76-blinkstick.js new file mode 100644 index 00000000..cae30ca8 --- /dev/null +++ b/hardware/blink/76-blinkstick.js @@ -0,0 +1,62 @@ +/** + * 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("../../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.html b/hardware/blink/77-blink1.html new file mode 100644 index 00000000..00579ce8 --- /dev/null +++ b/hardware/blink/77-blink1.html @@ -0,0 +1,52 @@ + + + + + + + diff --git a/hardware/blink/77-blink1.js b/hardware/blink/77-blink1.js new file mode 100644 index 00000000..236683ed --- /dev/null +++ b/hardware/blink/77-blink1.js @@ -0,0 +1,60 @@ +/** + * 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("../../red/red"); +var Blink1 = require("node-blink1"); + +function Blink1Node(n) { + RED.nodes.createNode(this,n); + this.fade = 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) { + if (blink1) { + 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 do fancy colours by name here if you want... + node.warn("Blink1 : invalid msg : "+msg.payload); + } + } + else { + node.warn("No Blink1 found"); + } + }); + var blink1 = new Blink1.Blink1(); + } + catch(e) { + node.error("No Blink1 found"); + } +} + +RED.nodes.registerType("blink1",Blink1Node); diff --git a/social/notify/57-notify.html b/social/notify/57-notify.html new file mode 100644 index 00000000..67c04cbf --- /dev/null +++ b/social/notify/57-notify.html @@ -0,0 +1,55 @@ + + + + + + + diff --git a/social/notify/57-notify.js b/social/notify/57-notify.js new file mode 100644 index 00000000..9330966d --- /dev/null +++ b/social/notify/57-notify.js @@ -0,0 +1,39 @@ +/** + * 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("../../red/red"); +var growl = require('growl'); +var imagefile = __dirname+"/../../public/mqtt-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 }); + } + }); +} + +RED.nodes.registerType("notify",NotifyNode); diff --git a/social/prowl/57-prowl.html b/social/prowl/57-prowl.html new file mode 100644 index 00000000..6a897f79 --- /dev/null +++ b/social/prowl/57-prowl.html @@ -0,0 +1,63 @@ + + + + + + + diff --git a/social/prowl/57-prowl.js b/social/prowl/57-prowl.js new file mode 100644 index 00000000..d59dc2a3 --- /dev/null +++ b/social/prowl/57-prowl.js @@ -0,0 +1,67 @@ +/** + * 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("../../red/red"); +var Prowl = require('node-prowl'); +var util = require('util'); + +// 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 = require("../../settings").prowl || require("../../../pushkey.js"); +} +catch(err) { + util.log("[57-prowl.js] Error: Failed to load Prowl credentials"); +} + +if (pushkey) { + 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); + } + if (pushkey) { + 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.' ); + }); + } + catch (err) { + node.error(err); + } + } + else { + node.warn("Prowl credentials not set/found. See node info."); + } + }); +} + +RED.nodes.registerType("prowl",ProwlNode); diff --git a/social/prowl/icons/prowl.png b/social/prowl/icons/prowl.png new file mode 100644 index 00000000..43f32253 Binary files /dev/null and b/social/prowl/icons/prowl.png differ diff --git a/social/pushbullet/57-pushbullet.html b/social/pushbullet/57-pushbullet.html new file mode 100644 index 00000000..32020297 --- /dev/null +++ b/social/pushbullet/57-pushbullet.html @@ -0,0 +1,57 @@ + + + + + + + diff --git a/social/pushbullet/57-pushbullet.js b/social/pushbullet/57-pushbullet.js new file mode 100644 index 00000000..b839e893 --- /dev/null +++ b/social/pushbullet/57-pushbullet.js @@ -0,0 +1,64 @@ +/** + * 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("../../red/red"); +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'} + +try { + var pushkey = require("../../settings").pushbullet || require("../../../pushkey.js"); +} +catch(err) { + util.log("[57-pushbullet.js] Error: Failed to load PushBullet credentials"); +} + +if (pushkey) { + var pusher = new PushBullet(pushkey.pushbullet); + 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); + } + if (pushkey) { + try { + pusher.note(deviceId, titl, msg.payload, function(err, response) { + if (err) node.error(err); + console.log(response); + }); + } + catch (err) { + node.error(err); + } + } + else { + node.warn("Pushbullet credentials not set/found. See node info."); + } + }); +} + +RED.nodes.registerType("pushbullet",PushbulletNode); diff --git a/social/pushbullet/icons/bullet.png b/social/pushbullet/icons/bullet.png new file mode 100644 index 00000000..3cf11b3f Binary files /dev/null and b/social/pushbullet/icons/bullet.png differ diff --git a/social/xmpp/92-xmpp.html b/social/xmpp/92-xmpp.html new file mode 100644 index 00000000..daaa2715 --- /dev/null +++ b/social/xmpp/92-xmpp.html @@ -0,0 +1,80 @@ + + + + + + + diff --git a/social/xmpp/92-xmpp.js b/social/xmpp/92-xmpp.js new file mode 100644 index 00000000..15f95795 --- /dev/null +++ b/social/xmpp/92-xmpp.js @@ -0,0 +1,118 @@ +/** + * 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 orig=console.warn; +console.warn=(function() { // suppress warning from stringprep when not needed) + var orig=console.warn; + return function() { + //orig.apply(console, arguments); + }; +})(); + +var RED = require("../../red/red"); +var xmpp = require('simple-xmpp'); +console.warn = orig; + +try { + var xmppkey = require("../../settings").xmpp || require("../../../xmppkeys.js"); +} catch(err) { + throw new Error("Failed to load XMPP credentials"); +} + +function XmppNode(n) { + RED.nodes.createNode(this,n); + this.server = n.server; + this.port = n.port; + 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); + + xmpp.on('online', function() { + node.log('connected to '+node.server); + xmpp.setPresence('online', node.nick+' online'); + if (node.join) { + xmpp.join(node.to+'/'+node.nick); + } + }); + + xmpp.on('chat', function(from, message) { + var msg = { topic:from, payload:message }; + node.send([msg,null]); + }); + + xmpp.on('groupchat', function(conference, from, message, stamp) { + var msg = { topic:from, payload:message, room:conference }; + if (from != node.nick) { node.send([msg,null]); } + }); + + //xmpp.on('chatstate', function(from, state) { + //console.log('%s is currently %s', from, state); + //var msg = { topic:from, payload:state }; + //node.send([null,msg]); + //}); + + xmpp.on('buddy', function(jid, state, statusText) { + node.log(jid+" is "+state+" : "+statusText); + var msg = { topic:jid, payload: { presence:state, status:statusText} }; + node.send([null,msg]); + }); + + xmpp.on('error', function(err) { + console.error(err); + }); + + xmpp.on('close', function(err) { + node.log('connection closed'); + }); + + 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); + } + }); + + this.on("close", function() { + xmpp.setPresence('offline'); + //xmpp.conn.end(); + // 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)). + 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."); + }); +} + +RED.nodes.registerType("xmpp",XmppNode); diff --git a/social/xmpp/icons/xmpp.png b/social/xmpp/icons/xmpp.png new file mode 100644 index 00000000..57e43fc4 Binary files /dev/null and b/social/xmpp/icons/xmpp.png differ diff --git a/storage/leveldb/67-leveldb.html b/storage/leveldb/67-leveldb.html new file mode 100644 index 00000000..bca7afb0 --- /dev/null +++ b/storage/leveldb/67-leveldb.html @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + diff --git a/storage/leveldb/67-leveldb.js b/storage/leveldb/67-leveldb.js new file mode 100644 index 00000000..050d456b --- /dev/null +++ b/storage/leveldb/67-leveldb.js @@ -0,0 +1,93 @@ +/** + * 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("../../red/red"); +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; + }); +} +RED.nodes.registerType("leveldbase",LevelNode); +LevelNode.prototype.close = function() { + this.db.close(); +} + +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') { + 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 { + 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);