Operations on collections (lists?)

I need to perform operations on collections (lists?) in YAML to get some values that I need from OpenWeatherMap.

The things I need to expose are:

  • Does the condition become ‘foggy’, ‘misty’ or ‘smoky’ in the next 24 hours
  • The maximum humidity figure in the next 24 hours
  • The maximum hourly precipitation in the next 24 hours
  • The total precipitation for the next 24 hours
  • The maximum wind speed in the next 24 hours
  • The maximum and minimum temperatures in the next 24 hours

In the Template editor in Development Tools, I can see the values that I need and do basic tests on them, but I’m new to this and am hoping that there is a nicer way to do things than what I have currently. The following is the code for checking if it becomes ‘foggy’, ‘misty’ or ‘smoky’ in the next 24 hours. Is there a better way of doings this? Would generating maximums, minimums or totals be done in much the same way, or are there shorter/faster ways of doing things?

{%- set data = namespace(res=false) -%}
{% set attrs = states.weather.openweathermap.attributes %}
{% for i in range(0, 23) %}
{% if attrs['forecast'][i].condition in ["foggy", "misty", "smoky"] %}
{%- set data.res = true -%}
{% if not loop.last %}
{% break %}
{% endif %}
{% endif %}
{% endfor %}
{{data.res}}

Before you get too far into setting up a bunch of sensors based on forecast attributes make sure to take a look at the following:

Release Notes: 2023-09

With that out of the way…

It is often possible to use filtering instead of using namespaces and loops:

{{ state_attr('weather.openweathermap','forecast')
| rejectattr('datetime', 'lt', utcnow().isoformat())
| rejectattr('datetime', 'gt', (utcnow()+timedelta(days=1)).isoformat())
| selectattr('condition', 'in', ["foggy", "misty", "smoky"])
| list | count > 0 }}