@gravypower/node-red-franklinwh
Version:
Node-RED node to control FranklinWH gateway
93 lines (80 loc) • 3.56 kB
JavaScript
const apiHandler = require('../../../api-handler');
module.exports = function(RED) {
const MIN_RESERVE = 5;
const MAX_RESERVE = 100;
function FranklinWHSetReserveNode(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;
}
// Set initial status based on configuration
if (!config.usePayload && config.reserveValue) {
node.status({fill:"blue", shape:"dot", text:`Default: ${config.reserveValue}%`});
} else {
node.status({fill:"grey", shape:"ring", text:"waiting for input"});
}
node.on("input", async function (msg, send, done) {
let reserveValue;
try {
// Determine value source and validate
if (config.usePayload) {
if (msg.payload === undefined || msg.payload === null || msg.payload === '') {
throw new Error('No reserve value provided in payload');
}
reserveValue = parseFloat(msg.payload);
} else {
if (!config.reserveValue) {
throw new Error('No reserve value provided in configuration');
}
reserveValue = parseFloat(config.reserveValue);
}
// Validate value
if (isNaN(reserveValue)) {
throw new Error('Reserve value must be a number');
}
// Round to nearest integer
reserveValue = Math.round(reserveValue);
if (reserveValue < MIN_RESERVE || reserveValue > MAX_RESERVE) {
throw new Error(`Reserve value must be between ${MIN_RESERVE} and ${MAX_RESERVE}`);
}
// Show processing status
node.status({fill:"yellow", shape:"dot", text:`Setting: ${reserveValue}%`});
await apiHandler.executeWithRetry(
node,
server,
async (api) => {
const success = await api.setReserve(reserveValue);
if (!success) {
throw new Error('Failed to set battery reserve');
}
return {
reserve: reserveValue,
success: success,
unit: '%',
description: `Battery reserve set to ${reserveValue}%`
};
},
msg,
send,
done
);
// Update status with success
node.status({fill:"green", shape:"dot", text:`Reserve: ${reserveValue}%`});
} 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-reserve", FranklinWHSetReserveNode);
}