From 735b48d4dfb62a28687c6f65d5d8606d09d7266e Mon Sep 17 00:00:00 2001 From: Harald Rietman Date: Fri, 14 Jul 2017 23:40:14 +0200 Subject: [PATCH] Refactored handling retry timer --- .../xiaomi-socket-wifi.js | 203 ++++++++++-------- 1 file changed, 111 insertions(+), 92 deletions(-) diff --git a/node-red-contrib-xiaomi-socket-wifi/xiaomi-socket-wifi.js b/node-red-contrib-xiaomi-socket-wifi/xiaomi-socket-wifi.js index 61c5cc5..319119b 100644 --- a/node-red-contrib-xiaomi-socket-wifi/xiaomi-socket-wifi.js +++ b/node-red-contrib-xiaomi-socket-wifi/xiaomi-socket-wifi.js @@ -3,6 +3,10 @@ module.exports = function(RED) { var mustache = require("mustache"); var crypto = require("crypto"); var miio = require("miio"); + var connectionState = "timeout"; + var retryTimer; + var delayedStatusMsgTimer; + function XiaomiPlugWifiNode(config) { RED.nodes.createNode(this, config); @@ -10,143 +14,158 @@ module.exports = function(RED) { this.output = config.output; this.onmsg = config.onmsg; this.offmsg = config.offmsg; + this.plug = null; var node = this; - var connectionState = "timeout"; - var plug = {}; - var retryTimer; - node.status({fill:"yellow", shape:"dot", text:"connecting"}); + node.status({fill: "yellow", shape: "dot", text: "connecting"}); - miio.device({ address: node.ip }) - .then(function(result) { - if (result.type === "power-plug") { - plug = result; - node.status({fill:"green", shape:"dot", text:"connected"}); - connectionState = "connected"; + miio.device({address: node.ip}) + .then(function (plug) { + node.plug = plug; + node.status({fill:"green", shape:"dot", text:"connected"}); + connectionState = "connected"; + delayedStatusMsgUpdate(node); - setTimeout(function() { - if (result.power()['0']) { + node.plug.on('propertyChanged', function(e) { + if (e.property === "power") { + if (e.value['0']) { setState("on"); } else { setState("off"); } - }, 1500); - - watchdog(); - - plug.on('propertyChanged', function(e) { - if (e.property === "power") { - if (e.value['0']) { - setState("on"); - } else { - setState("off"); - } - } - }); - - } + } + }); + watchdog(); }) - .catch(function(error) { - node.status({fill:"red", shape:"dot", text:"time out"}); + .catch(function (error) { connectionState = "reconnecting"; watchdog(); - }); + }) - node.on('input', function(msg) { + node.on('input', function (msg) { var payload = msg.payload; + if (connectionState === "connected") { + if (payload == 'on') { + node.plug.setPower(true); + } - if (payload == 'on') { - if (connectionState === "connected") { - plug.setPower(true); + if (payload == 'off') { + node.plug.setPower(false); } } - - if (payload == 'off') { - if (connectionState === "connected") { - plug.setPower(false); - } - } - }); - this.on('close', function(done) { + node.on('close', function (done) { if (retryTimer) { - clearTimeout(retryTimer); + clearInterval(retryTimer); } - if (plug) { - plug.destroy(); + if (delayedStatusMsgTimer) { + clearTimeout(delayedStatusMsgTimer); + } + if (node.plug) { + node.plug.destroy(); } done(); }); var setState = function(state) { - var status = null; - var info = null; - if (plug) { - info = {"payload": { - "id": plug.id, - "type": plug.type, - "model": plug.model, - "capabilities": plug.capabilities, - "address": plug.address, - "port": plug.port, - "power": plug.power() + if (node.plug) { + var status = null; + var info = {"payload": { + "id": node.plug.id, + "type": node.plug.type, + "model": node.plug.model, + "capabilities": node.plug.capabilities, + "address": node.plug.address, + "port": node.plug.port, + "power": node.plug.power() }}; - } - if (state === "on") { - node.status({fill:"green", shape:"dot", text:"on"}); - status = {"payload": mustache.render(node.onmsg, info.payload)} - } - if (state === "off") { - node.status({fill:"red", shape:"dot", text:"off"}); - status = {"payload": mustache.render(node.offmsg, info.payload)} - } + if (state === "on") { + node.status({fill:"green", shape:"dot", text:"on"}); + status = {"payload": mustache.render(node.onmsg, info.payload)} + } + if (state === "off") { + node.status({fill:"red", shape:"dot", text:"off"}); + status = {"payload": mustache.render(node.offmsg, info.payload)} + } - if (node.output == 0) { - status = info; - } else if (node.output == "1") { - status = {"payload": state} - } else if (node.output == "2") { - // do nothing, just send status parsed with mustache + if (node.output == 0) { + status = info; + } else if (node.output == "1") { + status = {"payload": state} + } else if (node.output == "2") { + // do nothing, just send status parsed with mustache + } + node.send([status]); } - node.send([status]); + }; + + var delayedStatusMsgUpdate = function() { + delayedStatusMsgTimer = setTimeout(function() { + if (node.plug.power()['0']) { + setState("on"); + } else { + setState("off"); + } + }, 1500); + }; + + var discoverDevice = function() { + miio.device({address: node.ip}) + .then(function (plug) { + if (node.plug == null) { + node.plug = plug; + node.plug.on('propertyChanged', function(e) { + if (e.property === "power") { + if (e.value['0']) { + setState("on"); + } else { + setState("off"); + } + } + }); + } + if (connectionState === "reconnecting") { + node.status({fill:"green", shape:"dot", text:"connected"}); + connectionState = "connected"; + delayedStatusMsgUpdate(); + } + watchdog(); + }) + .catch(function (error) { + connectionState = "reconnecting"; + if (node.plug) { + node.plug.destroy(); + node.plug = null; + } + watchdog(); + }) }; var watchdog = function() { + console.log("retrytimer started"); var interval = 10; retryTimer = setInterval(function() { if (interval == 0) { - miio.device({address: node.ip}) - .then(function (result) { - if (connectionState === "reconnecting") { - node.status({fill:"green", shape:"dot", text:"connected"}); - connectionState = "connected"; - - setTimeout(function() { - if (result.power()['0']) { - setState("on"); - } else { - setState("off"); - } - }, 1500); - } - }) - .catch(function (error) { - connectionState = "reconnecting"; - }) interval = 10; + clearInterval(retryTimer); + discoverDevice(); } else { interval--; if (connectionState === "reconnecting") { - node.status({fill: "red", shape: "dot", text: "retrying in " + interval + " sec."}); + node.status({fill: "red", shape: "dot", text: "retrying in " + interval + " sec."}); } } }, 1000); } - } + } RED.nodes.registerType("xiaomi-plug-wifi", XiaomiPlugWifiNode); + process.on('unhandledRejection', function(reason, p){ + console.log("Possibly Unhandled Rejection at: Promise ", p, " reason: ", reason); + // application specific logging here + }); }