UNPKG

node-red-contrib-miio-humidifier

Version:

Miio node for Smartmi humidifier (Xiaomi)

175 lines (145 loc) 6.08 kB
const miio = require('miio'); module.exports = function (RED) { class MiioHumidifierInput { constructor(config) { RED.nodes.createNode(this, config); var node = this; node.config = config; node.cleanTimer = null; node.connected = false; node.status({}); //clean //get server node node.server = RED.nodes.getNode(node.config.server); if (node.server) { // node.server.on('onClose', () => this.onClose()); node.server.on('onInitEnd', (status) => node.onInitEnd(status)); node.server.on('onState', (status) => node.onStateChanged(status)); node.server.on('onStateChanged', (data, output) => node.onStateChanged(data, output)); node.server.on('onConnectionError', (error) => node.onConnectionError(error)); if (node.config.outputAtStartup || node.config.for_homekit) { node.sendState(); } } else { node.status({ fill: "red", shape: "dot", text: "node-red-contrib-miio-humidifier/in:status.server_node_error" }); } } sendState() { var node = this; node.send({'payload':node.config.for_homekit?node.formatHomeKit():node.server.status, 'change': null, 'status': node.server.status}); } updateStatus() { var node = this; if (Object.keys(node.server.status).length) { var isOn = node.server.status.power === 'on'; var waterLevel = Math.ceil(node.server.status.depth / 1.2); var mode = node.server.status.mode; var status = { fill: waterLevel <= 15 ? "yellow" : (isOn ? "green" : "red"), shape: "dot", text: (isOn ? "On (" + mode + ")" : "Off") + ', ' + node.server.status.humidity + '%, ' + (!isNaN(parseFloat(node.server.status.temp_dec)) && isFinite(node.server.status.temp_dec)?(node.server.status.temp_dec / 10).toFixed(1) + '℃':'') + ' 💧' + waterLevel }; node.status(status); } } onInitEnd(status) { var node = this; node.connected = true; node.updateStatus(); if (node.config.outputAtStartup || node.config.for_homekit) { node.sendState(); } } onState(status) { var node = this; if (!node.connected) { if (node.config.outputAtStartup || node.config.for_homekit) { node.sendState(); node.updateStatus(); } } node.connected = true; } onStateChanged(data, output) { var node = this; if ("key" in data && ["power", "depth", "mode", "humidity", "temp_dec"].indexOf(data.key) >= 0) { node.updateStatus(); } if (output) { node.send({'payload':node.config.for_homekit?node.formatHomeKit():data, 'change': data, 'status': node.server.status}); } } onConnectionError(error) { var node = this; node.connected = false; var status = { fill: "red", shape: "dot", text: "node-red-contrib-miio-humidifier/in:status.disconnected" }; node.status(status); if (node.config.for_homekit) { node.send({ 'payload': node.formatHomeKitError(), 'status': null, 'error': error }); } } formatHomeKit() { var node = this; var status = node.server.status; var msg = {}; if (status.power === "on") { msg.Active = 1; msg.CurrentHumidifierDehumidifierState = 2; } else if (status.power === "off") { msg.Active = 0; msg.CurrentHumidifierDehumidifierState = 0; } if (status.child_lock === "on") { msg.LockPhysicalControls = 1; } else if (status.child_lock === "off") { msg.LockPhysicalControls = 0; } if (status.dry === "on") { msg.SwingMode = 1; } else if (status.dry === "off") { msg.SwingMode = 0; } if (status.mode === "auto") { msg.RotationSpeed = 25; } else if (status.mode === "silent") { msg.RotationSpeed = 50; } else if (status.mode === "medium") { msg.RotationSpeed = 75; } else if (status.mode === "high") { msg.RotationSpeed = 100; } else { msg.RotationSpeed = 0; } msg.WaterLevel = status.depth <= 120?Math.ceil(status.depth / 1.2):100; msg.CurrentRelativeHumidity = status.humidity; msg.TargetHumidifierDehumidifierState = 1; msg.RelativeHumidityHumidifierThreshold = status.limit_hum; return msg; } formatHomeKitError() { var msg = {}; msg.Active = "NO_RESPONSE"; msg.CurrentHumidifierDehumidifierState = "NO_RESPONSE"; msg.LockPhysicalControls = "NO_RESPONSE"; msg.SwingMode = "NO_RESPONSE"; msg.RotationSpeed = "NO_RESPONSE"; msg.WaterLevel = "NO_RESPONSE"; msg.CurrentRelativeHumidity = "NO_RESPONSE"; msg.TargetHumidifierDehumidifierState = "NO_RESPONSE"; msg.RelativeHumidityHumidifierThreshold = "NO_RESPONSE"; return msg; } } RED.nodes.registerType('miio-humidifier-input', MiioHumidifierInput, {}); };