I recently made this.
template:
- trigger:
- platform: time_pattern
# every 5 minutes past the hour
hours: "*"
minutes: "5"
- platform: state
entity_id: weather.openweathermap
action:
- service: weather.get_forecasts
target:
entity_id: weather.openweathermap
data:
type: hourly
response_variable: hourly
binary_sensor:
- name: "Weather Forecast Precipitation Soon"
unique_id: "949dd25e-35cf-4000-a3f9-f38ab20e112f"
device_class: moisture
state: >-
{% set threshold = 5 %}
{% set forecast = hourly['weather.openweathermap']['forecast'] %}
{% set start = utcnow() %}
{% set end = start + timedelta(hours=12) %}
{% set precipitation_soon = forecast
| selectattr('datetime', '>=', start.isoformat())
| selectattr('datetime', '<=', end.isoformat())
| map(attribute='precipitation')
| map('int')
| select('>=', threshold)
| list
| count > 0 %}
{{ precipitation_soon }}
automation:
- alias: "Notify When Significant Rain Is Expected"
id: "aff421a7-d99a-45c2-baa5-710b11d010b9"
initial_state: true
variables:
last_changed: "{{ states.binary_sensor.weather_forecast_precipitation_soon.last_changed }}"
trigger:
# id is the number of seconds from the previous time slot
- platform: time
at: "06:30:00"
id: "41400"
- platform: time
at: "12:00:00"
id: "19800"
- platform: time
at: "17:30:00"
id: "19800"
- platform: time
at: "19:00:00"
id: "5400"
condition:
- condition: state
entity_id: binary_sensor.weather_forecast_precipitation_soon
state: "on"
# if the sensor changed to on during the last interval
- condition: template
value_template: >
{{ (now() - last_changed | as_datetime).total_seconds() < trigger.id | int(0) }}
- condition: state
entity_id: binary_sensor.pieter_present
state: "on"
action:
- service: weather.get_forecasts
target:
entity_id: weather.openweathermap
data:
type: hourly
response_variable: hourly
- service: notify.mobile_app_ceres
data:
title: "🌧️ Rain Expected"
message: >-
{% set forecast = hourly['weather.openweathermap']['forecast'] %}
{# must match the sensor's definition #}
{% set start = utcnow() + timedelta(hours=12) %}
{% set end = start + timedelta(hours=36) %}
{% set rain_window = forecast
| selectattr('datetime', '>=', start.isoformat())
| selectattr('datetime', '<', end.isoformat())
| list %}
{# find first rainy hour #}
{% set first_rain = rain_window
| selectattr('precipitation', '>', 0)
| list
| first %}
{% if first_rain %}
{% set first_rain_local_dt = first_rain.datetime | as_datetime | as_local %}
{% set rain_time = first_rain_local_dt.strftime('%H:%M') %}
{# later today → tonight → overnight → early morning → early tomorrow → later tomorrow #}
{% if first_rain_local_dt.date() == now().date() %}
{% set time_phrase = "later today" %}
{% elif first_rain_local_dt.hour < 4 %}
{% set time_phrase = "overnight" %}
{% elif first_rain_local_dt.hour < 7 %}
{% set time_phrase = "early morning" %}
{% elif first_rain_local_dt.hour < 10 %}
{% set time_phrase = "early tomorrow" %}
{% elif first_rain_local_dt.hour < 18 %}
{% set time_phrase = "later tomorrow" %}
{% else %}
{% set time_phrase = "tonight" %}
{% endif %}
Rain is expected {{ time_phrase }} around {{ rain_time }}. Plan accordingly.
{% else %}
Rain is expected, but timing is uncertain. Check the forecast and plan accordingly.
{% endif %}
Rain is expected {{ time_phrase }}. Plan accordingly.
data:
url: homeassistant://navigate/lovelace-main/environment
group: "environment"