UNPKG

node-red-contrib-huemagic

Version:

Philips Hue node to control bridges, lights, groups, scenes, rules, taps, switches, buttons, motion sensors, temperature sensors and Lux sensors using Node-RED.

163 lines (139 loc) 4.26 kB
module.exports = function(RED) { "use strict"; function HueButtons(config) { RED.nodes.createNode(this, config); const scope = this; const bridge = RED.nodes.getNode(config.bridge); // NODE UI STATUS TIMEOUT this.timeout = null; // SAVE LAST COMMAND this.lastCommand = null; // // CHECK CONFIG if(bridge == null) { this.status({fill: "red", shape: "ring", text: "hue-buttons.node.not-configured"}); return false; } // // UNIVERSAL MODE? if(!config.sensorid) { this.status({fill: "grey", shape: "dot", text: "hue-buttons.node.universal"}); } // // UPDATE STATE if(config.sensorid) { scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"}); } // // SUBSCRIBE TO UPDATES FROM THE BRIDGE bridge.subscribe("button", config.sensorid, function(info) { let currentState = bridge.get("button", info.id); // RESOURCE FOUND? if(currentState !== false) { // SEND MESSAGE if(!config.skipevents && currentState.payload.button !== false && (config.initevents || info.suppressMessage == false)) { // SET LAST COMMAND if(scope.lastCommand !== null) { currentState.command = scope.lastCommand; } // SEND STATE scope.send(currentState); // RESET LAST COMMAND scope.lastCommand = null; } // NOT IN UNIVERAL MODE? -> CHANGE UI STATES if(config.sensorid) { if(currentState.payload.button === false) { scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"}); } else { var action = ""; switch (currentState.payload.action) { case "initial_press": action = "(pressed)"; break; case "repeat": action = "(repeated)"; break; case "short_release": action = "(short press)"; break; case "long_release": action = "(long press)"; break; case "double_short_release": action = "(double pressed)"; break; default: action = "(pressed)"; } scope.status({fill: "blue", shape: "dot", text: "Button #"+ currentState.payload.button + " " + action }); // RESET TO WAITING AFTER 3 SECONDS if(scope.timeout !== null) { clearTimeout(scope.timeout); }; scope.timeout = setTimeout(function() { scope.status({fill: "grey", shape: "dot", text: "hue-buttons.node.waiting"}); // REMOVE OLD BUTTON STATES for (const [oneButtonID, oneButton] of Object.entries(bridge.resources[config.sensorid]["services"]["button"])) { delete bridge.resources[config.sensorid]["services"]["button"][oneButtonID]["button"]; } }, 3000); } } } }); // // ON COMMAND this.on('input', function(msg, send, done) { // REDEFINE SEND AND DONE IF NOT AVAILABLE send = send || function() { scope.send.apply(scope,arguments); } done = done || function() { scope.done.apply(scope,arguments); } // SAVE LAST COMMAND scope.lastCommand = RED.util.cloneMessage(msg); // DEFINE SENSOR ID const tempSensorID = (!config.sensorid && typeof msg.topic != 'undefined' && bridge.validResourceID.test(msg.topic) === true) ? msg.topic : config.sensorid; if(!tempSensorID) { scope.error("Please submit a valid button ID."); return false; } let currentState = bridge.get("button", tempSensorID); if(!currentState) { scope.error("The button/switch in not yet available. Please wait until HueMagic has established a connection with the bridge or check whether the resource ID in the configuration is valid."); return false; } // GET CURRENT STATE if( (typeof msg.payload != 'undefined' && typeof msg.payload.status != 'undefined') || (typeof msg.__user_inject_props__ != 'undefined' && msg.__user_inject_props__ == "status") ) { // SET LAST COMMAND if(scope.lastCommand !== null) { currentState.command = scope.lastCommand; } // SEND STATE scope.send(currentState); // RESET LAST COMMAND scope.lastCommand = null; if(done) { done(); } return true; } }); } RED.nodes.registerType("hue-buttons", HueButtons); }