I’m looking for suggestions on how to check the onecall_hourly forecast of the OpenWeatherMap integration and calculate the number of hours until this forecast is above/below a certain limit. In my specific case, I’d want to generate a notification if it will be freezing over night, including the time period when it will do so. Something like “Tonight it’s going to be cold. Between 3am and 6am the temperature will be below 0° C, with a minimum of -5° C at 5am.”. (I’m using this warning to decide if I move some plants from my terrace to a room indoor over night when it’s going to be very cold outside to prevent them from freezing)
The state attributes of weather.openweathermap in the states inspector in developer tools shows that there is a yaml array named forecast and each item of the array contains the key/value pair for both temperature and datetime.
Please excuse if “array” and “key/value” is incorrect lingo in python/yaml. I’m very new to YAML and can’t yet find something appropriate in the Home AssistantUI. I was able to set the logic up in a homekit automation, but I’m currently moving everything away from homekit.
In Homekit automation I’d first create an array of only the temperature values, then count through the array until the first time the value is below 0, save that counter in a variable, continue counting until it rises above zero again, save that in another variable, and also compare each value to the minimum of the array and store the index in a third variable.
But how would I do that in a value template? If anyone could point me in the right direction, I’d very much appreciate it. Thanks!
I do this for a number of things using the forecast. Here’s an example:
sensor:
- name: "Next Precipitation"
unique_id: "9d693c5a-5ea7-4ca2-88d1-cadc3563172f"
icon: mdi:weather-rainy
state: >-
{% set ns = namespace(raintime = "") %}
{% if int(state_attr('weather.smart_weather_daily', 'forecast')[0].precipitation_probability | round(0), 0) > 10 %}
{% for s in state_attr('weather.smart_weather', 'forecast') | list %}
{% if int(s['precipitation_probability'], 0) > 19 %}
{% set ns.raintime = int(s['precipitation_probability'], 0) | string + '% Chance on ' + as_timestamp(s.datetime) | timestamp_custom('%A %b %-d at %-I:00 %p ') %}
{% break %}
{% endif %}
{% endfor %}
{% endif %}
{% if ns.raintime != "" %}
{{ ns.raintime }}
{% else %}
{{ "Nothing 20% or more forecast for the next 4 days" }}
{% endif %}
That is so I have a sensor of the next time rain is forecast for 20% or more chance using the hourly weather forecast. You can modify this easily to see lowtemp or just what the forecast temperature is at that time. If you want to limit it, you can just limit the loop to X hours into the future or use a date comparison like I do to find out the humidity and temp at a particular time like this:
{% set ns = namespace(high_temp = 0, humidity = 0) %}
{% set current_date = (now() | as_timestamp) | timestamp_custom("%d.%m.%Y") %}
{% for forecast in state_attr('weather.smart_weather_detailed_forecast','forecast') %}
{% if (forecast.datetime | as_timestamp) | timestamp_custom("%d.%m.%Y") == current_date %}
{% if forecast.temperature > ns.high_temp %}
{% set ns.high_temp = forecast.temperature %}
{% set ns.humidity = forecast.humidity %}
{% endif %}
{% endif %}
{% endfor %}
The “smart_weather_detailed_forecast” is a template weather device I created to use whatever is available in my 4 different weather integrations (in case my primary is down).
Oh wow, this is an impressive script. Thank you very, very much. I will have to find some basic Python tutorials to understand everything, I’m currently only familiar with Ruby and it is a transition to a different language. And the difficult part is partly the “short” syntax, such as the | pipe seems to be passing the result of a method to the next, which would translate to dots in Ruby. And these things are much harder to google than method names.
One additional question though: From what I’ve read about Python, the block scalar | turns every newline within the string into a literal newline. As I’d not want these newlines in the message variable, I changed it to:
message: >
{% if first_low != 'No Values' %}
{% set last_low = forecast|selectattr('temperature', 'le', threshold)
But as soon as I save the script and reopen it, the > is replaced by a ‘|’ again. Is there something preventing string variables in scripts using the folded style? Or is it an issue with the UI, that even when editing it in YAML mode, it will somehow parse everything and replace parts of it?
While Python might help with some aspects of Jinja templating in HA, check out the following before you do a deep dive:
Various Jinja Templating Documents
Jinja Docs: This document describes the syntax and semantics of the template engine.
Home Assistant Templating : This is the the most comprehensive and up-to-date source for HA-specific functions.
Jinja for Ninjas: This is a well organized tutorial and group of examples. It’s been a while since this was updated, so there are better/easier ways to do some of the things shown, but it’s still a good resource.
The UI editor does weird and annoying things to multi-line quotes. No matter whether you use > or | the actual yaml loses the block scalar header. If you use the folding with chomping header>-, it will persist in the UI editor’s “Edit in YAML”, but I haven’t bothered experimenting if the actual text output of the template… I don’t really have any templates where it matters.
Don’t waste your time removing them manually unless your going to move the scripts out of the UI-manged scripts.yaml file, they will just be changed back at some, seemingly random, point in the future… that’s the “annoying” part of my earlier statement.