Created
June 9, 2024 21:58
-
-
Save M4GNV5/056f69677771a7ad53aea9b96eb48aad to your computer and use it in GitHub Desktop.
smart home energy management
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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