I try to implement a warning about possible frost via weather forecast. My plan is to use openweathermap, check if there is any temperature value below zero and send myself a notification. I could use a template sensor to check for a temperature below zero and use an automation to trigger the notification.
The forecast comes as an array with 40 objects for each time in the future.
My problem is now how to manage to iterate over that array and stop on the first finding or save the (first) finding in a variable. So far I tried namespaces but can’t read the value from the namespace:
{% set ns = namespace(temp=100) %}
{% for state in states.weather.openweathermap.attributes.forecast %}
{% if state.temperature <= 0 %}
{% set ns.temp = state.temperature %}
{% endif %}
{% endfor %}
Works but not what I need: {{ns}}
Doesn't work: {{ns.temp}}
Doesn't work: {{ns['temp']}}
Also using “break” to stop the iteration does not work for me (I guess it does not work with HA):
{% for state in states.weather.openweathermap.attributes.forecast %}
{% if state.temperature <= 0 %}
{{ state.temperature }}
{% break %}
{% endif %}
{% endfor %}
Does someone have an idea how I could get the first temperature below zero with it`s datetime?
Or is there a better approach to solve this without writing a custom component?
Thanks for sharing your config! That’s nice way to estimate the bad weather conditions It won’t do that for the next (3) day(s), right?
I would need it for a) taking plants inside that are not frost save and b) salt the pedestrian path. The earlier I know that I should do that the better
No, it doesn’t predict it a few days in advance, I use that sensor to make my alarm clock go off 15 minutes early if I’m going to have to scrape the car and take longer to get to work, so it’s more of a ‘this is happening now’ deal.
I guess though if you could get those values for 3 days time from the forecast somehow and be a little looser with the figures it could work, although it’ll be less accurate so you’d have to decide whether you want it to be overly cautious or whatever.
I setup a frost alert to notify me the night before so I can take any appropriate actions. It’s setup with DarkSky currently. You can add additional days to the forecast for more advanced notice.
Meanwhile, I got it working by following this post: Getting warned when it's going to freeze
It utilizes OpenWeatherMap, which I had as a sensor already, so appreciated that.
But I see that yours is much easier to setup with no need of Python! If I wouldn´t have it up and running already I would definitely now have gone for this one even though I would have to get another weather service up and running for it. It is also able to be used with metric / European values (i.e. Celsius instead of Fahrenheit)?
Should you be interested in a way to get tomorrow’s forecasted maximum or minimum temperatures from OpenWeatherMap, Petro posted a three-line template here:
It would be trivial to make it into a frost warning sensor.
NOTE
Any solutions based on the DarkSky API are now subject to the following limitations:
If you already have a DarkSky API key, the API service will terminate at the end of 2021.
If you do not currently have a DarkSky API key, you are no longer able to get one.
Thought to resurrect this thread as the DarkSky API is now inaccessible, so here is my solution using openWeather:
Sensor created in config.yaml
sensor:
######## Frost Sensor:
- platform: template
sensors:
24hrlowtemp:
value_template: >
{% set start = now().replace(hour=0,minute=0,second=0, microsecond=0) %}
{% set end = (start + timedelta(days=1)) %}
{% set start = start.strftime("%Y-%m-%dT%H:%M:%S+00:00") %}
{% set end = end.strftime("%Y-%m-%dT%H:%M:%S+00:00") %}
{{ state_attr('weather.openweathermap', 'forecast') | selectattr('datetime', '>=', start) | selectattr('datetime','<=', end) | map(attribute='templow') | list | max }}
Automation:
alias: Frost Forecast
description: >-
Checks the low temps for the next 24 hours and notifies to bring in plants and
open outdoor tap
mode: single
trigger:
- platform: time
at: '18:30:00'
condition:
- condition: numeric_state
entity_id: sensor.24hrlowtemp
below: '2'
action:
- service: notify.mobile_app
data:
title: Frost is forecast!
message: >-
Bring in the outdoor plants and consider opening the outdoor tap fully
(after turning it off, under the kitchen sink)
In 2024 openweather no longer provides an hourly state to use in this way, you instead need to call the service to retrieve the hourly forecast for analysis.
Here’s a fairly decent automation to warn you about upcoming frost in the next few days using the weather.get_forecasts style introduced earlier this year. If it looks familiar, it might. This is an updated version of a blog post by Stephan Klein (March 2021).
The 2 sensors created in the template get updated hourly with the daily weather forecast for the next few days. Within the template we check if there are any days where the forecast’s templow value is below zero, which day that is, for how many days it lasts. Based on all that goodness we can provide some informative notifications to a user and help drive some automation.
template:
- trigger:
- trigger: time_pattern
hours: /1
action:
- action: weather.get_forecasts
data:
type: daily
target:
entity_id: weather.forecast_hague
response_variable: daily_weather
sensor:
- name: "frost warning"
unique_id: "39a5e512-b92f-449c-b681"
icon: "mdi:snowflake-alert"
state: >-
{% if states('sensor.forecasted_minimal_temperature') | float < 0 %}
on
{% else %}
off
{% endif %}
attributes:
frostdays: >-
{% set ns = namespace(frostdays=0) %}
{%- for fc in daily_weather['weather.forecast_hague'].forecast -%}
{%- if fc.templow < 0 -%}
{%- set ns.frostdays = ns.frostdays + 1 -%}
{%- endif -%}
{%- endfor -%}
{{ns.frostdays}}
first_frost_date: >-
{% set ns = namespace(date=0) %}
{%- for fc in daily_weather['weather.forecast_hague'].forecast -%}
{%- if fc.templow < 0 and ns.date == 0 -%}
{%- set ns.date = fc.datetime -%}
{%- endif -%}
{%- endfor -%}
{{ns.date}}
date_low: "{{state_attr('sensor.forecasted_minimal_temperature', 'datetime')}}"
temp_low: "{{states('sensor.forecasted_minimal_temperature')}}"
forecastdays: "{{state_attr('sensor.forecasted_minimal_temperature', 'forecastdays')}}"
- name: "forecasted minimal temperature"
unique_id: "a148a623-7999-4d76-9af2"
unit_of_measurement: "°C"
icon: "mdi:thermometer-chevron-down"
state: >-
{% set ns = namespace(templow=999) %}
{%- for fc in daily_weather['weather.forecast_hague'].forecast -%}
{%- if fc.templow < ns.templow -%}
{%- set ns.templow = fc.templow -%}
{%- endif -%}
{%- endfor -%}
{{ns.templow}}
attributes:
datetime: >-
{% set ns = namespace(templow=999, datetime=0) %}
{%- for fc in daily_weather['weather.forecast_hague'].forecast -%}
{%- if fc.templow < ns.templow -%}
{%- set ns.datetime = fc.datetime -%}
{%- endif -%}
{%- endfor -%}
{{ns.datetime}}
forecastdays: >-
{% set ns = namespace(days=0) %}
{%- for fc in daily_weather['weather.forecast_hague'].forecast -%}
{%- set ns.days = ns.days + 1 -%}
{%- endfor -%}
{{ns.days}}
The nature of the two sensors and their use may become a little clearer if you look at the automation side of things. Notice the trigger, and the notification message itself.
automation:
- id: '1728145134278'
alias: 'Frost Warning: Send Notification'
description: If frost is forecast in the weather forecast, then send out a notification
so that the water is turned off.
triggers:
- entity_id: sensor.frost_warning
from: 'off'
to: 'on'
trigger: state
conditions: []
actions:
- data:
title: Winter is coming!
message: From {{ as_timestamp(state_attr("sensor.frost_warning", "first_frost_date"))
| timestamp_custom("%a, %d.%m.%y", True) }} it should freeze with temperatures
down to {{ state_attr('sensor.frost_warning', 'temp_low') }}°C on {{state_attr('sensor.frost_warning',
'frostdays') }} days in the coming {{state_attr('sensor.frost_warning', 'forecastdays')
}} days.
data:
priority: 1
action: notify.notify
mode: single
As with most things, this won’t run straight out of the box. You will need to replace ‘forecast_hague’ with your weather enity.
It’s also worth checking if your provider gives daily weather reports:
go to Developer tools.
open the Actions tab.
select “Weather: Get forecasts”.
set “Targets” to your provider.
set “Forecast type” to daily.
click “Perform Action”.
You should now see something in the Response pane which resembles several days of forecasted weather.
That’s all there is to it. I hope you find it useful.
This is fantastic, thanks for sharing! Can you please let us know how you have defined sensor.forecasted_minimal_temperature? That seems to be the missing piece of the puzzle. Thanks!
Can you please let us know how you have defined sensor.forecasted_minimal_temperature? That seems to be the missing piece of the puzzle. Thanks!
Take a closer look at the first piece of code I posted above, the template where I define two sensors.
It’s also good to remember that when you define sensors the spaces in the names get replaced with underscores by HA when you use them elsewhere. Hence forecasted_minimal_temperature is defined as:
Ooof * face palm*! Thanks for this! I got it to work now. It wasn’t the sensor that was causing it but more that the data wasn’t available due to the time_pattern. I’ve also added new triggers to prevent this from happening, which made troubleshooting easier too. Thanks again!