Last active
March 30, 2026 23:11
-
-
Save connorjfarrell/e91a91242236eb64ff338ba84a467223 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| blueprint: | |
| name: Fridge / Freezer Left Open Escalation | |
| description: > | |
| Escalating notifications for a fridge/freezer door left open. | |
| Stage 1 after X minutes, stage 2 after Y minutes, and stage 3 after Z minutes, | |
| with optional flashing lights, additional lights, TTS, and an all-clear notification. | |
| Notes: | |
| - This blueprint sends push notifications through notify.family_phones. | |
| - This blueprint uses tts.google_translate_say for TTS. | |
| - For best results, keep stage1 < stage2 < stage3. | |
| - On close after stage 3, it turns off the flashing light and the additional stage 3 lights. | |
| It does not restore prior light state. | |
| domain: automation | |
| input: | |
| door_sensor: | |
| name: Door sensor | |
| selector: | |
| entity: | |
| domain: binary_sensor | |
| appliance_name: | |
| name: Appliance friendly name | |
| default: Fridge/Freezer | |
| selector: | |
| text: | |
| stage1_minutes: | |
| name: Stage 1 delay from open (minutes) | |
| default: 2 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 120 | |
| mode: box | |
| stage2_minutes: | |
| name: Stage 2 delay from open (minutes) | |
| default: 5 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 240 | |
| mode: box | |
| stage3_minutes: | |
| name: Stage 3 delay from open (minutes) | |
| default: 10 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 480 | |
| mode: box | |
| stage1_critical: | |
| name: Stage 1 critical push | |
| default: false | |
| selector: | |
| boolean: | |
| stage2_critical: | |
| name: Stage 2 critical push | |
| default: true | |
| selector: | |
| boolean: | |
| stage3_critical: | |
| name: Stage 3 critical push | |
| default: true | |
| selector: | |
| boolean: | |
| send_all_clear: | |
| name: Send all-clear notification | |
| default: true | |
| selector: | |
| boolean: | |
| enable_flash_lights: | |
| name: Enable flashing lights at stage 3 | |
| default: true | |
| selector: | |
| boolean: | |
| flash_light: | |
| name: Flashing light target | |
| default: | |
| entity_id: light.living_room_lamps | |
| selector: | |
| target: | |
| entity: | |
| domain: light | |
| flash_rgb: | |
| name: Flash RGB color | |
| default: | |
| - 255 | |
| - 0 | |
| - 0 | |
| selector: | |
| color_rgb: | |
| flash_brightness_pct: | |
| name: Flash brightness percent | |
| default: 100 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 100 | |
| mode: slider | |
| flash_on_seconds: | |
| name: Flash ON time (seconds) | |
| default: 1 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 10 | |
| mode: box | |
| flash_off_seconds: | |
| name: Flash OFF time (seconds) | |
| default: 1 | |
| selector: | |
| number: | |
| min: 1 | |
| max: 10 | |
| mode: box | |
| stage3_turn_on_lights: | |
| name: Additional lights to turn on at stage 3 | |
| default: {} | |
| selector: | |
| target: | |
| entity: | |
| domain: light | |
| enable_tts: | |
| name: Enable TTS at stage 3 | |
| default: false | |
| selector: | |
| boolean: | |
| tts_media_player: | |
| name: TTS media player | |
| default: media_player.master_bedroom_homepod | |
| selector: | |
| entity: | |
| domain: media_player | |
| tts_volume: | |
| name: Temporary TTS volume | |
| default: 1.0 | |
| selector: | |
| number: | |
| min: 0 | |
| max: 1 | |
| step: 0.05 | |
| mode: slider | |
| mode: parallel | |
| max: 20 | |
| trigger: | |
| - platform: state | |
| entity_id: !input door_sensor | |
| from: "off" | |
| to: "on" | |
| variables: | |
| door_sensor: !input door_sensor | |
| appliance_name: !input appliance_name | |
| stage1_minutes: !input stage1_minutes | |
| stage2_minutes: !input stage2_minutes | |
| stage3_minutes: !input stage3_minutes | |
| stage1_critical: !input stage1_critical | |
| stage2_critical: !input stage2_critical | |
| stage3_critical: !input stage3_critical | |
| send_all_clear: !input send_all_clear | |
| enable_flash_lights: !input enable_flash_lights | |
| enable_tts: !input enable_tts | |
| tts_media_player: !input tts_media_player | |
| tts_volume: !input tts_volume | |
| opened_at: "{{ now() }}" | |
| stage1_title: "{{ appliance_name }} Left Open" | |
| stage1_message: "The {{ appliance_name | lower }} has been open." | |
| stage2_title: "{{ appliance_name }} Left Open" | |
| stage2_message: "The {{ appliance_name | lower }} is still open after {{ stage2_minutes }} minutes!" | |
| stage3_title: "{{ appliance_name }} Left Open" | |
| stage3_message: "The {{ appliance_name | lower }} is still open after {{ stage3_minutes }} minutes!" | |
| all_clear_title: "{{ appliance_name }} Closed" | |
| action: | |
| - wait_template: "{{ is_state(door_sensor, 'off') }}" | |
| timeout: | |
| minutes: !input stage1_minutes | |
| continue_on_timeout: true | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ wait.completed }}" | |
| sequence: | |
| - stop: Closed before stage 1 | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ stage1_critical }}" | |
| sequence: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ stage1_title }}" | |
| message: "{{ stage1_message }}" | |
| data: | |
| push: | |
| sound: | |
| name: default | |
| critical: 1 | |
| volume: 1.0 | |
| default: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ stage1_title }}" | |
| message: "{{ stage1_message }}" | |
| data: | |
| push: | |
| sound: | |
| name: default | |
| critical: 0 | |
| volume: 1.0 | |
| - wait_template: "{{ is_state(door_sensor, 'off') }}" | |
| timeout: | |
| seconds: "{{ ((stage2_minutes - stage1_minutes) * 60) | int }}" | |
| continue_on_timeout: true | |
| - variables: | |
| duration_text: >- | |
| {% set s = (as_timestamp(now()) - as_timestamp(opened_at)) | int(0) %} | |
| {% set m = s // 60 %} | |
| {% set r = s % 60 %} | |
| {{ m }} minute{{ 's' if m != 1 else '' }}{% if r > 0 %} and {{ r }} second{{ 's' if r != 1 else '' }}{% endif %} | |
| all_clear_message: "{{ appliance_name }} was closed after {{ duration_text }}." | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ wait.completed }}" | |
| sequence: | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ send_all_clear }}" | |
| sequence: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ all_clear_title }}" | |
| message: "{{ all_clear_message }}" | |
| - stop: Closed before stage 2 | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ stage2_critical }}" | |
| sequence: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ stage2_title }}" | |
| message: "{{ stage2_message }}" | |
| data: | |
| push: | |
| sound: | |
| name: default | |
| critical: 1 | |
| volume: 1.0 | |
| default: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ stage2_title }}" | |
| message: "{{ stage2_message }}" | |
| data: | |
| push: | |
| sound: | |
| name: default | |
| critical: 0 | |
| volume: 1.0 | |
| - wait_template: "{{ is_state(door_sensor, 'off') }}" | |
| timeout: | |
| seconds: "{{ ((stage3_minutes - stage2_minutes) * 60) | int }}" | |
| continue_on_timeout: true | |
| - variables: | |
| duration_text: >- | |
| {% set s = (as_timestamp(now()) - as_timestamp(opened_at)) | int(0) %} | |
| {% set m = s // 60 %} | |
| {% set r = s % 60 %} | |
| {{ m }} minute{{ 's' if m != 1 else '' }}{% if r > 0 %} and {{ r }} second{{ 's' if r != 1 else '' }}{% endif %} | |
| all_clear_message: "{{ appliance_name }} was closed after {{ duration_text }}." | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ wait.completed }}" | |
| sequence: | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ send_all_clear }}" | |
| sequence: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ all_clear_title }}" | |
| message: "{{ all_clear_message }}" | |
| - stop: Closed before stage 3 | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ stage3_critical }}" | |
| sequence: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ stage3_title }}" | |
| message: "{{ stage3_message }}" | |
| data: | |
| push: | |
| sound: | |
| name: default | |
| critical: 1 | |
| volume: 1.0 | |
| default: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ stage3_title }}" | |
| message: "{{ stage3_message }}" | |
| data: | |
| push: | |
| sound: | |
| name: default | |
| critical: 0 | |
| volume: 1.0 | |
| - action: light.turn_on | |
| target: !input stage3_turn_on_lights | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ enable_tts }}" | |
| sequence: | |
| - variables: | |
| old_volume: "{{ state_attr(tts_media_player, 'volume_level') | float(0.35) }}" | |
| - action: media_player.volume_set | |
| target: | |
| entity_id: !input tts_media_player | |
| data: | |
| volume_level: !input tts_volume | |
| - action: tts.google_translate_say | |
| data: | |
| cache: false | |
| entity_id: !input tts_media_player | |
| message: "{{ appliance_name }} has been left open for {{ stage3_minutes }} minutes." | |
| - parallel: | |
| - sequence: | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ enable_flash_lights }}" | |
| sequence: | |
| - repeat: | |
| while: | |
| - condition: state | |
| entity_id: !input door_sensor | |
| state: "on" | |
| sequence: | |
| - action: light.turn_on | |
| target: !input flash_light | |
| data: | |
| rgb_color: !input flash_rgb | |
| brightness_pct: !input flash_brightness_pct | |
| - delay: | |
| seconds: !input flash_on_seconds | |
| - action: light.turn_off | |
| target: !input flash_light | |
| - delay: | |
| seconds: !input flash_off_seconds | |
| - sequence: | |
| - wait_template: "{{ is_state(door_sensor, 'off') }}" | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ enable_tts }}" | |
| sequence: | |
| - delay: "00:00:08" | |
| - action: media_player.volume_set | |
| target: | |
| entity_id: !input tts_media_player | |
| data: | |
| volume_level: "{{ old_volume | default(0.35) }}" | |
| - action: light.turn_off | |
| target: !input flash_light | |
| - action: light.turn_off | |
| target: !input stage3_turn_on_lights | |
| - variables: | |
| duration_text: >- | |
| {% set s = (as_timestamp(now()) - as_timestamp(opened_at)) | int(0) %} | |
| {% set m = s // 60 %} | |
| {% set r = s % 60 %} | |
| {{ m }} minute{{ 's' if m != 1 else '' }}{% if r > 0 %} and {{ r }} second{{ 's' if r != 1 else '' }}{% endif %} | |
| all_clear_message: "{{ appliance_name }} was closed after {{ duration_text }}." | |
| - choose: | |
| - conditions: | |
| - condition: template | |
| value_template: "{{ send_all_clear }}" | |
| sequence: | |
| - action: notify.family_phones | |
| data: | |
| title: "{{ all_clear_title }}" | |
| message: "{{ all_clear_message }}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment