diff --git a/flows.json b/flows.json index f616688..77a6f3b 100644 --- a/flows.json +++ b/flows.json @@ -1730,6 +1730,8 @@ ], "x": 34, "y": 719, + "w": 732, + "h": 282, "info": "https://stackoverflow.com/a/74399359" }, { @@ -1741,7 +1743,6 @@ "label": true }, "nodes": [ - "f5879622a44b7213", "5848c6edf2bd06fe", "3bb9755d18f517d6", "c52f61fa427a773c", @@ -1765,10 +1766,16 @@ "514057723d9662e0", "1df32d98b498c875", "192260163c49816a", - "79f3ceee718cd7cb" + "79f3ceee718cd7cb", + "14181143d23aa423", + "f9e1aec6c25f6480", + "0693239363c59c3e", + "44b7eabdec8197a3" ], "x": 34, - "y": 19 + "y": 19, + "w": 752, + "h": 682 }, { "id": "50e4d951ee7b3e54", @@ -16200,11 +16207,11 @@ "z": "72f99805df043603", "g": "e065b1ed4938b477", "name": "Processing", - "func": "node.log(\"Master Bedroom Climate: Processing Started\")\n// pull in the necessary information\n\nconst states = global.get('homeassistant.homeAssistant.states')\nconst allowed = states['input_boolean.master_bedroom_climate_protocol'].state\nconst ac = global.get('mb_aircon_installed', \"diskCon\")\nconst temp = global.get(\"tempStr\")\nconst payload = msg.payload\nconst vacation = states['input_boolean.vacation_mode'].state\nconst highTemp = states['sensor.today_corrected_high_temp'].state\nconst dayTemp = states['input_number.master_bedroom_daytime_temp'].state\nconst nightTemp = states['input_number.master_bedroom_night_temp'].state\nconst bedTemp = states['input_number.master_bedroom_bedtime_temp'].state\nconst showerMode = states['input_boolean.shower_mode'].state\nconst nightVolume = states['input_number.master_bedroom_echo_dot_night_volume'].state\nconst fanMode = states['input_select.scheduled_climate_mode_master_bedroom_fan'].state\nconst acMode = states['input_select.scheduled_climate_mode_master_bedroom_aircon'].state\nconst sleeping = states['input_boolean.master_bedroom_sleeping'].state\nconst hotDay = states['input_boolean.hot_day'].state\nconst heatWarning = states[\"binary_sensor.heat_warning\"].state\nconst showerCooldown = states[\"timer.shower_mode_cooldown\"].state\nconst earlyNight = states[\"binary_sensor.early_night_mode\"].state\nconst danger = states['binary_sensor.heat_warning'].attributes.danger\nconst meltdown = states['input_boolean.meltdown_protocol'].state\nconst coolingActive = states['input_boolean.master_bedroom_cooling_on'].state\nconst echoDotDND = 'switch.basement_echo_dot_do_not_disturb_switch'\nnode.log(\"Master Bedroom Climate: Constants Set\")\n\n// init variables\n\nlet setTemp = []\nlet setEco = []\nlet setHvac = []\nlet setFan = []\nlet setCool = []\nlet setSleep = []\nlet setDisplay = []\nlet time = []\nlet type = msg.type\nlet topic = msg.topic\nlet echoDotService = []\nlet setBriefing = []\nlet setBriefingDelay = []\nnode.log(\"Master Bedroom Climate: Variables Defined\")\n\n// Sleep Switch Handling\nif (type === 'sleep' && payload === 'off') {\n setDisplay = 'turn_on'\n echoDotService = 'turn_off'\n if (coolingActive === 'on') {\n time = 'night'\n } else {\n time = 'day'\n }\n} else if (type === 'sleep' && payload === 'on') {\n setDisplay = 'turn_off'\n echoDotService = 'turn_on'\n time = 'bedtime'\n} else {\n time = msg.time\n}\n\nif (topic === 'mrbedroom-wakeup') {\n setSleep = 'turn_off'\n}\n\n// Setup TTS briefing\nif (time === 'day') {\n setBriefing = \"master_bedroom_wakeup_briefing\"\n if (topic === 'mrbedroom-wakeup') {\n setBriefingDelay = 60\n } else if (type === 'sleep' && payload === 'off') {\n setBriefingDelay = 15\n }\n}\n\n// Day Time\nif (time === 'day') {\n if (type === 'auto') {\n setCool = 'turn_off'\n setBriefingDelay = 60\n } else if (type === 'manual') {\n setBriefingDelay = 15\n }\n if (earlyNight === 'off') {\n setFan = \"turn_off\"\n if (ac === 'on') {\n if (danger === 'Extreme') {\n setTemp = nightTemp\n setEco = \"eco\"\n setHvac = \"cool\"\n } else if (hotDay === 'on' || heatWarning === 'on') {\n setTemp = dayTemp\n setEco = \"eco\"\n setHvac = \"cool\"\n } else {\n setTemp = nightTemp\n setEco = \"eco\"\n setHvac = \"off\"\n }\n }\n } else if (earlyNight === 'on') {\n if (ac === 'on') {\n if (danger === 'Extreme') {\n setTemp === bedTemp\n } else {\n setTemp = nightTemp\n }\n if (fanMode === 'Fan') {\n setFan = 'turn_on'\n } else {\n setFan = 'turn_off'\n }\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'fan') {\n setHvac = 'fan_only'\n } else {\n setHvac = 'off'\n }\n if (hotDay === 'on') {\n setEco = 'off'\n } else {\n setEco = 'on'\n }\n }\n }\n// Night Time\n} else if (time === 'night') {\n if (type === 'auto') {\n setCool = 'turn_on'\n }\n if (danger === 'Extreme') {\n setTemp = bedTemp\n } else {\n setTemp = nightTemp\n }\n if (hotDay === 'on' || sleeping === 'on') {\n setEco = 'none'\n } else {\n setEco = 'eco'\n }\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'Fan') {\n setHvac = 'fan_only'\n } else {\n setHvac = 'off'\n }\n if (type === 'sleep' && payload === 'off') {\n setFan = 'turn_off'\n } else if (fanMode === 'Fan') {\n setFan = 'turn_on'\n }\n// Bed Time\n} else if (time === 'bedtime') {\n if (ac === 'on') {\n setTemp = bedTemp\n setEco = 'none'\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'Fan') {\n setHvac = \"fan_only\"\n }\n }\n if (fanMode === 'Fan') {\n setFan = 'turn_on'\n }\n}\nnode.log(\"Master Bedroom Climate: Decision Logic Complete\")\n\n// Define message payloads\n\nlet sendFan = {\n \"payload\": {\n \"domain\": \"fan\",\n \"service\": setFan,\n \"target\": {\n \"entity_id\": [\"fan.master_bedroom_fan\"]\n },\n \"data\": {}\n }\n}\n\nlet sendCool = {\n \"payload\": {\n \"domain\": \"input_boolean\",\n \"service\": setCool,\n \"target\": {\n \"entity_id\": [\"input_boolean.master_bedroom_cooling_on\"]\n },\n \"data\": {}\n }\n}\n\nlet sendSleep = {\n \"payload\": {\n \"domain\": \"input_boolean\",\n \"service\": setSleep,\n \"target\": {\n \"entity_id\": [\"input_boolean.master_bedroom_sleeping\"]\n },\n \"data\": {}\n }\n}\n\nlet sendDisplay = {\n \"payload\": {\n \"domain\": \"switch\",\n \"service\": setDisplay,\n \"target\": {\n \"entity_id\": [\"switch.master_bedroom_aircon_display\"]\n },\n \"data\": {}\n }\n}\n\nlet notify = {\n \"topic\": topic,\n \"nighttemp\": nightTemp,\n \"acmode\": acMode,\n \"fanmode\": fanMode\n}\n\nlet sendBriefing = {\n \"payload\": {\n \"domain\": \"script\",\n \"service\": setBriefing\n },\n \"delay\": setBriefingDelay\n}\n\nlet sendHvac = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_hvac_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"hvac_mode\": setHvac\n }\n }\n}\n\nlet sendTemp = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_temperature\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"temperature\": setTemp\n }\n }\n}\n\nlet sendEco = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_preset_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"preset_mode\": setEco\n }\n }\n}\n\nlet sendAcFan = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_fan_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"fan_mode\": \"Auto\"\n }\n }\n}\n\nlet sendEchoDotDND = {\n \"payload\": {\n \"domain\": \"switch\",\n \"service\": echoDotService,\n \"target\": {\n \"entity_id\": [\"switch.basement_echo_dot_do_not_disturb_switch\"]\n },\n \"data\": {}\n }\n}\n\nnode.log(\"Master Bedroom Climate: Message Payloads Defined\")\n\n// Log the parameters that were chosen, for debugging purposes\n\nnode.log(\"----- Master Bedroom Climate: Set Parameters -----\")\nnode.log(\"setTemp: \" + setTemp)\nnode.log(\"setEco: \" + setEco)\nnode.log(\"setHvac: \" + setHvac)\nnode.log(\"setFan: \" + setFan)\nnode.log(\"setCool: \" + setCool)\nnode.log(\"setSleep: \" + setSleep)\nnode.log(\"setDisplay: \" + setDisplay)\nnode.log(\"setBriefing: \" + setBriefing)\nnode.log(\"setBriefingDelay: \" + setBriefingDelay)\nnode.log(\"time: \" + time)\nnode.log(\"type: \" + type)\nnode.log(\"topic: \" + topic)\nnode.log(\"----- Master Bedroom Climate: End Parameters -----\")\n\n// If this was an automated trigger, set the cooling context for the bedroom accordingly.\n\nif (type === 'auto' && time != 'bedtime') {\n node.send([null, null, sendCool, null, null])\n node.log(\"Master Bedroom Climate: Cooling Context Set\")\n}\n\n// Automated responses\nif (type === 'auto' && allowed === 'on' && meltdown === 'off' && vacation === 'off') {\n node.log(\"Master Bedroom Climate: Auto\")\n if (sleeping === 'on' && topic != 'mrbedroom-wakeup') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (sleep mode)\" })\n node.log(\"Master Bedroom Climate: Blocked (sleep mode)\")\n } else {\n if (topic === 'mrbedroom-cooling' && ac === 'on') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Cooling Schedule\" })\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Cooling\")\n } else if (topic === 'mrbedroom-bedtime') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Bedtime\" })\n node.log(\"Master Bedroom Climate: Auto/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Bedtime/AC\")\n }\n if (fanMode === 'fan') {\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Bedtime/Fan\")\n }\n } else if (topic === 'mrbedroom-fan' && fanMode === 'Fan') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Fan Schedule\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Fan\")\n } else if (topic === 'mrbedroom-wakeup') {\n node.send([null, null, null, null, sendBriefing])\n node.status({ fill: \"green\", shape: \"dot\", text: \"Wakeup Schedule\" })\n node.log(\"Master Bedroom Climate: Auto/Wakeup\")\n if (sleeping === 'off') {\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/Sleep Off\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/AC On\")\n }\n } else if (sleeping === 'on') {\n node.send([null, null, sendSleep, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/Sleep On\")\n }\n }\n }\n// Manual Responses\n} else if (type === 'manual') {\n node.log(\"Master Bedroom Climate: Manual\")\n if (time === 'night') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Night\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Night\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Night/AC\")\n }\n } else if (time === 'day') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Day\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Day\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Day/AC\")\n }\n } else if (time === 'bedtime') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Bedtime\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Bedtime/AC\")\n }\n }\n} else if (type === 'sleep') {\n node.log(\"Master Bedroom Climate: Sleep\")\n if (time === 'night') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Wakeup (Hot Day)\" })\n node.send([null, sendFan, sendEchoDotDND, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Night\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Night/AC\")\n }\n } else if (time === 'day') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Wakeup\" })\n node.send([null, sendFan, sendEchoDotDND, null, sendBriefing])\n node.log(\"Master Bedroom Climate: Sleep/Day\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Day/AC\")\n }\n } else if (time === 'bedtime') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Sleep\" })\n node.send([null, sendFan, sendEchoDotDND, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Bedtime\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Bedtime/AC\")\n }\n }\n} else if (meltdown === 'on') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Meltdown Protocol)\" })\n node.log(\"Master Bedroom Climate: Blocked (Meltdown Protocol)\")\n} else if (vacation === 'on') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Vacation Mode)\" })\n node.log(\"Master Bedroom Climate: Blocked (Vacation Mode)\")\n} else {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Automation Disabled)\" })\n node.log(\"Master Bedroom Climate: Blocked (Automation Disabled)\")\n}\n\nnode.log(\"Master Bedroom Climate: Processing Complete\")\n", + "func": "node.log(\"Master Bedroom Climate: Processing Started\")\n// pull in the necessary information\n\nconst states = global.get('homeassistant.homeAssistant.states')\nconst allowed = states['input_boolean.master_bedroom_climate_protocol'].state\nconst ac = global.get('mb_aircon_installed', \"diskCon\")\nconst temp = global.get(\"tempStr\")\nconst payload = msg.payload\nconst vacation = states['input_boolean.vacation_mode'].state\nconst highTemp = states['sensor.today_corrected_high_temp'].state\nconst dayTemp = states['input_number.master_bedroom_daytime_temp'].state\nconst nightTemp = states['input_number.master_bedroom_night_temp'].state\nconst bedTemp = states['input_number.master_bedroom_bedtime_temp'].state\nconst showerMode = states['input_boolean.shower_mode'].state\nconst nightVolume = states['input_number.master_bedroom_echo_dot_night_volume'].state\nconst fanMode = states['input_select.scheduled_climate_mode_master_bedroom_fan'].state\nconst acMode = states['input_select.scheduled_climate_mode_master_bedroom_aircon'].state\nconst sleeping = states['input_boolean.master_bedroom_sleeping'].state\nconst hotDay = states['input_boolean.hot_day'].state\nconst heatWarning = states[\"binary_sensor.heat_warning\"].state\nconst showerCooldown = states[\"timer.shower_mode_cooldown\"].state\nconst earlyNight = states[\"binary_sensor.early_night_mode\"].state\nconst danger = states['binary_sensor.heat_warning'].attributes.danger\nconst meltdown = states['input_boolean.meltdown_protocol'].state\nconst coolingActive = states['input_boolean.master_bedroom_cooling_on'].state\nconst echoDotDND = 'switch.basement_echo_dot_do_not_disturb_switch'\nnode.log(\"Master Bedroom Climate: Constants Set\")\n\n// init variables\n\nlet setTemp = []\nlet setEco = []\nlet setHvac = []\nlet setFan = []\nlet setCool = []\nlet setSleep = []\nlet setDisplay = []\nlet time = []\nlet echoDotService = []\nlet setBriefing = []\nlet setBriefingDelay = []\nlet type = msg.type\nlet topic = msg.topic\nlet isWakeup = context.get(\"isWakeup\")\nnode.log(\"Master Bedroom Climate: Variables Defined\")\n\n// Sleep Switch Handling\nif (type === 'sleep' && payload === 'off') {\n setDisplay = 'turn_on'\n echoDotService = 'turn_off'\n if (coolingActive === 'on') {\n time = 'night'\n } else {\n time = 'day'\n }\n} else if (type === 'sleep' && payload === 'on') {\n setDisplay = 'turn_off'\n echoDotService = 'turn_on'\n time = 'bedtime'\n} else {\n time = msg.time\n}\n\nif (topic === 'mrbedroom-wakeup') {\n setSleep = 'turn_off'\n}\n\n// Setup TTS briefing\nif (topic === 'mrbedroom-wakeup') {\n setBriefing = \"master_bedroom_wakeup_briefing\"\n setBriefingDelay = 60000\n} else if (type === 'sleep' && payload === 'off') {\n setBriefing = \"master_bedroom_wakeup_briefing\"\n setBriefingDelay = 15000\n}\n\n// Day Time\nif (time === 'day') {\n if (type === 'auto') {\n setCool = 'turn_off'\n }\n if (earlyNight === 'off') {\n setFan = \"turn_off\"\n if (ac === 'on') {\n if (danger === 'Extreme') {\n setTemp = nightTemp\n setEco = \"eco\"\n setHvac = \"cool\"\n } else if (hotDay === 'on' || heatWarning === 'on') {\n setTemp = dayTemp\n setEco = \"eco\"\n setHvac = \"cool\"\n } else {\n setTemp = nightTemp\n setEco = \"eco\"\n setHvac = \"off\"\n }\n }\n } else if (earlyNight === 'on') {\n if (ac === 'on') {\n if (danger === 'Extreme') {\n setTemp === bedTemp\n } else {\n setTemp = nightTemp\n }\n if (fanMode === 'Fan') {\n setFan = 'turn_on'\n } else {\n setFan = 'turn_off'\n }\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'fan') {\n setHvac = 'fan_only'\n } else {\n setHvac = 'off'\n }\n if (hotDay === 'on') {\n setEco = 'off'\n } else {\n setEco = 'on'\n }\n }\n }\n// Night Time\n} else if (time === 'night') {\n if (type === 'auto') {\n setCool = 'turn_on'\n }\n if (danger === 'Extreme') {\n setTemp = bedTemp\n } else {\n setTemp = nightTemp\n }\n if (hotDay === 'on' || sleeping === 'on') {\n setEco = 'none'\n } else {\n setEco = 'eco'\n }\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'Fan') {\n setHvac = 'fan_only'\n } else {\n setHvac = 'off'\n }\n if (type === 'sleep' && payload === 'off') {\n setFan = 'turn_off'\n } else if (fanMode === 'Fan') {\n setFan = 'turn_on'\n }\n// Bed Time\n} else if (time === 'bedtime') {\n if (ac === 'on') {\n setTemp = bedTemp\n setEco = 'none'\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'Fan') {\n setHvac = \"fan_only\"\n }\n }\n if (fanMode === 'Fan') {\n setFan = 'turn_on'\n }\n}\nnode.log(\"Master Bedroom Climate: Decision Logic Complete\")\n\n// Define message payloads\n\nlet sendFan = {\n \"payload\": {\n \"domain\": \"fan\",\n \"service\": setFan,\n \"target\": {\n \"entity_id\": [\"fan.master_bedroom_fan\"]\n },\n \"data\": {}\n }\n}\n\nlet sendCool = {\n \"payload\": {\n \"domain\": \"input_boolean\",\n \"service\": setCool,\n \"target\": {\n \"entity_id\": [\"input_boolean.master_bedroom_cooling_on\"]\n },\n \"data\": {}\n }\n}\n\nlet sendSleep = {\n \"payload\": {\n \"domain\": \"input_boolean\",\n \"service\": setSleep,\n \"target\": {\n \"entity_id\": [\"input_boolean.master_bedroom_sleeping\"]\n },\n \"data\": {}\n }\n}\n\nlet sendDisplay = {\n \"payload\": {\n \"domain\": \"switch\",\n \"service\": setDisplay,\n \"target\": {\n \"entity_id\": [\"switch.master_bedroom_aircon_display\"]\n },\n \"data\": {}\n }\n}\n\nlet notify = {\n \"topic\": topic,\n \"nighttemp\": nightTemp,\n \"acmode\": acMode,\n \"fanmode\": fanMode\n}\n\nlet sendBriefing = {\n \"payload\": {\n \"domain\": \"script\",\n \"service\": setBriefing\n },\n \"delay\": setBriefingDelay\n}\n\nlet sendHvac = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_hvac_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"hvac_mode\": setHvac\n }\n }\n}\n\nlet sendTemp = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_temperature\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"temperature\": setTemp\n }\n }\n}\n\nlet sendEco = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_preset_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"preset_mode\": setEco\n }\n }\n}\n\nlet sendAcFan = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_fan_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"fan_mode\": \"Auto\"\n }\n }\n}\n\nlet sendEchoDotDND = {\n \"payload\": {\n \"domain\": \"switch\",\n \"service\": echoDotService,\n \"target\": {\n \"entity_id\": [\"switch.basement_echo_dot_do_not_disturb_switch\"]\n },\n \"data\": {}\n }\n}\n\nnode.log(\"Master Bedroom Climate: Message Payloads Defined\")\n\n// Log the parameters that were chosen, for debugging purposes\n\nnode.log(\"----- Master Bedroom Climate: Set Parameters -----\")\nnode.log(\"setTemp: \" + setTemp)\nnode.log(\"setEco: \" + setEco)\nnode.log(\"setHvac: \" + setHvac)\nnode.log(\"setFan: \" + setFan)\nnode.log(\"setCool: \" + setCool)\nnode.log(\"setSleep: \" + setSleep)\nnode.log(\"setDisplay: \" + setDisplay)\nnode.log(\"setBriefing: \" + setBriefing)\nnode.log(\"setBriefingDelay: \" + setBriefingDelay)\nnode.log(\"time: \" + time)\nnode.log(\"type: \" + type)\nnode.log(\"topic: \" + topic)\nnode.log(\"----- Master Bedroom Climate: End Parameters -----\")\n\n// If this was an automated trigger, set the cooling context for the bedroom accordingly.\n\nif (type === 'auto' && time != 'bedtime') {\n node.send([null, null, sendCool, null, null])\n node.log(\"Master Bedroom Climate: Cooling Context Set\")\n}\n\n// Automated responses\nif (type === 'auto' && allowed === 'on' && meltdown === 'off' && vacation === 'off') {\n node.log(\"Master Bedroom Climate: Auto\")\n if (sleeping === 'on' && topic != 'mrbedroom-wakeup') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (sleep mode)\" })\n node.log(\"Master Bedroom Climate: Blocked (sleep mode)\")\n } else {\n if (topic === 'mrbedroom-cooling' && ac === 'on') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Cooling Schedule\" })\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Cooling\")\n } else if (topic === 'mrbedroom-bedtime') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Bedtime\" })\n node.log(\"Master Bedroom Climate: Auto/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Bedtime/AC\")\n }\n if (fanMode === 'fan') {\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Bedtime/Fan\")\n }\n } else if (topic === 'mrbedroom-fan' && fanMode === 'Fan') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Fan Schedule\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Fan\")\n } else if (topic === 'mrbedroom-wakeup') {\n node.send([null, null, null, null, sendBriefing])\n node.status({ fill: \"green\", shape: \"dot\", text: \"Wakeup Schedule\" })\n node.log(\"Master Bedroom Climate: Auto/Wakeup\")\n if (sleeping === 'off') {\n context.set(\"isWakeup\", false)\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/Sleep Off\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/AC On\")\n }\n } else if (sleeping === 'on') {\n context.set(\"isWakeup\", true)\n node.send([null, null, sendSleep, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/Sleep On\")\n }\n }\n }\n// Manual Responses\n} else if (type === 'manual') {\n node.log(\"Master Bedroom Climate: Manual\")\n if (time === 'night') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Night\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Night\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Night/AC\")\n }\n } else if (time === 'day') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Day\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Day\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Day/AC\")\n }\n } else if (time === 'bedtime') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Bedtime\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Bedtime/AC\")\n }\n }\n context.set(\"isWakeup\", false)\n} else if (type === 'sleep') {\n node.log(\"Master Bedroom Climate: Sleep\")\n if (time === 'night') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Wakeup (Hot Day)\" })\n node.send([null, sendFan, sendEchoDotDND, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Night\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Night/AC\")\n }\n } else if (time === 'day') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Wakeup\" })\n node.send([null, sendFan, sendEchoDotDND, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Day\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Day/AC\")\n }\n if (isWakeup === false) {\n node.send([null, null, null, null, sendBriefing])\n }\n } else if (time === 'bedtime') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Sleep\" })\n node.send([null, sendFan, sendEchoDotDND, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Bedtime\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Bedtime/AC\")\n }\n }\n context.set(\"isWakeup\", false)\n} else if (meltdown === 'on') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Meltdown Protocol)\" })\n node.log(\"Master Bedroom Climate: Blocked (Meltdown Protocol)\")\n} else if (vacation === 'on') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Vacation Mode)\" })\n node.log(\"Master Bedroom Climate: Blocked (Vacation Mode)\")\n} else {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Automation Disabled)\" })\n node.log(\"Master Bedroom Climate: Blocked (Automation Disabled)\")\n}\n\nnode.log(\"Master Bedroom Climate: Processing Complete\")\n", "outputs": 5, "timeout": "", "noerr": 0, - "initialize": "", + "initialize": "context.set(\"isWakeup\", false)", "finalize": "", "libs": [], "x": 550, @@ -28750,42 +28757,6 @@ "y": 760, "wires": [] }, - { - "id": "f5879622a44b7213", - "type": "function", - "z": "d49b385d8b582b20", - "g": "c3dc29879117218b", - "name": "Processing", - "func": "node.log(\"Master Bedroom Climate: Processing Started\")\n// pull in the necessary information\n\nconst states = global.get('homeassistant.homeAssistant.states')\nconst allowed = states['input_boolean.master_bedroom_climate_protocol'].state\nconst ac = global.get('mb_aircon_installed', \"diskCon\")\nconst temp = global.get(\"tempStr\")\nconst payload = msg.payload\nconst vacation = states['input_boolean.vacation_mode'].state\nconst highTemp = states['sensor.today_corrected_high_temp'].state\nconst dayTemp = states['input_number.master_bedroom_daytime_temp'].state\nconst nightTemp = states['input_number.master_bedroom_night_temp'].state\nconst bedTemp = states['input_number.master_bedroom_bedtime_temp'].state\nconst showerMode = states['input_boolean.shower_mode'].state\nconst nightVolume = states['input_number.master_bedroom_echo_dot_night_volume'].state\nconst fanMode = states['input_select.scheduled_climate_mode_master_bedroom_fan'].state\nconst acMode = states['input_select.scheduled_climate_mode_master_bedroom_aircon'].state\nconst sleeping = states['input_boolean.master_bedroom_sleeping'].state\nconst hotDay = states['input_boolean.hot_day'].state\nconst heatWarning = states[\"binary_sensor.heat_warning\"].state\nconst showerCooldown = states[\"timer.shower_mode_cooldown\"].state\nconst earlyNight = states[\"binary_sensor.early_night_mode\"].state\nconst danger = states['binary_sensor.heat_warning'].attributes.danger\nconst meltdown = states['input_boolean.meltdown_protocol'].state\nconst coolingActive = states['input_boolean.master_bedroom_cooling_on'].state\nnode.log(\"Master Bedroom Climate: Constants Set\")\n\n// init variables\n\nlet setTemp = []\nlet setEco = []\nlet setHvac = []\nlet setFan = []\nlet setCool = []\nlet setSleep = []\nlet time = []\nlet type = msg.type\nlet topic = msg.topic\nnode.log(\"Master Bedroom Climate: Variables Defined\")\n\n// Sleep Switch Handling\nif (type === 'sleep' && payload === 'off') {\n if (coolingActive === 'on') {\n time = 'night'\n } else {\n time = 'day'\n }\n} else if (type === 'sleep' && payload === 'on') {\n time = 'bedtime'\n} else {\n time = msg.time\n}\n\nif (topic === 'mrbedroom-wakeup') {\n setSleep = 'turn_off'\n}\n\n// Day Time\nif (time === 'day') {\n if (type === 'auto') {\n setCool = 'turn_off'\n }\n if (earlyNight === 'off') {\n setFan = \"turn_off\"\n if (ac === 'on') {\n if (danger === 'Extreme') {\n setTemp = nightTemp\n setEco = \"eco\"\n setHvac = \"cool\"\n } else if (hotDay === 'on' || heatWarning === 'on') {\n setTemp = dayTemp\n setEco = \"eco\"\n setHvac = \"cool\"\n } else {\n setTemp = nightTemp\n setEco = \"eco\"\n setHvac = \"off\"\n }\n }\n } else if (earlyNight === 'on') {\n if (ac === 'on') {\n if (danger === 'Extreme') {\n setTemp === bedTemp\n } else {\n setTemp = nightTemp\n }\n if (fanMode === 'Fan') {\n setFan = 'turn_on'\n } else {\n setFan = 'turn_off'\n }\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'fan') {\n setHvac = 'fan_only'\n } else {\n setHvac = 'off'\n }\n if (hotDay === 'on') {\n setEco = 'off'\n } else {\n setEco = 'on'\n }\n }\n }\n// Night Time\n} else if (time === 'night') {\n if (type === 'auto') {\n setCool = 'turn_on'\n }\n if (danger === 'Extreme') {\n setTemp = bedTemp\n } else {\n setTemp = nightTemp\n }\n if (hotDay === 'on' || sleeping === 'on') {\n setEco = 'none'\n } else {\n setEco = 'eco'\n }\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'Fan') {\n setHvac = 'fan_only'\n } else {\n setHvac = 'off'\n }\n if (type === 'sleep' && payload === 'off') {\n setFan = 'turn_off'\n } else if (fanMode === 'Fan') {\n setFan = 'turn_on'\n }\n// Bed Time\n} else if (time === 'bedtime') {\n if (ac === 'on') {\n setTemp = bedTemp\n setEco = 'none'\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'Fan') {\n setHvac = \"fan_only\"\n }\n }\n if (fanMode === 'Fan') {\n setFan = 'turn_on'\n }\n}\nnode.log(\"Master Bedroom Climate: Decision Logic Complete\")\n\n// Define message payloads\n\nlet sendFan = {\n \"payload\": {\n \"domain\": \"fan\",\n \"service\": setFan,\n \"target\": {\n \"entity_id\": [\"fan.master_bedroom_fan\"]\n },\n \"data\": {}\n }\n}\n\nlet sendCool = {\n \"payload\": {\n \"domain\": \"input_boolean\",\n \"service\": setCool,\n \"target\": {\n \"entity_id\": [\"input_boolean.master_bedroom_cooling_on\"]\n },\n \"data\": {}\n }\n}\n\nlet sendSleep = {\n \"payload\": {\n \"domain\": \"input_boolean\",\n \"service\": setSleep,\n \"target\": {\n \"entity_id\": [\"input_boolean.master_bedroom_sleeping\"]\n },\n \"data\": {}\n }\n}\n\nlet notify = {\n \"topic\": topic,\n \"nighttemp\": nightTemp,\n \"acmode\": acMode,\n \"fanmode\": fanMode\n}\n\nlet sendHvac = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_hvac_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"hvac_mode\": setHvac\n }\n }\n}\n\nlet sendTemp = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_temperature\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"temperature\": setTemp\n }\n }\n}\n\nlet sendEco = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_preset_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"preset_mode\": setEco\n }\n }\n}\n\nlet sendAcFan = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_fan_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"fan_mode\": \"Auto\"\n }\n }\n}\nnode.log(\"Master Bedroom Climate: Message Payloads Defined\")\n\n// Log the parameters that were chosen, for debugging purposes\n\nnode.log(\"----- Master Bedroom Climate: Set Parameters -----\")\nnode.log(\"setTemp: \" + setTemp)\nnode.log(\"setEco: \" + setEco)\nnode.log(\"setHvac: \" + setHvac)\nnode.log(\"setFan: \" + setFan)\nnode.log(\"setCool: \" + setCool)\nnode.log(\"setSleep: \" + setSleep)\nnode.log(\"time: \" + time)\nnode.log(\"type: \" + type)\nnode.log(\"topic: \" + topic)\nnode.log(\"----- Master Bedroom Climate: End Parameters -----\")\n\n// If this was an automated trigger, set the cooling context for the bedroom accordingly.\n\nif (type === 'auto' && time != 'bedtime') {\n node.send([null, null, sendCool, null])\n node.log(\"Master Bedroom Climate: Cooling Context Set\")\n}\n\n// Automated responses\nif (type === 'auto' && allowed === 'on' && meltdown === 'off' && vacation === 'off') {\n node.log(\"Master Bedroom Climate: Auto\");\n if (sleeping === 'on' && topic != 'mrbedroom-wakeup') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (sleep mode)\" })\n node.log(\"Master Bedroom Climate: Blocked (sleep mode)\")\n } else {\n if (topic === 'mrbedroom-cooling' && ac === 'on') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Cooling Schedule\" })\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null])\n node.log(\"Master Bedroom Climate: Auto/Cooling\")\n } else if (topic === 'mrbedroom-bedtime') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Bedtime\" })\n node.log(\"Master Bedroom Climate: Auto/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Bedtime/AC\")\n }\n if (fanMode === 'fan') {\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Auto/Bedtime/Fan\")\n }\n } else if (topic === 'mrbedroom-fan' && fanMode === 'Fan') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Fan Schedule\" })\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Auto/Fan\")\n } else if (topic === 'mrbedroom-wakeup') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Wakeup Schedule\" })\n node.log(\"Master Bedroom Climate: Auto/Wakeup\");\n if (sleeping === 'off') {\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/Sleep Off\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/AC On\")\n }\n } else if (sleeping === 'on') {\n node.send([null, null, sendSleep, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/Sleep On\")\n }\n }\n }\n// Manual Responses\n} else if (type === 'manual') {\n node.log(\"Master Bedroom Climate: Manual\")\n if (time === 'night') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Night\" })\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Manual/Night\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Night/AC\")\n }\n } else if (time === 'day') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Day\" })\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Manual/Day\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Day/AC\")\n }\n } else if (time === 'bedtime') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Bedtime\" })\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Manual/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Bedtime/AC\");\n }\n }\n} else if (type === 'sleep') {\n node.log(\"Master Bedroom Climate: Sleep\");\n if (time === 'night') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Wakeup (Hot Day)\" })\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Night\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Night/AC\")\n }\n } else if (time === 'day') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Wakeup\" })\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Day\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Day/AC\")\n }\n } else if (time === 'bedtime') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Sleep\" })\n node.send([null, sendFan, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Bedtime/AC\")\n }\n }\n} else if (meltdown === 'on') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Meltdown Protocol)\" })\n node.log(\"Master Bedroom Climate: Blocked (Meltdown Protocol)\")\n} else if (vacation === 'on') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Vacation Mode)\" })\n node.log(\"Master Bedroom Climate: Blocked (Vacation Mode)\")\n} else {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Automation Disabled)\" })\n node.log(\"Master Bedroom Climate: Blocked (Automation Disabled)\")\n}\n\nnode.log(\"Master Bedroom Climate: Processing Complete\")\n", - "outputs": 4, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 510, - "y": 380, - "wires": [ - [ - "d275a12c1817925e" - ], - [ - "4d9e5c1bade281af" - ], - [ - "330eaf3afee1c405" - ], - [ - "93072f995377775b" - ] - ], - "outputLabels": [ - "A/C", - "Fan", - "Boolean", - "Notify" - ], - "icon": "node-red-contrib-cpu/cpu.png" - }, { "id": "5848c6edf2bd06fe", "type": "inject", @@ -28822,7 +28793,7 @@ "y": 240, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ] }, @@ -28862,7 +28833,7 @@ "y": 300, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ] }, @@ -28902,7 +28873,7 @@ "y": 360, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ] }, @@ -28942,7 +28913,7 @@ "y": 420, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ] }, @@ -28982,7 +28953,7 @@ "y": 480, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ] }, @@ -29022,7 +28993,7 @@ "y": 540, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ] }, @@ -29041,7 +29012,7 @@ "statusVal": "", "statusType": "auto", "x": 670, - "y": 320, + "y": 280, "wires": [] }, { @@ -29059,7 +29030,7 @@ "statusVal": "", "statusType": "auto", "x": 670, - "y": 380, + "y": 340, "wires": [] }, { @@ -29077,7 +29048,7 @@ "statusVal": "", "statusType": "auto", "x": 680, - "y": 440, + "y": 400, "wires": [] }, { @@ -29095,7 +29066,7 @@ "statusVal": "", "statusType": "auto", "x": 670, - "y": 560, + "y": 600, "wires": [] }, { @@ -29198,7 +29169,7 @@ "finalize": "", "libs": [], "x": 690, - "y": 500, + "y": 460, "wires": [ [ "c59db4f3f0112244" @@ -29286,7 +29257,7 @@ "y": 600, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ] }, @@ -29317,7 +29288,7 @@ "y": 660, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ] }, @@ -29366,7 +29337,7 @@ "y": 200, "wires": [ [ - "f5879622a44b7213" + "14181143d23aa423" ] ], "l": false @@ -29502,5 +29473,117 @@ "16d93fd5efd5fec3" ] ] + }, + { + "id": "14181143d23aa423", + "type": "function", + "z": "d49b385d8b582b20", + "g": "c3dc29879117218b", + "name": "Processing", + "func": "node.log(\"Master Bedroom Climate: Processing Started\")\n// pull in the necessary information\n\nconst states = global.get('homeassistant.homeAssistant.states')\nconst allowed = states['input_boolean.master_bedroom_climate_protocol'].state\nconst ac = global.get('mb_aircon_installed', \"diskCon\")\nconst temp = global.get(\"tempStr\")\nconst payload = msg.payload\nconst vacation = states['input_boolean.vacation_mode'].state\nconst highTemp = states['sensor.today_corrected_high_temp'].state\nconst dayTemp = states['input_number.master_bedroom_daytime_temp'].state\nconst nightTemp = states['input_number.master_bedroom_night_temp'].state\nconst bedTemp = states['input_number.master_bedroom_bedtime_temp'].state\nconst showerMode = states['input_boolean.shower_mode'].state\nconst nightVolume = states['input_number.master_bedroom_echo_dot_night_volume'].state\nconst fanMode = states['input_select.scheduled_climate_mode_master_bedroom_fan'].state\nconst acMode = states['input_select.scheduled_climate_mode_master_bedroom_aircon'].state\nconst sleeping = states['input_boolean.toggle_testing'].state\nconst hotDay = states['input_boolean.hot_day'].state\nconst heatWarning = states[\"binary_sensor.heat_warning\"].state\nconst showerCooldown = states[\"timer.shower_mode_cooldown\"].state\nconst earlyNight = states[\"binary_sensor.early_night_mode\"].state\nconst danger = states['binary_sensor.heat_warning'].attributes.danger\nconst meltdown = states['input_boolean.meltdown_protocol'].state\nconst coolingActive = states['input_boolean.master_bedroom_cooling_on'].state\nconst echoDotDND = 'switch.basement_echo_dot_do_not_disturb_switch'\nnode.log(\"Master Bedroom Climate: Constants Set\")\n\n// init variables\n\nlet setTemp = []\nlet setEco = []\nlet setHvac = []\nlet setFan = []\nlet setCool = []\nlet setSleep = []\nlet setDisplay = []\nlet time = []\nlet echoDotService = []\nlet setBriefing = []\nlet setBriefingDelay = []\nlet type = msg.type\nlet topic = msg.topic\nlet isWakeup = context.get(\"isWakeup\")\nnode.log(\"Master Bedroom Climate: Variables Defined\")\n\n// Sleep Switch Handling\nif (type === 'sleep' && payload === 'off') {\n setDisplay = 'turn_on'\n echoDotService = 'turn_off'\n if (coolingActive === 'on') {\n time = 'night'\n } else {\n time = 'day'\n }\n} else if (type === 'sleep' && payload === 'on') {\n setDisplay = 'turn_off'\n echoDotService = 'turn_on'\n time = 'bedtime'\n} else {\n time = msg.time\n}\n\nif (topic === 'mrbedroom-wakeup') {\n setSleep = 'turn_off'\n}\n\n// Setup TTS briefing\nif (topic === 'mrbedroom-wakeup') {\n setBriefing = \"master_bedroom_wakeup_briefing\"\n setBriefingDelay = 60000\n} else if (type === 'sleep' && payload === 'off') {\n setBriefing = \"master_bedroom_wakeup_briefing\"\n setBriefingDelay = 15000\n}\n\n// Day Time\nif (time === 'day') {\n if (type === 'auto') {\n setCool = 'turn_off'\n }\n if (earlyNight === 'off') {\n setFan = \"turn_off\"\n if (ac === 'on') {\n if (danger === 'Extreme') {\n setTemp = nightTemp\n setEco = \"eco\"\n setHvac = \"cool\"\n } else if (hotDay === 'on' || heatWarning === 'on') {\n setTemp = dayTemp\n setEco = \"eco\"\n setHvac = \"cool\"\n } else {\n setTemp = nightTemp\n setEco = \"eco\"\n setHvac = \"off\"\n }\n }\n } else if (earlyNight === 'on') {\n if (ac === 'on') {\n if (danger === 'Extreme') {\n setTemp === bedTemp\n } else {\n setTemp = nightTemp\n }\n if (fanMode === 'Fan') {\n setFan = 'turn_on'\n } else {\n setFan = 'turn_off'\n }\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'fan') {\n setHvac = 'fan_only'\n } else {\n setHvac = 'off'\n }\n if (hotDay === 'on') {\n setEco = 'off'\n } else {\n setEco = 'on'\n }\n }\n }\n// Night Time\n} else if (time === 'night') {\n if (type === 'auto') {\n setCool = 'turn_on'\n }\n if (danger === 'Extreme') {\n setTemp = bedTemp\n } else {\n setTemp = nightTemp\n }\n if (hotDay === 'on' || sleeping === 'on') {\n setEco = 'none'\n } else {\n setEco = 'eco'\n }\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'Fan') {\n setHvac = 'fan_only'\n } else {\n setHvac = 'off'\n }\n if (type === 'sleep' && payload === 'off') {\n setFan = 'turn_off'\n } else if (fanMode === 'Fan') {\n setFan = 'turn_on'\n }\n// Bed Time\n} else if (time === 'bedtime') {\n if (ac === 'on') {\n setTemp = bedTemp\n setEco = 'none'\n if (acMode === 'AC') {\n setHvac = 'cool'\n } else if (acMode === 'Fan') {\n setHvac = \"fan_only\"\n }\n }\n if (fanMode === 'Fan') {\n setFan = 'turn_on'\n }\n}\nnode.log(\"Master Bedroom Climate: Decision Logic Complete\")\n\n// Define message payloads\n\nlet sendFan = {\n \"payload\": {\n \"domain\": \"fan\",\n \"service\": setFan,\n \"target\": {\n \"entity_id\": [\"fan.master_bedroom_fan\"]\n },\n \"data\": {}\n }\n}\n\nlet sendCool = {\n \"payload\": {\n \"domain\": \"input_boolean\",\n \"service\": setCool,\n \"target\": {\n \"entity_id\": [\"input_boolean.master_bedroom_cooling_on\"]\n },\n \"data\": {}\n }\n}\n\nlet sendSleep = {\n \"payload\": {\n \"domain\": \"input_boolean\",\n \"service\": setSleep,\n \"target\": {\n \"entity_id\": [\"input_boolean.master_bedroom_sleeping\"]\n },\n \"data\": {}\n }\n}\n\nlet sendDisplay = {\n \"payload\": {\n \"domain\": \"switch\",\n \"service\": setDisplay,\n \"target\": {\n \"entity_id\": [\"switch.master_bedroom_aircon_display\"]\n },\n \"data\": {}\n }\n}\n\nlet notify = {\n \"topic\": topic,\n \"nighttemp\": nightTemp,\n \"acmode\": acMode,\n \"fanmode\": fanMode\n}\n\nlet sendBriefing = {\n \"payload\": {\n \"domain\": \"script\",\n \"service\": setBriefing\n },\n \"delay\": setBriefingDelay\n}\n\nlet sendHvac = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_hvac_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"hvac_mode\": setHvac\n }\n }\n}\n\nlet sendTemp = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_temperature\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"temperature\": setTemp\n }\n }\n}\n\nlet sendEco = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_preset_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"preset_mode\": setEco\n }\n }\n}\n\nlet sendAcFan = {\n \"payload\": {\n \"domain\": \"climate\",\n \"service\": \"set_fan_mode\",\n \"target\": {\n \"entity_id\": [\"climate.master_bedroom_aircon\"]\n },\n \"data\": {\n \"fan_mode\": \"Auto\"\n }\n }\n}\n\nlet sendEchoDotDND = {\n \"payload\": {\n \"domain\": \"switch\",\n \"service\": echoDotService,\n \"target\": {\n \"entity_id\": [\"switch.basement_echo_dot_do_not_disturb_switch\"]\n },\n \"data\": {}\n }\n}\n\nnode.log(\"Master Bedroom Climate: Message Payloads Defined\")\n\n// Log the parameters that were chosen, for debugging purposes\n\nnode.log(\"----- Master Bedroom Climate: Set Parameters -----\")\nnode.log(\"setTemp: \" + setTemp)\nnode.log(\"setEco: \" + setEco)\nnode.log(\"setHvac: \" + setHvac)\nnode.log(\"setFan: \" + setFan)\nnode.log(\"setCool: \" + setCool)\nnode.log(\"setSleep: \" + setSleep)\nnode.log(\"setDisplay: \" + setDisplay)\nnode.log(\"setBriefing: \" + setBriefing)\nnode.log(\"setBriefingDelay: \" + setBriefingDelay)\nnode.log(\"time: \" + time)\nnode.log(\"type: \" + type)\nnode.log(\"topic: \" + topic)\nnode.log(\"----- Master Bedroom Climate: End Parameters -----\")\n\n// If this was an automated trigger, set the cooling context for the bedroom accordingly.\n\nif (type === 'auto' && time != 'bedtime') {\n node.send([null, null, sendCool, null, null])\n node.log(\"Master Bedroom Climate: Cooling Context Set\")\n}\n\n// Automated responses\nif (type === 'auto' && allowed === 'on' && meltdown === 'off' && vacation === 'off') {\n node.log(\"Master Bedroom Climate: Auto\")\n if (sleeping === 'on' && topic != 'mrbedroom-wakeup') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (sleep mode)\" })\n node.log(\"Master Bedroom Climate: Blocked (sleep mode)\")\n } else {\n if (topic === 'mrbedroom-cooling' && ac === 'on') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Cooling Schedule\" })\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Cooling\")\n } else if (topic === 'mrbedroom-bedtime') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Bedtime\" })\n node.log(\"Master Bedroom Climate: Auto/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Bedtime/AC\")\n }\n if (fanMode === 'fan') {\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Bedtime/Fan\")\n }\n } else if (topic === 'mrbedroom-fan' && fanMode === 'Fan') {\n node.status({ fill: \"green\", shape: \"dot\", text: \"Fan Schedule\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Fan\")\n } else if (topic === 'mrbedroom-wakeup') {\n node.send([null, null, null, null, sendBriefing])\n node.status({ fill: \"green\", shape: \"dot\", text: \"Wakeup Schedule\" })\n node.log(\"Master Bedroom Climate: Auto/Wakeup\")\n if (sleeping === 'off') {\n context.set(\"isWakeup\", false)\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/Sleep Off\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/AC On\")\n }\n } else if (sleeping === 'on') {\n context.set(\"isWakeup\", true)\n node.send([null, null, sendSleep, null, null])\n node.log(\"Master Bedroom Climate: Auto/Wakeup/Sleep On\")\n }\n }\n }\n// Manual Responses\n} else if (type === 'manual') {\n node.log(\"Master Bedroom Climate: Manual\")\n if (time === 'night') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Night\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Night\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Night/AC\")\n }\n } else if (time === 'day') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Day\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Day\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Day/AC\")\n }\n } else if (time === 'bedtime') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Manual Bedtime\" })\n node.send([null, sendFan, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Bedtime\")\n if (ac === 'on') {\n node.send([[sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Manual/Bedtime/AC\")\n }\n }\n context.set(\"isWakeup\", false)\n} else if (type === 'sleep') {\n node.log(\"Master Bedroom Climate: Sleep\")\n if (time === 'night') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Wakeup (Hot Day)\" })\n node.send([null, sendFan, sendEchoDotDND, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Night\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Night/AC\")\n }\n } else if (time === 'day') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Wakeup\" })\n node.send([null, sendFan, sendEchoDotDND, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Day\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Day/AC\")\n }\n if (isWakeup === false) {\n node.send([null, null, null, null, sendBriefing])\n }\n } else if (time === 'bedtime') {\n node.status({ fill: \"blue\", shape: \"dot\", text: \"Sleep\" })\n node.send([null, sendFan, sendEchoDotDND, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Bedtime\")\n if (ac === 'on') {\n node.send([[sendDisplay, sendHvac, sendTemp, sendEco, sendAcFan], null, null, null, null])\n node.log(\"Master Bedroom Climate: Sleep/Bedtime/AC\")\n }\n }\n context.set(\"isWakeup\", false)\n} else if (meltdown === 'on') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Meltdown Protocol)\" })\n node.log(\"Master Bedroom Climate: Blocked (Meltdown Protocol)\")\n} else if (vacation === 'on') {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Vacation Mode)\" })\n node.log(\"Master Bedroom Climate: Blocked (Vacation Mode)\")\n} else {\n node.status({ fill: \"red\", shape: \"ring\", text: \"Blocked (Automation Disabled)\" })\n node.log(\"Master Bedroom Climate: Blocked (Automation Disabled)\")\n}\n\nnode.log(\"Master Bedroom Climate: Processing Complete\")\n", + "outputs": 5, + "timeout": "", + "noerr": 0, + "initialize": "context.set(\"isWakeup\", false)", + "finalize": "", + "libs": [], + "x": 490, + "y": 380, + "wires": [ + [ + "d275a12c1817925e" + ], + [ + "4d9e5c1bade281af" + ], + [ + "330eaf3afee1c405" + ], + [ + "93072f995377775b" + ], + [ + "f9e1aec6c25f6480" + ] + ], + "outputLabels": [ + "A/C", + "Fan", + "Boolean", + "Notify", + "Briefing" + ], + "icon": "node-red-contrib-cpu/cpu.png" + }, + { + "id": "f9e1aec6c25f6480", + "type": "delay", + "z": "d49b385d8b582b20", + "g": "c3dc29879117218b", + "name": "Delay", + "pauseType": "delayv", + "timeout": "5", + "timeoutUnits": "seconds", + "rate": "1", + "nbRateUnits": "1", + "rateUnits": "second", + "randomFirst": "1", + "randomLast": "5", + "randomUnits": "seconds", + "drop": false, + "allowrate": false, + "outputs": 1, + "x": 575, + "y": 520, + "wires": [ + [ + "0693239363c59c3e" + ] + ], + "l": false + }, + { + "id": "0693239363c59c3e", + "type": "debug", + "z": "d49b385d8b582b20", + "g": "c3dc29879117218b", + "name": "TTS", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 670, + "y": 520, + "wires": [] + }, + { + "id": "44b7eabdec8197a3", + "type": "inject", + "z": "d49b385d8b582b20", + "g": "c3dc29879117218b", + "name": "reset", + "props": [ + { + "p": "reset", + "v": "", + "vt": "date" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "x": 470, + "y": 580, + "wires": [ + [ + "f9e1aec6c25f6480" + ] + ] } ] \ No newline at end of file