Rain notification, Based on forecast

Hello, i am fighting almost two weeks with a way to receive notifications, based on weather forecast. In my cast incoming rain i next 24h.

currently i have integration met.no and weather.com.

The code i have is the following, but not sending me anything.

No error in the logs, the notification part is correct as the rest of the automation work smoothly.

Thank you.

alias: Rain notification next 24h (robust test)
triggers:

  • trigger: time_pattern
    hours: /2
    conditions:

  • condition: template
    value_template: >
    {% set forecast = state_attr(‘weather.home’, ‘forecast’) %} {% if not
    forecast %}
    false
    {% else %}
    {% set now_ts = now().timestamp() %}
    {% set next_24h = now_ts + 86400 %}

    {% set rainy = [] %}
    {% for f in forecast %}
      {% if f.datetime is defined and f.precipitation is defined %}
        {% set ts = as_timestamp(f.datetime) %}
        {% if ts >= now_ts and ts <= next_24h and f.precipitation > 0 %}
          {% set rainy = rainy + [f] %}
        {% endif %}
      {% endif %}
    {% endfor %}
    
    {{ rainy | count > 0 }}
    

    {% endif %}
    actions:

  • data:
    message: “:cloud_with_rain: Rain detected in next 24h!”
    action: notify.mobile_app_miro
    mode: single

Please follow Community Questions Guideline #11 by using the “Preformatted text” option on any code or YAML configuration so that it is properly formatted. It can be difficult to determine the source of an issue if we cannot tell whether the proper indentation and syntax has been followed.


The forecast attribute was removed from most weather service integrations nearly 3 years ago… making the function call state_attr('weather.home', 'forecast') very unlikely to produce anything.

You will need to use the weather.get_forecasts action. In addition to the examples found on the linked Weather integration’s page, if you search this forum for that action you will find dozens of examples similar to what you are trying to do.

2 Likes

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"
1 Like

Ups, edit. Found the answer.

Tnx, after few hours if test to run in under weather.com, i still get this error, while test the template

UndefinedError: ‘hourly’ is undefined

Any ideas?

Thank you

Do you mean you are receiving that error when testing the template in the Template Editor?

The variable hourly does not have any value in the Template Editor unless you define it. The editor does not parse YAML and cannot run actions… it only renders Jinja templates.

You can run the action in the Actions tool to generate a response. Scroll down to the bottom and click “Copy to clipboard as template”. Paste that into the Template Editor above the template you are testing.

2 Likes

If you’re using my version, please note that I fixed something in my template (post updated). It’s not related to your issue (it’s ve ry likely what Didgeridrew said), but I had to mention it: The bug was that it reported the rain’s start time incorrectly.

1 Like