refactor: harden alerts and long-running waits

pull/1898/head
Carlo Costanzo 2 months ago
parent 993165a3ed
commit f54995c972

@ -3,44 +3,63 @@
# For more info visit https://www.vcloudinfo.com/click-here
# Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig
# -------------------------------------------------------------------
# High Wind Alerts - Severe wind warnings (push + Activity feed)
# High Wind Alerts - Tiered wind and open-garage safety warnings.
# Related Issue: 1550
# Logs to Activity feed while keeping existing notifications and actions.
# Coalesces 30/40/60 mph crossings so the highest current tier owns the alert.
# -------------------------------------------------------------------
######################################################################
- alias: 'High Wind Speed Notification'
id: 5cc158a5-038a-4078-a9fb-c9f9cf9ecd49
mode: single
mode: restart
trigger:
- platform: numeric_state
id: wind_advisory
entity_id: sensor.pirateweather_wind_speed
above: 30
- platform: numeric_state
id: wind_severe
entity_id: sensor.pirateweather_wind_speed
above: 40
- platform: numeric_state
id: wind_emergency
entity_id: sensor.pirateweather_wind_speed
above: 60
action:
- delay: "00:00:02"
- variables:
wind_speed: "{{ states('sensor.pirateweather_wind_speed') | float(0) }}"
wind_severity: >-
{% if wind_speed > 60 %}emergency
{% elif wind_speed > 40 %}severe
{% else %}advisory
{% endif %}
garage_warning: >-
{% set ns = namespace(doors=[]) %}
{% if is_state('cover.large_garage_door', 'open') %}
{% set ns.doors = ns.doors + ['large garage door'] %}
{% endif %}
{% if is_state('cover.small_garage_door', 'open') %}
{% set ns.doors = ns.doors + ['small garage door'] %}
{% endif %}
{{ (' Close the ' ~ ns.doors | join(' and ') ~ '.') if ns.doors | count > 0 else '' }}
wind_message: >-
{% if wind_severity == 'emergency' %}
Hurricane-force winds are detected at {{ wind_speed | round }} mph. Stay indoors.
{% elif wind_severity == 'severe' %}
Severe winds are detected at {{ wind_speed | round }} mph. Find shelter and avoid going outside.
{% else %}
Heavy winds are detected at {{ wind_speed | round }} mph. Be careful outdoors.
{% endif %}{{ garage_warning }}
- service: script.send_to_logbook
data:
topic: "WEATHER"
message: >-
Wind speed is {{ states('sensor.pirateweather_wind_speed') | round }} mph (thresholds: 30/40/60).
message: "{{ wind_message }}"
- service: script.notify_engine
data:
title: 'VERY HIGH WINDS:'
value1: >-
{% set windspeed = states.sensor.pirateweather_wind_speed.state | round %}
{% if ( windspeed > 31 ) and ( windspeed <= 45 ) %}
HEAVY WINDS!!! Current Wind Speed is : {{windspeed}} mph! Be VERY careful outdoors!
{% elif ( windspeed > 45 ) and ( windspeed <= 60 ) %}
Warning! Wind speed is {{windspeed}} MPH. FIND SHELTER IMMEDIATELY!
{% elif ( windspeed > 60 ) %}
HURRICANE WINDS. FIND SHELTER, AND STAY INDOORS!
{% endif %}
title: "{{ wind_severity | upper }} WIND ALERT"
value1: "{{ wind_message }}"
who: 'family'
group: 'Alert'
@ -49,19 +68,14 @@
- service: script.speech_engine
data:
value1: >
{% set windspeed = states.sensor.pirateweather_wind_speed.state | round %}
{% if ( windspeed > 31 ) and ( windspeed <= 40 ) %}
HEAVY WINDS!!! Current Wind Speed is : {{windspeed}} mph! Be VERY careful outdoors!
{% elif ( windspeed > 40 ) and ( windspeed <= 60 ) %}
Warning! Wind speed is {{windspeed}} MPH. FIND SHELTER IMMEDIATELY!
{% elif ( windspeed > 60 ) %}
HURRICANE WINDS. FIND SHELTER, AND STAY INDOORS!
{% endif %}
value1: "{{ wind_message }}"
call_window_check: 1
call_garage_check: 1
- service: script.emergency
- choose:
- conditions: "{{ wind_severity == 'emergency' }}"
sequence:
- service: script.emergency
- delay:
hours: 2

@ -49,7 +49,7 @@
add_entities: >-
{{ trigger.to_state.entity_id }}
- wait_template: "{{ states.binary_sensor.mcu1_gpio12.state == 'on' }}"
- wait_template: "{{ is_state('binary_sensor.mcu1_gpio12', 'on') }}"
timeout: '00:05:00'
# - wait_template: "{{ states.binary_sensor.kitchen_door.state == 'on' }}"

@ -41,6 +41,8 @@
volume_level: 0.22
- wait_template: "{{ not is_state('media_player.livingroomCC', 'playing') }}"
timeout: "00:02:00"
continue_on_timeout: false
- service: media_player.play_media
data:

@ -32,7 +32,7 @@
- service: media_player.play_media
data:
entity_id: >
{% if states.group.bed.state == 'off' %}
{% if is_state('group.bed', 'off') %}
media_player.livingroomCC
{% else %}
media_player.bedroom

@ -36,7 +36,9 @@
- switch.office_lamp_switch
- wait_template: >-
{{ states.sun.sun.state == 'above_horizon' }}
{{ is_state('sun.sun', 'above_horizon') }}
timeout: "04:00:00"
continue_on_timeout: false
- service: homeassistant.turn_on
entity_id:
- switch.alarm_panel_1_motion_detection

@ -9,6 +9,8 @@
######################################################################
- alias: 'Shut down AMP in Living room'
id: 3b41321c-8242-4cf5-9a93-b2b7aeeb8ea0
mode: single
max_exceeded: silent
trigger:
- platform: time
at: '22:00:00'
@ -16,10 +18,16 @@
action:
- wait_template: >-
{{ not is_state('input_boolean.guest_mode', 'on') or is_state('group.bed', 'on') }}
timeout: "08:00:00"
continue_on_timeout: false
- wait_template: >-
{{ not is_state('media_player.livingroomCC', 'playing') }}
timeout: "02:00:00"
continue_on_timeout: true
- wait_template: >-
{{ not is_state('media_player.everywhere', 'playing') }}
timeout: "02:00:00"
continue_on_timeout: true
- service: script.speech_engine
data:
@ -29,5 +37,7 @@
- wait_template: >-
{{ not is_state('media_player.livingroomCC', 'playing') }}
timeout: "00:10:00"
continue_on_timeout: true
- service: switch.turn_off
entity_id: switch.lr_amp

@ -32,7 +32,9 @@
entity_id: all
- wait_template: >-
{{ states.sun.sun.state == 'above_horizon' }}
{{ is_state('sun.sun', 'above_horizon') }}
timeout: "04:00:00"
continue_on_timeout: false
- service: homeassistant.turn_off
entity_id:
- group.master_bathroom_accents

@ -60,7 +60,7 @@
- light.outdoor_bathroom
data:
brightness: >
{% if states.group.family.state == 'home' -%}
{% if is_state('group.family', 'home') -%}
10
{% elif is_state('input_boolean.vacation_mode', 'on') and is_state('input_boolean.house_sitter_present', 'off') -%}
35
@ -74,7 +74,9 @@
state: 'off'
sequence:
- wait_template: >-
{{ states.group.family.state == 'home' }}
{{ is_state('group.family', 'home') }}
timeout: "06:00:00"
continue_on_timeout: false
- service: homeassistant.turn_on
entity_id:
- group.master_bathroom_accents
@ -201,4 +203,3 @@
entity_id:
- light.living_room_accents
- light.ikea_1

@ -38,7 +38,7 @@
- service: >
{% set hour=states("sensor.time").split(':')[0] | int %}
{% if hour >= 5 and hour <= 9 and states.group.bed.state == 'on'%}
{% if hour >= 5 and hour <= 9 and is_state('group.bed', 'on') %}
switch.turn_off
{% else %}
switch.turn_on
@ -48,6 +48,9 @@
- switch.back_landscaping
- switch.front_door_outlet
- switch.foyer_outlet
- wait_template: "{{ is_state('group.entry_points', 'off') }}"
- wait_template: "{{ is_state('group.garage_doors', 'closed') }}"
- wait_template: >-
{{ is_state('group.entry_points', 'off')
and is_state('group.garage_doors', 'closed') }}
timeout: "04:00:00"
continue_on_timeout: false
- service: script.monthly_color_scene

@ -41,8 +41,14 @@
- service: switch.turn_on
entity_id: switch.master_bathroom_accent_1
- wait_template: >-
{{ not is_state('binary_sensor.sleepnumber_carlo_stacey_is_in_bed', 'off') or is_state('person.stacey', 'not_home')}}
- wait_template: >-
{{ not is_state('binary_sensor.sleepnumber_carlo_carlo_is_in_bed', 'off') or is_state('person.carlo', 'not_home') }}
{{
(not is_state('binary_sensor.sleepnumber_carlo_stacey_is_in_bed', 'off')
or is_state('person.stacey', 'not_home'))
and
(not is_state('binary_sensor.sleepnumber_carlo_carlo_is_in_bed', 'off')
or is_state('person.carlo', 'not_home'))
}}
timeout: "12:00:00"
continue_on_timeout: false
- service: switch.turn_off
entity_id: group.master_bathroom_accents

@ -264,53 +264,6 @@ automation:
topic: "garadget/GLarge/command"
payload: "get-status"
###################################
## Garadget Wind Door Checks - [Garadget](https://amzn.to/2jQLpVQ)
###################################
- alias: 'Wind Speed Garage Door Check'
id: 2819207a-1716-4552-be34-a8e0f7af004e
trigger:
- platform: numeric_state
entity_id: sensor.pirateweather_wind_speed
above: 30
condition:
- condition: or
conditions:
- condition: state
entity_id: cover.large_garage_door
state: 'open'
- condition: state
entity_id: cover.small_garage_door
state: 'open'
action:
- service: input_boolean.turn_on
entity_id: input_boolean.alert_mode
- service: script.notify_engine
data:
title: 'Check/Close Garage Doors - High Speed Wind Alert:'
value1: "Small: {{ states('cover.small_garage_door')}}"
value2: "Large: {{ states('cover.large_garage_door')}}"
group: 'information'
who: 'parents'
- service: script.speech_engine
data:
value1: >
"The wind speed is {{ states('sensor.pirateweather_wind_speed')|round}} miles per hour. For safety, please close the garage doors.
{% if is_state('cover.large_garage_door', 'open') -%}
Large Garage Door: open
{% endif -%}
{% if is_state('cover.small_garage_door', 'open') -%}
{% if is_state('cover.large_garage_door', 'open') -%}and
{%- endif %} Small Garage Door: open.
{% endif %}"
##############################################################################
- alias: Is the Garage door Open at night - Checks every 30 minutes or 5 minutes after we drive away.
id: 4eb3e83e-4484-4102-a4ca-6bacd5b3cbdd

@ -54,7 +54,9 @@ automation:
entity_id: switch.back_landscaping
- wait_template: >-
{{ states.group.bed.state == 'on' }}
{{ is_state('group.bed', 'on') }}
timeout: "08:00:00"
continue_on_timeout: false
- delay: '0{{ range(0,2) | random | int }}:{{ range(0,5) | random | int }}{{ range(0,9) | random | int }}:00'

@ -8,7 +8,10 @@
# Keeps push alerts but also logs to Activity feed.
# -------------------------------------------------------------------
# Guide: https://www.vcloudinfo.com/2020/08/adding-a-lightning-sensor-to-home-assistant.html | Existing Issue #392
# Notes: Lightning Notification intentionally holds a 60-minute cooldown; duplicate triggers are silenced.
# Notes: Lightning Notification owns lightning safety speech and intentionally
# holds a 60-minute cooldown; duplicate triggers are silenced.
# Notes: Wait briefly for numeric distance data, then fall back to "nearby"
# rather than aborting when the distance sensor is unavailable.
######################################################################
input_boolean:
snooze_lightning:
@ -49,15 +52,28 @@ automation:
state: 'off'
action:
- wait_template: >-
{{ is_number(states('sensor.blitzortung_lightning_distance')) }}
timeout: "00:00:05"
continue_on_timeout: true
- variables:
lightning_location: >-
{% set distance_km = states('sensor.blitzortung_lightning_distance') | float(none) %}
{% if distance_km is not none %}
within {{ (distance_km / 1.609344) | round(1) }} miles of our home
{% else %}
nearby
{% endif %}
- service: script.send_to_logbook
data:
topic: "WEATHER"
message: >-
Lightning detected within {{ (states('sensor.blitzortung_lightning_distance') | int / 1.609) | round(1, 'floor') }} miles.
message: "Lightning detected {{ lightning_location }}."
- service: script.notify_engine_two_button
data:
title: 'Lightning Warning!'
value1: "Lightning has been detected within {{(states('sensor.blitzortung_lightning_distance') | int / 1.609) | round (1, 'floor')}} Miles of our home. Be careful if outdoors."
value1: "Lightning has been detected {{ lightning_location }}. Be careful if outdoors."
title1: 'Snooze Alerts until tomorrow'
action1: 'SNOOZE_LIGHTNING'
icon1: 'sfsymbols:arrow.up.circle'
@ -66,7 +82,7 @@ automation:
- service: script.speech_engine
data:
value1: "Lightning has been detected within {{(states('sensor.blitzortung_lightning_distance') | int / 1.609) | round (1, 'floor')}} Miles of our home. Please make sure everyone is inside the house."
value1: "Lightning has been detected {{ lightning_location }}. Please make sure everyone is inside the house."
call_window_check: 1
call_garage_check: 1

@ -9,7 +9,6 @@
# Logs hot-water availability alerts to Activity feed; keeps announcements.
# -------------------------------------------------------------------
# Docs: https://www.home-assistant.io/integrations/econet/ | Existing notes: Issue #892
# Temporary DigiCert G1 CA workaround lives in configuration.yaml/additional_ca.
# Powerwall outage control for Rheem WH lives in config/packages/powerwall.yaml
######################################################################
@ -19,18 +18,23 @@
automation:
- alias: "Rheem Water Heater Health Monitoring"
id: rheem_water_heater_health_monitoring
mode: single
max_exceeded: silent
trigger:
- platform: numeric_state
id: compressor_health
entity_id: sensor.rheem_wh_compressor_health
below: 90 # Adjust threshold as needed
- platform: numeric_state
id: tank_health
entity_id: sensor.rheem_wh_tank_health
below: 90 # Adjust threshold as needed
action:
- choose:
- conditions:
- condition: trigger
id: sensor.rheem_wh_compressor_health
id: compressor_health
sequence:
- service: script.notify_engine
data:
@ -40,7 +44,7 @@ automation:
group: 'information'
- conditions:
- condition: trigger
id: sensor.rheem_wh_tank_health
id: tank_health
sequence:
- service: script.notify_engine
data:
@ -50,6 +54,9 @@ automation:
group: 'information'
- alias: "Rheem Water Heater Hot Water Availability Alert"
id: rheem_water_heater_hot_water_availability_alert
mode: single
max_exceeded: silent
trigger:
- platform: numeric_state
entity_id: sensor.rheem_wh_available_hot_water
@ -61,7 +68,7 @@ automation:
message: "Hot water availability is below 30%."
- service: script.speech_engine
data:
value1: "Please be aware that the hot water has dropped below 30% availability. Gallons used today: {{sensor.phyn_daily_water_usage}}"
value1: "Please be aware that the hot water has dropped below 30% availability. Gallons used today: {{ states('sensor.phyn_daily_water_usage') }}"
- service: notify.alexa_media_master_bathroom
data:
@ -77,9 +84,10 @@ automation:
- wait_template: "{{ states('sensor.rheem_wh_available_hot_water')|float > 50 }}"
timeout: '01:00:00' # Adjust timeout as needed
continue_on_timeout: false
- service: script.speech_engine
data:
value1: "The available hot water is now above 50%. Normal showering can resume. Gallons used today: {{sensor.phyn_daily_water_usage}}"
value1: "The available hot water is now above 50%. Normal showering can resume. Gallons used today: {{ states('sensor.phyn_daily_water_usage') }}"
#-------------------------------------------
# Available Rheem entities snapshot (for reference)

@ -34,64 +34,85 @@
notify_engine:
alias: Notify Engine
mode: parallel
max: 20
sequence:
- condition: or
conditions:
- condition: state
entity_id: input_boolean.text_notifications
state: 'on'
- service: >
{% if who == 'stacey' %}
- condition: state
entity_id: input_boolean.text_notifications
state: 'on'
- variables:
notify_service: >-
{% if who | default('family', true) == 'stacey' %}
notify.mobile_app_stacey_iphone11
{% elif who == 'carlo' %}
{% elif who | default('family', true) == 'carlo' %}
notify.mobile_app_carlo_maxpro
{% elif who == 'parents' %}
{% elif who | default('family', true) == 'parents' %}
notify.ios_parents
{% elif who == 'family' %}
notify.ios_family
{% else %}
notify.ios_family
{% endif %}
data:
title: "{{ title }}"
message: "{{ ' '.join([value1|default('', true), value2|default('', true), value3|default('', true)]) | trim }}"
data:
group: "{{ group|default('information') }}"
interuption_level: "{{ level|default('active') }}"
entity_id: "{{ camera_entity|default('', true) }}"
notify_message: >-
{{ ' '.join([
value1 | default('', true),
value2 | default('', true),
value3 | default('', true)
]) | trim }}
has_actions: >-
{{ action1 | default('', true) | length > 0
or action2 | default('', true) | length > 0 }}
- choose:
- conditions: "{{ has_actions }}"
sequence:
- service: "{{ notify_service }}"
data:
title: "{{ title | default('', true) }}"
message: "{{ notify_message }}"
data:
actions:
- title: "{{ title1 | default('', true) }}"
action: "{{ action1 | default('', true) }}"
icon: "{{ icon1 | default('sfsymbols:house.circle', true) }}"
destructive: "{{ destructive1 | default(false, true) }}"
- title: "{{ title2 | default('', true) }}"
action: "{{ action2 | default('', true) }}"
icon: "{{ icon2 | default('sfsymbols:house.circle', true) }}"
destructive: "{{ destructive2 | default(false, true) }}"
group: "{{ group | default('information', true) }}"
entity_id: "{{ camera_entity | default('', true) }}"
push:
interruption-level: "{{ level | default('active', true) }}"
default:
- service: "{{ notify_service }}"
data:
title: "{{ title | default('', true) }}"
message: "{{ notify_message }}"
data:
group: "{{ group | default('information', true) }}"
entity_id: "{{ camera_entity | default('', true) }}"
push:
interruption-level: "{{ level | default('active', true) }}"
notify_engine_two_button:
alias: Notify Engine Two Button
mode: parallel
max: 20
sequence:
- condition: or
conditions:
- condition: state
entity_id: input_boolean.text_notifications
state: 'on'
- service: >
{% if who == 'stacey' %}
notify.mobile_app_stacey_iphone11
{% elif who == 'carlo' %}
notify.mobile_app_carlo_maxpro
{% elif who == 'parents' %}
notify.ios_parents
{% elif who == 'family' %}
notify.ios_family
{% else %}
notify.ios_family
{% endif %}
- service: script.notify_engine
data:
message: "{{ ' '.join([value1|default('', true), value2|default('', true), value3|default('', true)]) | trim }}"
title: "{{ title|default('', true) }}"
data:
actions:
- title: "{{ title1|default('', true) }}"
action: "{{ action1|default('', true) }}"
icon: "{{ icon1|default ('sfsymbols:house.circle', true) }}"
destructive: "{{ destructive1|default('false', true) }}"
- title: "{{ title2|default('', true) }}"
action: "{{ action2|default('', true) }}"
icon: "{{ icon2|default ('sfsymbols:house.circle', true) }}"
destructive: "{{ destructive2|default('false', true) }}"
group: "{{ group|default('information', true) }}"
title: "{{ title | default('', true) }}"
value1: "{{ value1 | default('', true) }}"
value2: "{{ value2 | default('', true) }}"
value3: "{{ value3 | default('', true) }}"
who: "{{ who | default('family', true) }}"
group: "{{ group | default('information', true) }}"
level: "{{ level | default('active', true) }}"
camera_entity: "{{ camera_entity | default('', true) }}"
title1: "{{ title1 | default('', true) }}"
action1: "{{ action1 | default('', true) }}"
icon1: "{{ icon1 | default('sfsymbols:house.circle', true) }}"
destructive1: "{{ destructive1 | default(false, true) }}"
title2: "{{ title2 | default('', true) }}"
action2: "{{ action2 | default('', true) }}"
icon2: "{{ icon2 | default('sfsymbols:house.circle', true) }}"
destructive2: "{{ destructive2 | default(false, true) }}"

Loading…
Cancel
Save

Powered by TurnKey Linux.