diff --git a/hardware/wemo/WeMoNG.html b/hardware/wemo/WeMoNG.html
index 71c82e34..cb3bcc6f 100644
--- a/hardware/wemo/WeMoNG.html
+++ b/hardware/wemo/WeMoNG.html
@@ -164,30 +164,30 @@
return this.name;
},
oneditprepare: function() {
- var devices;
- $.getJSON('wemoNG/devices', function(data){
- devices = data;
- var devs = Object.keys(data);
- if (devs.length !== 0) {
- for (var d in devs) {
- if (dev.hasOwnProperty(d)) {
- $('',{
- 'value': devs[d],
- 'text': data[devs[d]].name
- }).appendTo('#node-config-input-device');
- console.log(data[devs[d]].name);
+ var devices;
+ $.getJSON('wemoNG/devices', function(data) {
+ devices = data;
+ var devs = Object.keys(data);
+ if (devs.length !== 0) {
+ for (var d in devs) {
+ if (devs.hasOwnProperty(d)) {
+ $('',{
+ 'value': devs[d],
+ 'text': data[devs[d]].name
+ }).appendTo('#node-config-input-device');
+ console.log(data[devs[d]].name);
+ }
+ }
}
- }
- }
- });
+ });
- $('#node-config-input-device').change(function(){
- var id = $( "#node-config-input-device option:selected" ).first().val();
- if (devices) {
- $('#node-config-input-type').val(devices[id].type);
- $('#node-config-input-name').val(devices[id].name);
- }
- });
+ $('#node-config-input-device').change(function() {
+ var id = $( "#node-config-input-device option:selected" ).first().val();
+ if (devices) {
+ $('#node-config-input-type').val(devices[id].type);
+ $('#node-config-input-name').val(devices[id].name);
+ }
+ });
}
});
-
\ No newline at end of file
+
diff --git a/hardware/wemo/WeMoNG.js b/hardware/wemo/WeMoNG.js
index f3292810..6a642d65 100644
--- a/hardware/wemo/WeMoNG.js
+++ b/hardware/wemo/WeMoNG.js
@@ -15,7 +15,7 @@
**/
var WeMoNG = require('./lib/wemo.js');
-var wemo = new WeMoNG();
+var wemo = new WeMoNG();
//this won't work as there is no way to stop it...
//but is that a problem?
@@ -23,364 +23,361 @@ var interval = setInterval(wemo.start.bind(wemo), 60000);
wemo.start();
module.exports = function(RED) {
- "use strict";
- var util = require('util');
- var ip = require('ip');
- var bodyParser = require('body-parser');
- var http = require('http');
- var os = require('os');
+ 'use strict';
+ var util = require('util');
+ var ip = require('ip');
+ var bodyParser = require('body-parser');
+ var http = require('http');
+ var os = require('os');
- var settings = RED.settings;
+ var settings = RED.settings;
- var subscriptions = {};
- var sub2dev = {};
+ var subscriptions = {};
+ var sub2dev = {};
- var resubscribe = function() {
+ var resubscribe = function() {
- var subs = Object.keys(subscriptions);
- for (var s in subs) {
- if (subs.hasOwnProperty(s)) {
- var sub = subscriptions[subs[s]];
- var dev = wemo.get(subs[s]);
- var reSubOptions = {
- host: dev.ip,
- port: dev.port,
- path: dev.device.UDN.indexOf('Bridge-1_0') < 0 ? '/upnp/event/basicevent1': '/upnp/event/bridge1',
- method: 'SUBSCRIBE',
- headers: {
- 'SID': sub.sid,
- 'TIMEOUT': 'Second-300'
- }
- };
+ var subs = Object.keys(subscriptions);
+ for (var s in subs) {
+ if (subs.hasOwnProperty(s)) {
+ var sub = subscriptions[subs[s]];
+ var dev = wemo.get(subs[s]);
+ var reSubOptions = {
+ host: dev.ip,
+ port: dev.port,
+ path: dev.device.UDN.indexOf('Bridge-1_0') < 0 ? '/upnp/event/basicevent1' : '/upnp/event/bridge1',
+ method: 'SUBSCRIBE',
+ headers: {
+ 'SID': sub.sid,
+ 'TIMEOUT': 'Second-300'
+ }
+ };
- var resub_request = http.request(reSubOptions, function(res) {
- //shoudl raise an error if needed
- if (res.statusCode != 200) {
- console.log("problem with resubscription %s - %s", res.statusCode, res.statusMessage);
- console.log("opts - %s", util.inspect(reSubOptions));
- console.log("dev - %s", util.inspect(dev));
- delete subscriptions[dev];
- delete sub2dev[sub.sid];
- subscribe({dev: subs[s]});
- } else {
- // console.log("resubscription good %s", res.statusCode);
- // console.log("dev - %s", util.inspect(dev));
- }
- });
+ var resub_request = http.request(reSubOptions, function(res) {
+ //shoudl raise an error if needed
+ if (res.statusCode != 200) {
+ console.log('problem with resubscription %s - %s', res.statusCode, res.statusMessage);
+ console.log('opts - %s', util.inspect(reSubOptions));
+ console.log('dev - %s', util.inspect(dev));
+ delete subscriptions[dev];
+ delete sub2dev[sub.sid];
+ subscribe({dev: subs[s]});
+ } else {
+ // console.log("resubscription good %s", res.statusCode);
+ // console.log("dev - %s", util.inspect(dev));
+ }
+ });
- resub_request.on('error', function(){
- //console.log("failed to resubscribe to %s", dev.name );
- //need to find a way to resubsribe
- delete subscriptions[dev];
- delete sub2dev[sub.sid];
- subscribe({dev: subs[s]});
- });
+ resub_request.on('error', function() {
+ //console.log("failed to resubscribe to %s", dev.name );
+ //need to find a way to resubsribe
+ delete subscriptions[dev];
+ delete sub2dev[sub.sid];
+ subscribe({dev: subs[s]});
+ });
- resub_request.end();
+ resub_request.end();
- }
- }
-
- }
-
- setInterval(resubscribe, 200000);
-
- var subscribe = function(node) {
- var dev = node.dev;
- var device = wemo.get(dev);
- if (device){
- if (subscriptions[dev]) {
- //exists
- subscriptions[dev].count++;
- } else {
- //new
-
- var ipAddr;
- //device.ip
- var interfaces = os.networkInterfaces();
- var interfaceNames = Object.keys(interfaces);
- for (var name in interfaceNames) {
- if (interfaceNames.hasOwnProperty(name)) {
- var addrs = interfaces[interfaceNames[name]];
- for (var add in addrs) {
- if (addrs[add].netmask){
- //node 0.12 or better
- if (!addrs[add].internal && addrs[add].family == 'IPv4') {
- if (ip.isEqual(ip.mask(addrs[add].address,addrs[add].netmask),ip.mask(device.ip,addrs[add].netmask))) {
- ipAddr = addrs[add].address;
- break;
- }
- }
- } else {
- //node 0.10 not great but best we can do
- if (!addrs[add].internal && addrs[add].family == 'IPv4') {
- ipAddr = addrs[add].address;
- break;
- }
- }
}
- if (ipAddr) {
- break;
- }
- }
}
- var callback_url = 'http://' + ipAddr + ':' + settings.uiPort;
- if(settings.httpAdminRoot) {
- callback_url += settings.httpAdminRoot;
- }
+ };
- if (callback_url.lastIndexOf('/') != (callback_url.length -1)) {
- callback_url += '/';
- }
-
- callback_url += 'wemoNG/notification';
-
- console.log("Callback URL = %s",callback_url);
-
- var subscribeOptions = {
- host: device.ip,
- port: device.port,
- path: device.device.UDN.indexOf('Bridge-1_0') < 0 ? '/upnp/event/basicevent1': '/upnp/event/bridge1',
- method: 'SUBSCRIBE',
- headers: {
- 'CALLBACK': '<' + callback_url + '>',
- 'NT': 'upnp:event',
- 'TIMEOUT': 'Second-300'
- }
- };
-
- //console.log(util.inspect(subscribeOptions));
-
- var sub_request = http.request(subscribeOptions, function(res) {
- //console.log("subscribe: %s - %s", device.name, res.statusCode);
- if (res.statusCode == 200) {
- subscriptions[dev] = {'count': 1, 'sid': res.headers.sid};
- sub2dev[res.headers.sid] = dev;
- } else {
- console.log("failed to subsrcibe");
- }
- });
-
- sub_request.end();
- }
- }
- }
-
- function unsubscribe(node) {
- var dev = node.dev;
- if (subscriptions[dev]) {
- if (subscriptions[dev].count == 1) {
- var sid = subscriptions[dev].sid;
+ setInterval(resubscribe, 200000);
+ var subscribe = function(node) {
+ var dev = node.dev;
var device = wemo.get(dev);
- //need to unsubsribe properly here
- var unSubOpts = {
- host: device.ip,
- port: device.port,
- path: device.device.UDN.indexOf('Bridge-1_0') < 0 ? '/upnp/event/basicevent1': '/upnp/event/bridge1',
- method: 'UNSUBSCRIBE',
- headers: {
- 'SID': sid
- }
- };
+ if (device) {
+ if (subscriptions[dev]) {
+ //exists
+ subscriptions[dev].count++;
+ } else {
+ //new
- //console.log(util.inspect(unSubOpts));
+ var ipAddr;
+ //device.ip
+ var interfaces = os.networkInterfaces();
+ var interfaceNames = Object.keys(interfaces);
+ for (var name in interfaceNames) {
+ if (interfaceNames.hasOwnProperty(name)) {
+ var addrs = interfaces[interfaceNames[name]];
+ for (var add in addrs) {
+ if (addrs[add].netmask) {
+ //node 0.12 or better
+ if (!addrs[add].internal && addrs[add].family == 'IPv4') {
+ if (ip.isEqual(ip.mask(addrs[add].address,addrs[add].netmask),ip.mask(device.ip,addrs[add].netmask))) {
+ ipAddr = addrs[add].address;
+ break;
+ }
+ }
+ } else {
+ //node 0.10 not great but best we can do
+ if (!addrs[add].internal && addrs[add].family == 'IPv4') {
+ ipAddr = addrs[add].address;
+ break;
+ }
+ }
+ }
+ if (ipAddr) {
+ break;
+ }
+ }
+ }
- var unSubreq = http.request(unSubOpts, function(res){
- //console.log("unsubscribe: %s \n %s", device.name, res.statusCode);
- delete subscriptions[dev];
- delete sub2dev[sid];
- });
+ var callback_url = 'http://' + ipAddr + ':' + settings.uiPort;
+ if (settings.httpAdminRoot) {
+ callback_url += settings.httpAdminRoot;
+ }
- unSubreq.end();
+ if (callback_url.lastIndexOf('/') != (callback_url.length - 1)) {
+ callback_url += '/';
+ }
- } else {
- subscriptions[dev].count--;
- }
- } else {
- //shouldn't ever get here
- }
- }
+ callback_url += 'wemoNG/notification';
- var wemoNGConfig = function(n) {
- RED.nodes.createNode(this,n);
- this.device = n.device;
- }
- RED.nodes.registerType("wemo-dev", wemoNGConfig);
+ console.log('Callback URL = %s',callback_url);
- var wemoNGNode = function(n) {
- RED.nodes.createNode(this,n);
- var node = this;
- node.device = n.device;
- node.name = n.name;
- node.dev = RED.nodes.getNode(node.device).device;
- node.status({fill:"red",shape:"dot",text:"searching"});
+ var subscribeOptions = {
+ host: device.ip,
+ port: device.port,
+ path: device.device.UDN.indexOf('Bridge-1_0') < 0 ? '/upnp/event/basicevent1' : '/upnp/event/bridge1',
+ method: 'SUBSCRIBE',
+ headers: {
+ 'CALLBACK': '<' + callback_url + '>',
+ 'NT': 'upnp:event',
+ 'TIMEOUT': 'Second-300'
+ }
+ };
- //console.log("Control - %j" ,this.dev);
- if (!wemo.get(node.dev)){
- wemo.on('discovered', function(d){
- if (node.dev === d) {
- node.status({fill:"green",shape:"dot",text:"found"});
- }
- });
- } else {
- node.status({fill:"green",shape:"dot",text:"found"});
- }
+ //console.log(util.inspect(subscribeOptions));
- node.on('input', function(msg){
- var dev = wemo.get(node.dev);
+ var sub_request = http.request(subscribeOptions, function(res) {
+ //console.log("subscribe: %s - %s", device.name, res.statusCode);
+ if (res.statusCode == 200) {
+ subscriptions[dev] = {'count': 1, 'sid': res.headers.sid};
+ sub2dev[res.headers.sid] = dev;
+ } else {
+ console.log('failed to subsrcibe');
+ }
+ });
- if (!dev) {
- //need to show that dev not currently found
- console.log("no device found");
- return;
- }
-
- var on = 0;
- if (typeof msg.payload === 'string') {
- if (msg.payload == 'on' || msg.payload == '1' || msg.payload == 'true') {
- on = 1;
- } else if (msg.payload === 'toggle') {
- on = 2;
- }
- } else if (typeof msg.payload === 'number') {
- if (msg.payload >= 0 && msg.payload < 3) {
- on = msg.payload;
- }
- } else if (typeof msg.payload === 'object') {
- //object need to get complicated here
- if (msg.payload.state && typeof msg.payload.state === 'number') {
- if (dev.type === 'socket') {
- if (msg.payload >= 0 && msg.payload < 2) {
- on = msg.payload.state
+ sub_request.end();
}
- } else if (dev.type === 'light' || dev.type === 'group') {
- if (msg.payload >= 0 && msg.payload < 3) {
- on = msg.payload.state;
- }
- }
}
- } else if (typeof msg.payload === 'boolean') {
- if (msg.payload) {
- on = 1;
- }
- }
-
- if (dev.type === 'socket') {
- //console.log("socket");
- wemo.toggleSocket(dev, on);
- } else if (dev.type === 'light`') {
- //console.log("light");
- wemo.setStatus(dev,"10006", on);
- } else {
- console.log("group");
- wemo.setStatus(dev, "10006", on);
- }
- });
- }
- RED.nodes.registerType("wemo out", wemoNGNode);
-
- var wemoNGEvent = function(n) {
- RED.nodes.createNode(this,n);
- var node = this;
- node.ipaddr = n.ipaddr;
- node.device = n.device;
- node.name = n.name;
- node.topic = n.topic;
- node.dev = RED.nodes.getNode(node.device).device;
-
- node.status({fill:"red",shape:"dot",text:"searching"});
-
- var onEvent = function(notification){
- var d = sub2dev[notification.sid];
- if (d == node.dev) {
- var dd = wemo.get(node.dev);
- notification.type = dd.type;
- notification.name = dd.name;
- if (!notification.id) {
- notification.id = node.dev;
- }
-
- var msg = {
- topic: node.topic ? node.topic : 'wemo',
- payload: notification
- };
-
- switch (notification.type){
- case 'light':
- case 'group':
- if (dd.id === notification.id) {
- node.send(msg);
- }
- break;
- case 'socket':
- node.send(msg);
- break;
- default:
- }
-
- }
};
- wemo.on('event', onEvent);
+ function unsubscribe(node) {
+ var dev = node.dev;
+ if (subscriptions[dev]) {
+ if (subscriptions[dev].count == 1) {
+ var sid = subscriptions[dev].sid;
- if (node.dev) {
- //subscribe to events
- if (wemo.get(node.dev)) {
- node.status({fill:"green",shape:"dot",text:"found"});
- subscribe(node);
- } else {
- wemo.on('discovered', function(d){
- if (node.dev === d) {
- node.status({fill:"green",shape:"dot",text:"found"});
- subscribe(node);
- }
- });
- }
- } else if (node.ipaddr) {
- //legacy
- var devices = Object.keys(wemo.devices);
- for (var d in devices) {
- if (devices.hasOwnProperty(d)) {
- var device = devices[d];
- if (device.ip === node.ipaddr) {
- node.dev = device.id;
- node.status({fill:"green",shape:"circle",text:"reconfigure"});
- subscribe(node);
- break;
- }
+ var device = wemo.get(dev);
+ //need to unsubsribe properly here
+ var unSubOpts = {
+ host: device.ip,
+ port: device.port,
+ path: device.device.UDN.indexOf('Bridge-1_0') < 0 ? '/upnp/event/basicevent1' : '/upnp/event/bridge1',
+ method: 'UNSUBSCRIBE',
+ headers: {
+ 'SID': sid
+ }
+ };
+
+ //console.log(util.inspect(unSubOpts));
+
+ var unSubreq = http.request(unSubOpts, function(res) {
+ //console.log("unsubscribe: %s \n %s", device.name, res.statusCode);
+ delete subscriptions[dev];
+ delete sub2dev[sid];
+ });
+
+ unSubreq.end();
+
+ } else {
+ subscriptions[dev].count--;
+ }
+ } else {
+ //shouldn't ever get here
}
- }
}
-
- node.on('close', function(done){
- //should un subscribe from events
- wemo.removeListener('event', onEvent);
- unsubscribe(node);
- done();
- });
- }
- RED.nodes.registerType("wemo in", wemoNGEvent)
-
- RED.httpAdmin.get('/wemoNG/devices', function(req,res){
- res.json(wemo.devices);
-
- });
-
- RED.httpAdmin.use('/wemoNG/notification',bodyParser.raw({type: 'text/xml'}));
-
- RED.httpAdmin.notify('/wemoNG/notification', function(req, res){
- var notification = {
- 'sid': req.headers.sid
+ var wemoNGConfig = function(n) {
+ RED.nodes.createNode(this,n);
+ this.device = n.device;
};
- //console.log("Incoming Event %s", req.body.toString());
- wemo.parseEvent(req.body.toString()).then(function(evt){
- evt.sid = notification.sid;
- wemo.emit('event',evt);
- });
- res.send("");
- });
+ RED.nodes.registerType('wemo-dev', wemoNGConfig);
-}
\ No newline at end of file
+ var wemoNGNode = function(n) {
+ RED.nodes.createNode(this,n);
+ var node = this;
+ node.device = n.device;
+ node.name = n.name;
+ node.dev = RED.nodes.getNode(node.device).device;
+ node.status({fill: 'red',shape: 'dot',text: 'searching'});
+
+ //console.log("Control - %j" ,this.dev);
+ if (!wemo.get(node.dev)) {
+ wemo.on('discovered', function(d) {
+ if (node.dev === d) {
+ node.status({fill: 'green',shape: 'dot',text: 'found'});
+ }
+ });
+ } else {
+ node.status({fill: 'green',shape: 'dot',text: 'found'});
+ }
+
+ node.on('input', function(msg) {
+ var dev = wemo.get(node.dev);
+
+ if (!dev) {
+ //need to show that dev not currently found
+ console.log('no device found');
+ return;
+ }
+
+ var on = 0;
+ if (typeof msg.payload === 'string') {
+ if (msg.payload == 'on' || msg.payload == '1' || msg.payload == 'true') {
+ on = 1;
+ } else if (msg.payload === 'toggle') {
+ on = 2;
+ }
+ } else if (typeof msg.payload === 'number') {
+ if (msg.payload >= 0 && msg.payload < 3) {
+ on = msg.payload;
+ }
+ } else if (typeof msg.payload === 'object') {
+ //object need to get complicated here
+ if (msg.payload.state && typeof msg.payload.state === 'number') {
+ if (dev.type === 'socket') {
+ if (msg.payload >= 0 && msg.payload < 2) {
+ on = msg.payload.state;
+ }
+ } else if (dev.type === 'light' || dev.type === 'group') {
+ if (msg.payload >= 0 && msg.payload < 3) {
+ on = msg.payload.state;
+ }
+ }
+ }
+ } else if (typeof msg.payload === 'boolean') {
+ if (msg.payload) {
+ on = 1;
+ }
+ }
+
+ if (dev.type === 'socket') {
+ //console.log("socket");
+ wemo.toggleSocket(dev, on);
+ } else if (dev.type === 'light`') {
+ //console.log("light");
+ wemo.setStatus(dev,'10006', on);
+ } else {
+ console.log('group');
+ wemo.setStatus(dev, '10006', on);
+ }
+ });
+ };
+ RED.nodes.registerType('wemo out', wemoNGNode);
+
+ var wemoNGEvent = function(n) {
+ RED.nodes.createNode(this,n);
+ var node = this;
+ node.ipaddr = n.ipaddr;
+ node.device = n.device;
+ node.name = n.name;
+ node.topic = n.topic;
+ node.dev = RED.nodes.getNode(node.device).device;
+
+ node.status({fill: 'red',shape: 'dot',text: 'searching'});
+
+ var onEvent = function(notification) {
+ var d = sub2dev[notification.sid];
+ if (d == node.dev) {
+ var dd = wemo.get(node.dev);
+ notification.type = dd.type;
+ notification.name = dd.name;
+ if (!notification.id) {
+ notification.id = node.dev;
+ }
+
+ var msg = {
+ topic: node.topic ? node.topic : 'wemo',
+ payload: notification
+ };
+
+ switch (notification.type){
+ case 'light':
+ case 'group':
+ if (dd.id === notification.id) {
+ node.send(msg);
+ }
+ break;
+ case 'socket':
+ node.send(msg);
+ break;
+ default:
+ }
+
+ }
+ };
+
+ wemo.on('event', onEvent);
+
+ if (node.dev) {
+ //subscribe to events
+ if (wemo.get(node.dev)) {
+ node.status({fill: 'green',shape: 'dot',text: 'found'});
+ subscribe(node);
+ } else {
+ wemo.on('discovered', function(d) {
+ if (node.dev === d) {
+ node.status({fill: 'green',shape: 'dot',text: 'found'});
+ subscribe(node);
+ }
+ });
+ }
+ } else if (node.ipaddr) {
+ //legacy
+ var devices = Object.keys(wemo.devices);
+ for (var d in devices) {
+ if (devices.hasOwnProperty(d)) {
+ var device = devices[d];
+ if (device.ip === node.ipaddr) {
+ node.dev = device.id;
+ node.status({fill: 'green',shape: 'circle',text: 'reconfigure'});
+ subscribe(node);
+ break;
+ }
+ }
+ }
+ }
+
+ node.on('close', function(done) {
+ //should un subscribe from events
+ wemo.removeListener('event', onEvent);
+ unsubscribe(node);
+ done();
+ });
+ };
+ RED.nodes.registerType('wemo in', wemoNGEvent);
+
+ RED.httpAdmin.get('/wemoNG/devices', function(req, res) {
+ res.json(wemo.devices);
+ });
+
+ RED.httpAdmin.use('/wemoNG/notification',bodyParser.raw({type: 'text/xml'}));
+
+ RED.httpAdmin.notify('/wemoNG/notification', function(req, res) {
+ var notification = {
+ 'sid': req.headers.sid
+ };
+ //console.log("Incoming Event %s", req.body.toString());
+ wemo.parseEvent(req.body.toString()).then(function(evt) {
+ evt.sid = notification.sid;
+ wemo.emit('event',evt);
+ });
+ res.send('');
+ });
+};