From 5d8f69e4f4c6e92a3f2925b279d6c856353658b5 Mon Sep 17 00:00:00 2001 From: Tony Stork Date: Thu, 24 Apr 2025 01:25:44 -0400 Subject: [PATCH] Emma bedroom climate watchdog home_automation/HA-NerdFlows#31 --- climate/emma-bedroom/watchdog.js | 151 +++++++++++++++++++++++++++++-- 1 file changed, 142 insertions(+), 9 deletions(-) diff --git a/climate/emma-bedroom/watchdog.js b/climate/emma-bedroom/watchdog.js index e45382e..681a48c 100644 --- a/climate/emma-bedroom/watchdog.js +++ b/climate/emma-bedroom/watchdog.js @@ -1,18 +1,151 @@ +const states = global.get('homeassistant.homeAssistant.states') +const sleeping = states['input_boolean.emma_sleeping'].state + +if (sleeping !== 'on') { + node.status({fill:'red',shape:'ring',text:'Emma not sleeping, watchdog disabled'}) + return null +} + +const airconEntity = ['climate.emma_bedroom_aircon'] + +// Gather relevant attributes from the aircon entity + const airconState = msg.payload.state const airconAttributes = msg.payload.attributes -const airconPreset = airconAttributes['preset_mode'] const airconEco = airconAttributes['eco_mode'] const airconTargetTemp = airconAttributes['temperature'] const airconFanMode = airconAttributes['fan_mode'] const airconDisplay = airconAttributes['screen_display'] -msg.payload = { - "airconState": airconState, - "airconPreset": airconPreset, - "airconEco": airconEco, - "airconTargetTemp": airconTargetTemp, - "airconFanMode": airconFanMode, - "airconDisplay": airconDisplay +// Gather the last explicitly sent configuration from the context + +const airconHvacCfg = flow.get('emmaBedroom.airconHvacMode', 'diskCon') +const airconEcoCfg = flow.get('emmaBedroom.airconEco', 'diskCon') +const airconTargetTempCfg = parseFloat(flow.get('emmaBedroom.airconTargetTemp', 'diskCon')) +const airconFanModeCfg = flow.get('emmaBedroom.airconFanMode', 'diskCon') +const airconDisplayCfg = flow.get('emmaBedroom.airconDisplay', 'diskCon') + +// Compare the current state with the last sent configuration + +let ecoMatch = {} +let displayMatch = {} +let counter = 0 + +let sendDisplay = { + "payload": { + "action": `switch.${airconDisplayCfg}`, + "target": { + "entity_id": ["switch.emma_bedroom_aircon_display"] + }, + "data": {} + } } -return msg \ No newline at end of file +let sendHvac = { + "payload": { + "action": "climate.set_hvac_mode", + "target": { + "entity_id": airconEntity + }, + "data": { + "hvac_mode": airconHvacCfg + } + } +} + +let sendTemp = { + "payload": { + "action": "climate.set_temperature", + "target": { + "entity_id": airconEntity + }, + "data": { + "temperature": airconTargetTempCfg + } + } +} + +let sendEco = { + "payload": { + "action": `switch.${airconEcoCfg}`, + "target": { + "entity_id": ["switch.emma_bedroom_aircon_eco_mode"] + }, + "data": {} + } +} + +let sendAcFan = { + "payload": { + "action": "climate.set_fan_mode", + "target": { + "entity_id": airconEntity + }, + "data": { + "fan_mode": airconFanModeCfg + } + } +} + +// Fix hvac mode if mismatch + +if (airconState != airconHvacCfg) { + node.log(`Emma Bedroom Aircon HVAC mode mismatch: ${airconState} vs ${airconHvacCfg}`) + node.send(sendHvac) + counter += 1 +} + +// Fix eco mode if mismatch + +if (airconEco === false && airconEcoCfg === 'turn_off') { + ecoMatch = true +} else if (airconEco === true && airconEcoCfg === 'turn_on') { + ecoMatch = true +} else { + ecoMatch = false +} + +if (ecoMatch === false) { + node.log(`Emma Bedroom Aircon Eco mode mismatch: ${airconEco} vs ${airconEcoCfg}`) + node.send(sendEco) + counter += 1 +} + +// Fix target temperature if mismatch + +if (airconTargetTemp != airconTargetTempCfg) { + node.log(`Target temperature mismatch: ${airconTargetTemp} vs ${airconTargetTempCfg}`) + node.send(sendTemp) + counter += 1 +} + +// Fix fan mode if mismatch + +if (airconFanMode != airconFanModeCfg) { + node.log(`Fan mode mismatch: ${airconFanMode} vs ${airconFanModeCfg}`) + node.send(sendAcFan) + counter += 1 +} + +// Fix display mode if mismatch + +if (airconDisplay === false && airconDisplayCfg === 'turn_off') { + displayMatch = true +} else if (airconDisplay === true && airconDisplayCfg === 'turn_on') { + displayMatch = true +} else { + displayMatch = false +} + +if (displayMatch === false) { + node.log(`Emma Bedroom Aircon Display mode mismatch: ${airconDisplay} vs ${airconDisplayCfg}`) + node.send(sendDisplay) + counter += 1 +} + +if (counter > 0) { + node.log(`Emma Bedroom Aircon: ${counter} configuration(s) fixed`) + node.status({fill:'yellow',shape:'dot',text:`${counter} config(s) fixed`}) +} else { + node.status({fill:'green',shape:'dot',text:`No config changes`}) +} \ No newline at end of file