UNPKG

smart-nodes

Version:

Controls light, shutters and more. Includes common used logic and statistic nodes to control your home.

173 lines (137 loc) 5.12 kB
module.exports = function (RED) { "use strict"; function CounterNode(config) { const node = this; RED.nodes.createNode(node, config); // ################### // # Class constants # // ################### // ####################### // # Global help objects # // ####################### const smart_context = require("../persistence.js")(RED); const helper = require("../smart_helper.js"); // ##################### // # persistent values # // ##################### var node_settings = { value: null, last_message: null, }; // load or delete saved values if (config.save_state) node_settings = Object.assign(node_settings, smart_context.get(node.id)); else smart_context.del(node.id); // ################## // # Dynamic config # // ################## let start = parseInt(config.start, 10); let step = parseInt(config.step, 10); let min = parseInt(config.min, 10); let max = parseInt(config.max, 10); let out_message = helper.evaluateNodeProperty(RED, config.out_message, config.out_message_type); // ################## // # Runtime values # // ################## // Not used by this node node.on("input", function (msg) { handleTopic(msg); sendResult(); setStatus(); smart_context.set(node.id, node_settings); }); node.on("close", function () { }); // ##################### // # Private functions # // ##################### // This is the main function which handles all topics that was received. let handleTopic = msg => { let real_topic = helper.getTopicName(msg.topic); let temp_value; switch (real_topic) { case "debug": helper.nodeDebug(node, { node_settings, start, step, min, max, out_message, }); break; case "set_min": min = parseFloat(msg.payload); break; case "set_max": max = parseFloat(msg.payload); break; case "set_step": step = parseFloat(msg.payload); break; case "up": temp_value = parseFloat(msg.payload); if (isNaN(temp_value) && !isFinite(temp_value)) temp_value = step; node_settings.value += temp_value; break; case "down": temp_value = parseFloat(msg.payload); if (isNaN(temp_value) && !isFinite(temp_value)) temp_value = step; node_settings.value -= temp_value; break; case "reset": temp_value = parseFloat(msg.payload); if (isNaN(temp_value) && !isFinite(temp_value)) temp_value = start; node_settings.value = temp_value; break; default: node.error("Invalid topic: " + real_topic); return; } // Check value is in range node_settings.value = Math.min(max, Math.max(min, node_settings.value)); } /** * Send the result to the output */ let sendResult = () => { // Nothing changed, nothing to do if (node_settings.value == node_settings.last_message?.payload) return; // if out_message is set, use this instead of the default message if (out_message) node_settings.last_message = helper.cloneObject(out_message, { payload: node_settings.value }); else node_settings.last_message = { payload: node_settings.value }; node.send(node_settings.last_message); } // updates the status let setStatus = () => { if (node_settings.value == null) node.status({}); else node.status({ fill: "yellow", shape: "dot", text: helper.getCurrentTimeForStatus() + ": Min = " + min + " | Max = " + max + " | Value = " + node_settings.value }); } if (config.save_state && config.resend_on_start && node_settings.last_message != null) { setTimeout(() => { node.send(helper.cloneObject(node_settings.last_message)); }, 10000); } setStatus(); } RED.nodes.registerType("smart_counter", CounterNode); }