mirror of
				https://github.com/node-red/node-red-nodes.git
				synced 2025-03-01 10:37:43 +00:00 
			
		
		
		
	Wemo insight power parameters (#739)
* Insight power parameters * Insight power parameters * Insight power parameters * Insight power parameters * Insight power parameters * Bump version 0.2.0
This commit is contained in:
		@@ -73,16 +73,39 @@ And a lightbulb can look like this:
 | 
			
		||||
   }
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Insight
 | 
			
		||||
An Insight socket output can look like this:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
  {
 | 
			
		||||
    "raw": "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">\n<e:property>\n<BinaryState>8|1454271649|301|834|56717|1209600|8|1010|638602|12104165</BinaryState>\n</e:property>\n</e:propertyset>\n\n\r",
 | 
			
		||||
    "state": "8",
 | 
			
		||||
    "power": 1.01,
 | 
			
		||||
    "onSince": 1611179325,
 | 
			
		||||
    "onFor": 2545,
 | 
			
		||||
    "onToday": 17432,
 | 
			
		||||
    "onTotal": 47939,
 | 
			
		||||
    "averagePower": 13,
 | 
			
		||||
    "power": 3.205,
 | 
			
		||||
    "energyToday": 3596536,
 | 
			
		||||
    "energyTotal": 9966151
 | 
			
		||||
    "sid": "uuid:ea808ecc-1dd1-11b2-9579-8e5c117d479e",
 | 
			
		||||
    "type": "socket",
 | 
			
		||||
    "name": "WeMo Insight",
 | 
			
		||||
    "id": "221450K1200F5C"
 | 
			
		||||
  }
 | 
			
		||||
