Skip to content

Instantly share code, notes, and snippets.

@M4GNV5
Created June 9, 2024 21:58
Show Gist options
  • Save M4GNV5/056f69677771a7ad53aea9b96eb48aad to your computer and use it in GitHub Desktop.
Save M4GNV5/056f69677771a7ad53aea9b96eb48aad to your computer and use it in GitHub Desktop.
smart home energy management
// output nodes: [miner on/off, ventilation target, temperature target, user message]
const enabled = global.get("enablePvHeating");
const minerEnabled = global.get("enablePvMining");
const roomTempLow = parseFloat(global.get("minTemperature"));
const pvPower = parseFloat(flow.get("pvPower"));
const temp = parseFloat(flow.get("insideTemperature"));
const tempToHouse = parseFloat(flow.get("toHouseTemperature"));
const ventTarget = parseFloat(flow.get("ventilationTarget"));
const minerStatus = flow.get("minerStatus");
const roomTempNorm = 19;
const roomTempHigh = 21;
const heatpumpPower = 500;
const minerPower = 700;
const lastPvPowers = JSON.parse(context.get("lastPvPowers") || "[]");
if (lastPvPowers.length < 1 || Date.now() - lastPvPowers[lastPvPowers.length - 1].timestamp > 1 * 60 * 1000) {
lastPvPowers.push({ timestamp: Date.now(), power: pvPower });
if (lastPvPowers.length > 15)
lastPvPowers.splice(0, 1)
context.set("lastPvPowers", JSON.stringify(lastPvPowers));
node.log(`updated lastPvPowers: ${JSON.stringify(lastPvPowers) }`);
}
if(!enabled)
return new Array(node.outputCount); // do nothing
const lastChange = context.get("lastChange");
if(Date.now() - lastChange < 5 * 60 * 1000)
return new Array(node.outputCount); // do nothing
function telegramMsg(text) {
return {
chatId: 211452800,
type: "message",
content: text,
};
}
function isPvAbove(x) {
return lastPvPowers.length > 10 && lastPvPowers.every(y => x < y.power);
}
function isPvBelow(x) {
return lastPvPowers.every(y => x > y.power);
}
function determineHeating() {
if (temp < roomTempLow)
return [false, 1, roomTempNorm, telegramMsg("Starting the heatpump!")]
else if(minerEnabled && isPvAbove(minerPower + heatpumpPower))
return [true, 1, roomTempHigh, telegramMsg("Using ALL THE HEAT!")]
else if (minerEnabled && isPvAbove(minerPower) && isPvBelow(minerPower + heatpumpPower))
return [true, 0, roomTempHigh, telegramMsg("Using PV based BTC mining for heat!")]
else if (isPvAbove(heatpumpPower) && (!minerEnabled || isPvBelow(minerPower)))
return [false, 1, roomTempHigh, telegramMsg("Using PV heatpumping!")]
else if (minerStatus && isPvBelow(minerPower))
return [false, ventTarget, roomTempHigh, telegramMsg("Stopping the BTC miner!")]
else if (ventTarget > 0 && temp >= roomTempLow + 2 && isPvBelow(heatpumpPower))
return [false, 0, roomTempHigh, telegramMsg("Stopping PV heatpumping!")]
}
const result = determineHeating();
if(result) {
context.set("lastChange", Date.now());
return result.map(x => ({ payload: x }));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment