diff --git a/config/automation/Speech/High_Wind_Speed_Check.yaml b/config/automation/Speech/High_Wind_Speed_Check.yaml index a00a7ed3..d2de2036 100755 --- a/config/automation/Speech/High_Wind_Speed_Check.yaml +++ b/config/automation/Speech/High_Wind_Speed_Check.yaml @@ -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 diff --git a/config/automation/Speech/announcements.yaml b/config/automation/Speech/announcements.yaml index 504f27c9..9fe5cd09 100755 --- a/config/automation/Speech/announcements.yaml +++ b/config/automation/Speech/announcements.yaml @@ -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' }}" diff --git a/config/automation/System/CucKoo_Clock.yaml b/config/automation/System/CucKoo_Clock.yaml index 0fd9bdd2..e3644f28 100755 --- a/config/automation/System/CucKoo_Clock.yaml +++ b/config/automation/System/CucKoo_Clock.yaml @@ -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: diff --git a/config/automation/System/door_chime.yaml b/config/automation/System/door_chime.yaml index 2f255f80..c770dfa2 100755 --- a/config/automation/System/door_chime.yaml +++ b/config/automation/System/door_chime.yaml @@ -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 diff --git a/config/automation/Timed_Triggers/0830.yaml b/config/automation/Timed_Triggers/0830.yaml index 5d996c48..d2d61f90 100755 --- a/config/automation/Timed_Triggers/0830.yaml +++ b/config/automation/Timed_Triggers/0830.yaml @@ -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 diff --git a/config/automation/Timed_Triggers/2200.yaml b/config/automation/Timed_Triggers/2200.yaml index 29fa2006..b26d8600 100755 --- a/config/automation/Timed_Triggers/2200.yaml +++ b/config/automation/Timed_Triggers/2200.yaml @@ -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 diff --git a/config/automation/Timed_Triggers/sunrise_turn_off.yaml b/config/automation/Timed_Triggers/sunrise_turn_off.yaml index f113b63c..7f2a4a6b 100755 --- a/config/automation/Timed_Triggers/sunrise_turn_off.yaml +++ b/config/automation/Timed_Triggers/sunrise_turn_off.yaml @@ -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 diff --git a/config/automation/Timed_Triggers/sunset_turn_on.yaml b/config/automation/Timed_Triggers/sunset_turn_on.yaml index 32d77740..aada99c4 100755 --- a/config/automation/Timed_Triggers/sunset_turn_on.yaml +++ b/config/automation/Timed_Triggers/sunset_turn_on.yaml @@ -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 - diff --git a/config/automation/late_night_outside_helper.yaml b/config/automation/late_night_outside_helper.yaml index c2529368..0f9e9ad5 100755 --- a/config/automation/late_night_outside_helper.yaml +++ b/config/automation/late_night_outside_helper.yaml @@ -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 diff --git a/config/automation/master_bath_accents.yaml b/config/automation/master_bath_accents.yaml index 05d5ccf4..2c3854bb 100755 --- a/config/automation/master_bath_accents.yaml +++ b/config/automation/master_bath_accents.yaml @@ -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 diff --git a/config/packages/garadget.yaml b/config/packages/garadget.yaml index 15a4d5c7..9a474800 100755 --- a/config/packages/garadget.yaml +++ b/config/packages/garadget.yaml @@ -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 diff --git a/config/packages/landscape_lighting.yaml b/config/packages/landscape_lighting.yaml index 81716b9d..5f66aaef 100755 --- a/config/packages/landscape_lighting.yaml +++ b/config/packages/landscape_lighting.yaml @@ -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' diff --git a/config/packages/lightning.yaml b/config/packages/lightning.yaml index 74e39f2b..0f0ed4b2 100755 --- a/config/packages/lightning.yaml +++ b/config/packages/lightning.yaml @@ -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 diff --git a/config/packages/rheem_econet.yaml b/config/packages/rheem_econet.yaml index 862636f8..377cccd8 100755 --- a/config/packages/rheem_econet.yaml +++ b/config/packages/rheem_econet.yaml @@ -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) diff --git a/config/script/notify_engine.yaml b/config/script/notify_engine.yaml index f51f86f0..30d9e8da 100755 --- a/config/script/notify_engine.yaml +++ b/config/script/notify_engine.yaml @@ -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) }}"