Emma bedroom climate watchdog

home_automation/HA-NerdFlows#31
This commit is contained in:
2025-04-24 01:25:44 -04:00
parent 0b64c61cd1
commit 5d8f69e4f4

View File

@ -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
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`})
}