UNPKG

node-red-contrib-hubitat

Version:
154 lines (139 loc) 4.85 kB
module.exports = function HubitatHsmModule(RED) { function HubitatHsmNode(config) { RED.nodes.createNode(this, config); this.hubitat = RED.nodes.getNode(config.server); this.name = config.name; this.sendEvent = config.sendEvent; this.currentHsm = undefined; this.shape = this.sendEvent ? 'dot' : 'ring'; this.currentStatusText = ''; this.currentStatusFill = undefined; this.alert = false; 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 initializeHsm() { return node.hubitat.getHsm().then((hsm) => { if (!hsm) { throw new Error(JSON.stringify(hsm)); } node.currentHsm = hsm.hsm; node.log(`Initialized. HSM: ${node.currentHsm}`); node.updateStatus('blue', node.currentHsm); }).catch((err) => { node.warn(`Unable to initialize HSM: ${err.message}`); node.updateStatus('red', 'Uninitialized'); throw err; }); } const eventCallback = async (event) => { node.debug(`Event received: ${JSON.stringify(event)}`); if ((event.name === 'hsmAlert') && (['cancel', 'cancelRuleAlerts'].includes(event.value))) { node.alert = false; } else if (event.name === 'hsmAlert') { node.alert = true; } else if (event.name === 'hsmStatus') { node.currentHsm = event.value; } else { node.updateStatus('red', `Unknown event: ${event.name}`); return; } node.debug(`HSM: ${node.currentHsm}`); if (node.sendEvent) { const msg = { payload: { name: event.name, value: event.value, displayName: event.displayName, descriptionText: event.descriptionText, }, topic: 'hubitat-hsm', }; node.send(msg); } const color = this.alert ? 'red' : 'blue'; const status = this.alert ? `${node.currentHsm} - INTRUSION` : node.currentHsm; node.updateStatus(color, status); }; this.hubitat.hubitatEvent.on('hsm', eventCallback); const systemStartCallback = async () => { const previousHsm = node.currentHsm; try { await initializeHsm(); } catch (err) { return; } if (node.currentHsm !== previousHsm) { node.log(`Fix desynchronization: "${previousHsm}" --> "${node.currentHsm}"`); const event = { name: 'hsmStatus', value: node.currentHsm, 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); initializeHsm().catch(() => {}); node.on('input', async (msg, send, done) => { node.debug('Input received'); if (node.currentHsm === undefined) { try { await initializeHsm(); } catch (err) { return; } } const output = { ...msg, payload: { name: 'hsmStatus', value: node.currentHsm }, topic: 'hubitat-hsm', }; send(output); done(); }); node.on('close', () => { node.debug('Closed'); this.hubitat.hubitatEvent.removeListener('hsm', 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 hsm', HubitatHsmNode); };