UNPKG

@gravypower/node-red-franklinwh

Version:

Node-RED node to control FranklinWH gateway

117 lines (102 loc) 4.21 kB
const apiHandler = require('../../../api-handler'); module.exports = function(RED) { const SWITCHES = { sw1: { id: 'sw1', name: 'Switch 1' }, sw2: { id: 'sw2', name: 'Switch 2' }, sw3: { id: 'sw3', name: 'Switch 3' } }; function formatSwitchState(id, state) { return `${id.toUpperCase()}:${state ? 'on' : 'off'}`; } function validateSwitch(sw) { if (!sw?.id || !SWITCHES[sw.id]) { throw new Error(`Invalid switch id: ${sw?.id}. Must be one of: ${Object.keys(SWITCHES).join(', ')}`); } if (typeof sw.state !== 'boolean') { throw new Error('Switch state must be a boolean'); } } function FranklinWHSetSwitchesNode(config) { RED.nodes.createNode(this, config); const node = this; const server = RED.nodes.getNode(config.server); if (!server) { node.status({fill:"red", shape:"ring", text:"missing config"}); node.error("No server configuration"); return; } function getConfiguredSwitches() { return [ { id: 'sw1', enabled: config.sw1enabled, state: config.sw1state }, { id: 'sw2', enabled: config.sw2enabled, state: config.sw2state }, { id: 'sw3', enabled: config.sw3enabled, state: config.sw3state } ] .filter(sw => sw.enabled) .map(({ id, state }) => ({ id, state: !!state })); } // Set initial status const initialSwitches = config.usePayload ? null : getConfiguredSwitches(); if (initialSwitches?.length) { node.status({ fill: "blue", shape: "dot", text: initialSwitches.map(sw => formatSwitchState(sw.id, sw.state)).join(', ') }); } else { node.status({ fill: "grey", shape: "ring", text: config.usePayload ? "waiting for input" : "no switches configured" }); } node.on("input", async function(msg, send, done) { try { // Get switches configuration const switches = config.usePayload ? (Array.isArray(msg.payload) ? msg.payload : [msg.payload]) : getConfiguredSwitches(); if (!switches?.length) { throw new Error('No switches provided'); } // Validate each switch switches.forEach(validateSwitch); node.status({fill: "yellow", shape: "dot", text: "setting switches..."}); await apiHandler.executeWithRetry( node, server, async (api) => { await api.setSmartSwitches(switches); return { switches: switches.map(sw => ({ ...sw, name: SWITCHES[sw.id].name, status: sw.state ? 'on' : 'off' })), summary: switches.map(sw => `${SWITCHES[sw.id].name}: ${sw.state ? 'on' : 'off'}` ).join(', ') }; }, msg, send, done ); node.status({ fill: "green", shape: "dot", text: switches.map(sw => formatSwitchState(sw.id, sw.state)).join(', ') }); } catch (err) { const errorMsg = err.message || 'Unknown error'; node.status({fill: "red", shape: "ring", text: errorMsg.substring(0, 25)}); node.error("FranklinWH Error: " + errorMsg, msg); if (done) done(err); } }); node.on('close', function(done) { node.status({}); done(); }); } RED.nodes.registerType("franklinwh-set-switches", FranklinWHSetSwitchesNode); }