```
 | 
			
		||||
Some information about those power parameters:
 | 
			
		||||
+ `state`: Whether the device is currently ON or OFF (1 or 0).
 | 
			
		||||
+ `onSince`: The date and time when the device was last turned on or off (as a Unix timestamp).
 | 
			
		||||
+ `onFor`: How long the device was last ON for (seconds).
 | 
			
		||||
+ `onToday`: How long the device has been ON today (seconds).
 | 
			
		||||
+ `onTotal`: How long the device has been ON total (seconds).
 | 
			
		||||
+ `timespan`: Timespan over which onTotal is relevant (seconds). Typically 2 weeks except when first started up.
 | 
			
		||||
+ `averagePower`: Average power consumption (Watts).
 | 
			
		||||
+ `power`: Current power consumption (Watts).
 | 
			
		||||
+ `energyToday`: Energy used today (Watt-hours, or Wh).
 | 
			
		||||
+ `energyTotal`: Energy used in total (Wh).
 | 
			
		||||
+ `standbyLimit`: Minimum energy usage to register the insight as switched on ( milliwats, default 8000mW, configurable via WeMo App).
 | 
			
		||||
 | 
			
		||||
## Lookup Node
 | 
			
		||||
 | 
			
		||||
This node queries the current state of a device, when an input message is injected.  The output is very similar to that of the Input node.
 | 
			
		||||
 
 | 
			
		||||
@@ -29,9 +29,26 @@
 | 
			
		||||
    <li>Light Groups</li>
 | 
			
		||||
    <li>Motion Detector</li>
 | 
			
		||||
  </ul>
 | 
			
		||||
  <p>Sockets will generate msg.payload with values of 0/1/8 for off or on 
 | 
			
		||||
  (8 is on but at standby load for insight sockets), lightswill return an
 | 
			
		||||
  object like this:</p>
 | 
			
		||||
  <p>Sockets will generate msg.payload with values of 0 or 1 (for off or on).</p> 
 | 
			
		||||
  <p>Insight sockets will return an object like this (where state can also be 8 at standby):</p>
 | 
			
		||||
  <pre>
 | 
			
		||||
  {
 | 
			
		||||
    state: "1"
 | 
			
		||||
    onSince: 1611180205
 | 
			
		||||
    onFor: 853
 | 
			
		||||
    onToday: 18284
 | 
			
		||||
    onTotal: 48785
 | 
			
		||||
    averagePower: 12
 | 
			
		||||
    power: 0
 | 
			
		||||
    energyToday: 3772853
 | 
			
		||||
    energyTotal: 10142468
 | 
			
		||||
    sid: "uuid:adebe0c4-1dd1-11b2-8779-d6b6d5a8a932"
 | 
			
		||||
    type: "socket"
 | 
			
		||||
    name: "WeMo Insight"
 | 
			
		||||
    id: "221536K12000B4"
 | 
			
		||||
  }
 | 
			
		||||
  </pre>
 | 
			
		||||
  <p>Lights will return an object like this:</p>
 | 
			
		||||
  <pre>
 | 
			
		||||
  {
 | 
			
		||||
    name: 'Bedroom light',
 | 
			
		||||
@@ -164,7 +181,23 @@
 | 
			
		||||
 | 
			
		||||
<script type="text/x-red" data-help-name="wemo lookup">
 | 
			
		||||
    <p>This node queries the current state of a device</p>
 | 
			
		||||
    <p>For lights it return a msg.payload that looks like this:</p>
 | 
			
		||||
    <p>For sockets it returns a msg.payload that looks like this:</p>
 | 
			
		||||
<pre>{
 | 
			
		||||
  state: 0
 | 
			
		||||
}</pre>
 | 
			
		||||
    <p>For insight sockets it returns a msg.payload that contains extra power parameters:</p>
 | 
			
		||||
<pre>{
 | 
			
		||||
  state: 0,
 | 
			
		||||
  onSince: 1611179325,
 | 
			
		||||
  onFor: 2545,
 | 
			
		||||
  onToday: 17432,
 | 
			
		||||
  onTotal: 47939,
 | 
			
		||||
  averagePower: 13,
 | 
			
		||||
  power: 3.205,
 | 
			
		||||
  energyToday: 3596536,
 | 
			
		||||
  energyTotal: 9966151
 | 
			
		||||
}</pre>
 | 
			
		||||
    <p>For lights it returns a msg.payload that looks like this:</p>
 | 
			
		||||
<pre>{
 | 
			
		||||
  available: true,
 | 
			
		||||
  state: 0,
 | 
			
		||||
 
 | 
			
		||||
@@ -246,7 +246,7 @@ module.exports = function(RED) {
 | 
			
		||||
            } else if (typeof msg.payload === 'object') {
 | 
			
		||||
                //object need to get complicated here
 | 
			
		||||
                if (msg.payload.hasOwnProperty('state') && typeof msg.payload.state === 'number') {
 | 
			
		||||
                    if (dev.type === 'socket') {
 | 
			
		||||
                    if (dev.type === 'socket' || dev.type === 'socket_insight') {
 | 
			
		||||
                        if (msg.payload.state >= 0 && msg.payload.state < 2) {
 | 
			
		||||
                            on = msg.payload.state;
 | 
			
		||||
                        }
 | 
			
		||||
@@ -278,7 +278,7 @@ module.exports = function(RED) {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (dev.type == 'socket') {
 | 
			
		||||
            if (dev.type == 'socket' || dev.type == 'socket_insight') {
 | 
			
		||||
                //console.log("socket");
 | 
			
		||||
                wemo.toggleSocket(dev, on);
 | 
			
		||||
            } else if (dev.type === 'light') {
 | 
			
		||||
@@ -325,7 +325,10 @@ module.exports = function(RED) {
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                    case 'socket': {
 | 
			
		||||
                    case 'socket':
 | 
			
		||||
                    case 'socket_insight': {
 | 
			
		||||
                        // For backwards compatibility, always send type 'socket'
 | 
			
		||||
                        notification.type = 'socket';
 | 
			
		||||
                        node.send(msg);
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -426,9 +429,19 @@ module.exports = function(RED) {
 | 
			
		||||
                    msg.payload = status;
 | 
			
		||||
                    node.send(msg);
 | 
			
		||||
                });
 | 
			
		||||
            } else if (dev.type === 'socket_insight') {
 | 
			
		||||
                console.log("socket_insight");
 | 
			
		||||
                // insight socket: ask both current switch status AND power measurements
 | 
			
		||||
                wemo.getInsightParams(dev)
 | 
			
		||||
                .then(function(insightParameters) {
 | 
			
		||||
                    msg.payload = insightParameters;
 | 
			
		||||
                    // 'state' should be a number for backwards compatibility
 | 
			
		||||
                    msg.payload.state = parseInt(msg.payload.state);
 | 
			
		||||
                    node.send(msg);
 | 
			
		||||
                });            
 | 
			
		||||
            } else {
 | 
			
		||||
                console.log("socket");
 | 
			
		||||
                //socket
 | 
			
		||||
                // classic socket: no power measurement, so only request current switch status
 | 
			
		||||
                wemo.getSocketStatus(dev)
 | 
			
		||||
                .then(function(status) {
 | 
			
		||||
                    msg.payload = {
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,17 @@ var getSocketState = {
 | 
			
		||||
  ].join('\n')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var getInsightParameters = {
 | 
			
		||||
  method: 'POST',
 | 
			
		||||
  path: '/upnp/control/insight1',
 | 
			
		||||
  action: '"urn:Belkin:service:insight:1#GetInsightParams"',
 | 
			
		||||
  body: [
 | 
			
		||||
    postbodyheader,
 | 
			
		||||
    '<u:GetInsightParams xmlns:u="urn:Belkin:service:insight:1">',
 | 
			
		||||
    '</u:GetInsightParams>',
 | 
			
		||||
    postbodyfooter
 | 
			
		||||
  ].join('\n')
 | 
			
		||||
}    
 | 
			
		||||
 | 
			
		||||
var setdevstatus = {};
 | 
			
		||||
setdevstatus.path = '/upnp/control/bridge1';
 | 
			
		||||
@@ -109,6 +120,47 @@ var WeMoNG = function () {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function addInsightParams(insightParms, msg) {
 | 
			
		||||
  var params = insightParms.split("|");
 | 
			
		||||
 | 
			
		||||
  // Whether the device is ON or OFF (1 or 0)
 | 
			
		||||
  msg.state = params[0];
 | 
			
		||||
  
 | 
			
		||||
  // The date and time when the device was last turned on or off (as a Unix timestamp)
 | 
			
		||||
  msg.onSince = parseInt(params[1]);
 | 
			
		||||
  
 | 
			
		||||
  // How long the device was last ON for (seconds)
 | 
			
		||||
  msg.onFor = parseInt(params[2]);
 | 
			
		||||
 | 
			
		||||
  // How long the device has been ON today (seconds)
 | 
			
		||||
  msg.onToday = parseInt(params[3]);
 | 
			
		||||
  
 | 
			
		||||
  // How long the device has been ON total (seconds)
 | 
			
		||||
  msg.onTotal = parseInt(params[4]);
 | 
			
		||||
  
 | 
			
		||||
  // Timespan over which onTotal is relevant (seconds). Typically 2 weeks except when first started up.
 | 
			
		||||
  //msg.timespan = parseInt(params[5]);
 | 
			
		||||
  
 | 
			
		||||
  // Average power consumption (Watts)
 | 
			
		||||
  msg.averagePower = parseInt(params[6]);
 | 
			
		||||
  
 | 
			
		||||
  // Current power consumption (Watts).  Conversion required because the value is delivered in milliWatts.
 | 
			
		||||
  // It is called 'power' (instead of currentPower) for backwards compatibility ...
 | 
			
		||||
  msg.power = params[7]/1000;
 | 
			
		||||
  
 | 
			
		||||
  // Energy used today (Watt-hours, or Wh)
 | 
			
		||||
  msg.energyToday = parseInt(params[8]);
 | 
			
		||||
  
 | 
			
		||||
  // Energy used in total (Wh)
 | 
			
		||||
  msg.energyTotal = parseFloat(params[9]);
 | 
			
		||||
  
 | 
			
		||||
  // The 10-th parameter is not always available
 | 
			
		||||
  if (params[10]) {
 | 
			
		||||
    // Minimum energy usage to register the insight as switched on ( milliwats, default 8000mW, configurable via WeMo App)
 | 
			
		||||
    msg.standbyLimit = parseInt(params[10]);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
util.inherits(WeMoNG, events.EventEmitter);
 | 
			
		||||
 | 
			
		||||
WeMoNG.prototype.start = function start() {
 | 
			
		||||
@@ -222,8 +274,23 @@ WeMoNG.prototype.start = function start() {
 | 
			
		||||
              post_request.write(util.format(getenddevs.body, udn));
 | 
			
		||||
              post_request.end();
 | 
			
		||||
 | 
			
		||||
            } else if (device.deviceType.indexOf('urn:Belkin:device:insight') != -1) {
 | 
			
		||||
              // Insight socket (with power measurement)
 | 
			
		||||
              var socket = {
 | 
			
		||||
                "ip": location.hostname,
 | 
			
		||||
                "port": location.port,
 | 
			
		||||
                "name": device.friendlyName,
 | 
			
		||||
                "type": "socket_insight",
 | 
			
		||||
                "device": device
 | 
			
		||||
              };
 | 
			
		||||
              if (!_wemo.devices[device.serialNumber]) {
 | 
			
		||||
                _wemo.devices[device.serialNumber] = socket;
 | 
			
		||||
                _wemo.emit('discovered',device.serialNumber);
 | 
			
		||||
              } else {
 | 
			
		||||
                _wemo.devices[device.serialNumber] = socket;
 | 
			
		||||
              }
 | 
			
		||||
            } else if (device.deviceType.indexOf('urn:Belkin:device') != -1) {
 | 
			
		||||
              //socket
 | 
			
		||||
              // classic socket (without power measurement)
 | 
			
		||||
              var socket = {
 | 
			
		||||
                "ip": location.hostname,
 | 
			
		||||
                "port": location.port,
 | 
			
		||||
@@ -364,6 +431,57 @@ WeMoNG.prototype.getSocketStatus = function getSocketStatus(socket) {
 | 
			
		||||
  return def.promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
WeMoNG.prototype.getInsightParams = function getInsightParams(socket) {
 | 
			
		||||
  var postoptions = {
 | 
			
		||||
    host: socket.ip,
 | 
			
		||||
    port: socket.port,
 | 
			
		||||
    path: getInsightParameters.path,
 | 
			
		||||
    method: getInsightParameters.method,
 | 
			
		||||
    headers: {
 | 
			
		||||
      'SOAPACTION': getInsightParameters.action,
 | 
			
		||||
      'Content-Type': 'text/xml; charset="utf-8"',
 | 
			
		||||
      'Accept': ''
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var def = Q.defer();
 | 
			
		||||
 | 
			
		||||
  var post_request = http.request(postoptions, function(res){
 | 
			
		||||
    var data = "";
 | 
			
		||||
    res.setEncoding('utf8');
 | 
			
		||||
    res.on('data', function(chunk){
 | 
			
		||||
      data += chunk;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    res.on('end', function(){
 | 
			
		||||
      xml2js.parseString(data, function(err, result){
 | 
			
		||||
        if (!err) {
 | 
			
		||||
          var params = result["s:Envelope"]["s:Body"][0]["u:GetInsightParamsResponse"][0].InsightParams[0];
 | 
			
		||||
          var msg = {};
 | 
			
		||||
          addInsightParams(params, msg);
 | 
			
		||||
          def.resolve(msg);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  post_request.on('error', function (e) {
 | 
			
		||||
    console.log(e);
 | 
			
		||||
    console.log("%j", postoptions);
 | 
			
		||||
    def.reject();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  post_request.on('timeout', function(){
 | 
			
		||||
    post_request.abort();
 | 
			
		||||
    def.reject();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  post_request.write(getInsightParameters.body);
 | 
			
		||||
  post_request.end();
 | 
			
		||||
 | 
			
		||||
  return def.promise;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
WeMoNG.prototype.getLightStatus = function getLightStatus(light) {
 | 
			
		||||
  var postoptions = {
 | 
			
		||||
    host: light.ip,
 | 
			
		||||
@@ -500,9 +618,8 @@ WeMoNG.prototype.parseEvent = function parseEvent(evt) {
 | 
			
		||||
      } else if (prop.hasOwnProperty('BinaryState')) {
 | 
			
		||||
        msg.state = prop['BinaryState'][0];
 | 
			
		||||
        if (msg.state.length > 1) {
 | 
			
		||||
          var parts = msg.state.split('|');
 | 
			
		||||
          msg.state = parts[0];
 | 
			
		||||
          msg.power = parts[7]/1000;
 | 
			
		||||
          // Add all the insight params to the msg
 | 
			
		||||
          addInsightParams(msg.state, msg);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        def.resolve(msg);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "node-red-node-wemo",
 | 
			
		||||
  "version": "0.1.18",
 | 
			
		||||
  "version": "0.2.0",
 | 
			
		||||
  "description": "Input and Output nodes for Belkin WeMo devices",
 | 
			
		||||
  "repository": "https://github.com/node-red/node-red-nodes/tree/master/hardware",
 | 
			
		||||
  "main": "WeMoNG.js",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user