UNPKG

node-red-contrib-hubitat

Version:
137 lines (123 loc) 4.36 kB
module.exports = function HubitatModeModule(RED) { function HubitatModeNode(config) { RED.nodes.createNode(this, config); this.hubitat = RED.nodes.getNode(config.server); this.name = config.name; this.sendEvent = config.sendEvent; this.currentMode = undefined; this.shape = this.sendEvent ? 'dot' : 'ring'; this.currentStatusText = ''; this.currentStatusFill = undefined; const node = this; if (!node.hubitat) { node.error('Hubitat server not configured'); return; } this.updateStatus = (fill = null, text = null) => { const status = { fill, shape: this.shape, text }; node.currentStatusText = text; node.currentStatusFill = fill; if (fill === null) { delete status.shape; delete status.fill; } if (text === null) { delete status.text; } if (node.hubitat.useWebsocket) { if (fill === null) { status.fill = 'green'; status.shape = this.shape; } else if (fill === 'blue') { status.fill = 'green'; } if (!node.hubitat.wsStatusOk) { status.fill = 'red'; status.text = 'WS ERROR'; } } node.status(status); }; async function initializeMode() { return node.hubitat.getMode().then((mode) => { if (!mode) { throw new Error(JSON.stringify(mode)); } node.currentMode = mode.filter((eachMode) => eachMode.active)[0].name; node.log(`Initialized. mode: ${node.currentMode}`); node.updateStatus('blue', node.currentMode); }).catch((err) => { node.warn(`Unable to initialize mode: ${err.message}`); node.updateStatus('red', 'Uninitialized'); throw err; }); } const eventCallback = async (event) => { node.debug(`Event received: ${JSON.stringify(event)}`); node.currentMode = event.value; node.debug(`Mode: ${node.currentMode}`); if (node.sendEvent) { const msg = { payload: { name: 'mode', value: node.currentMode, displayName: event.displayName, descriptionText: event.descriptionText, }, topic: 'hubitat-mode', }; node.send(msg); } node.updateStatus('blue', node.currentMode); }; this.hubitat.hubitatEvent.on('mode', eventCallback); const systemStartCallback = async () => { const previousMode = node.currentMode; try { await initializeMode(); } catch (err) { return; } if (node.currentMode !== previousMode) { node.log(`Fix desynchronization: "${previousMode}" --> "${node.currentMode}"`); const event = { value: node.currentMode, descriptionText: 'Event triggered by systemStart and generated by Node-RED' }; eventCallback(event); } }; this.hubitat.hubitatEvent.on('systemStart', systemStartCallback); const wsOpened = async () => { node.updateStatus(node.currentStatusFill, node.currentStatusText); }; this.hubitat.hubitatEvent.on('websocket-opened', wsOpened); const wsClosed = async () => { node.updateStatus(node.currentStatusFill, node.currentStatusText); }; this.hubitat.hubitatEvent.on('websocket-closed', wsClosed); this.hubitat.hubitatEvent.on('websocket-error', wsClosed); initializeMode().catch(() => {}); node.on('input', async (msg, send, done) => { node.debug('Input received'); if (node.currentMode === undefined) { try { await initializeMode(); } catch (err) { return; } } const output = { ...msg, payload: { name: 'mode', value: node.currentMode }, topic: 'hubitat-mode', }; send(output); done(); }); node.on('close', () => { node.debug('Closed'); this.hubitat.hubitatEvent.removeListener('mode', eventCallback); this.hubitat.hubitatEvent.removeListener('systemStart', systemStartCallback); this.hubitat.hubitatEvent.removeListener('websocket-opened', wsOpened); this.hubitat.hubitatEvent.removeListener('websocket-closed', wsClosed); this.hubitat.hubitatEvent.removeListener('websocket-error', wsClosed); }); } RED.nodes.registerType('hubitat mode', HubitatModeNode); };