How can select based on local time in a UTC json?

I’m currently trying to set up a twice daily weather report, the one I get from get_weather is not what I want. I need two daytime values but the integration gives me midnight and noon.

So, I set up a API sensor to get the data myself and I get the data.
Now I want to get lets say the average wind speed. And currently this kind of works.

 {% for d in range(1,5) %}
  {{ state_attr('sensor.smhi_hourly_2', 'timeSeries')
   | selectattr('time', '>=', (utcnow().replace(hour=6)+ timedelta(days= d | int)).isoformat()) 
   | selectattr('time', '<=', (utcnow().replace(hour=12)+ timedelta(days= d | int)).isoformat()) 
   | map(attribute='data')| map(attribute='wind_speed')
   | list | average | round(1)}} m/s

  {{ state_attr('sensor.smhi_hourly_2', 'timeSeries')
   | selectattr('time', '>=', (utcnow().replace(hour=12)+ timedelta(days= d | int)).isoformat()) 
   | selectattr('time', '<=', (utcnow().replace(hour=18)+ timedelta(days= d | int)).isoformat()) 
   | map(attribute='data')| map(attribute='wind_speed')
   | list | average | round(1) }} m/s
   __________________
{% endfor %}

As far as I can tell since the data is in UTC everything is off from what I expect.
I could change the replace but that will mean I get issues at winter time again (right?).
So what would be the “proper solution”?

In case anyone wants to play with the data then the below is the relevant parts of the API output and adjusted templates to just copy paste to template tools.

Summary
{% set json = {
  "timeSeries": [
    { "time": "2026-04-07T08:00:00Z", "data": { "wind_speed": 4.8 } },
    { "time": "2026-04-07T09:00:00Z", "data": { "wind_speed": 5.1 } },
    { "time": "2026-04-07T10:00:00Z", "data": { "wind_speed": 5.8 } },
    { "time": "2026-04-07T11:00:00Z", "data": { "wind_speed": 6.3 } },
    { "time": "2026-04-07T12:00:00Z", "data": { "wind_speed": 6.7 } },
    { "time": "2026-04-07T13:00:00Z", "data": { "wind_speed": 7.0 } },
    { "time": "2026-04-07T14:00:00Z", "data": { "wind_speed": 6.4 } },
    { "time": "2026-04-07T15:00:00Z", "data": { "wind_speed": 6.1 } },
    { "time": "2026-04-07T16:00:00Z", "data": { "wind_speed": 6.0 } },
    { "time": "2026-04-07T17:00:00Z", "data": { "wind_speed": 5.7 } },
    { "time": "2026-04-07T18:00:00Z", "data": { "wind_speed": 4.1 } },
    { "time": "2026-04-07T19:00:00Z", "data": { "wind_speed": 2.9 } },
    { "time": "2026-04-07T20:00:00Z", "data": { "wind_speed": 2.4 } },
    { "time": "2026-04-07T21:00:00Z", "data": { "wind_speed": 2.1 } },
    { "time": "2026-04-07T22:00:00Z", "data": { "wind_speed": 2.2 } },
    { "time": "2026-04-07T23:00:00Z", "data": { "wind_speed": 2.1 } },

    { "time": "2026-04-08T00:00:00Z", "data": { "wind_speed": 2.1 } },
    { "time": "2026-04-08T01:00:00Z", "data": { "wind_speed": 2.0 } },
    { "time": "2026-04-08T02:00:00Z", "data": { "wind_speed": 2.1 } },
    { "time": "2026-04-08T03:00:00Z", "data": { "wind_speed": 2.4 } },
    { "time": "2026-04-08T04:00:00Z", "data": { "wind_speed": 2.4 } },
    { "time": "2026-04-08T05:00:00Z", "data": { "wind_speed": 2.4 } },
    { "time": "2026-04-08T06:00:00Z", "data": { "wind_speed": 1.6 } },
    { "time": "2026-04-08T07:00:00Z", "data": { "wind_speed": 2.3 } },
    { "time": "2026-04-08T08:00:00Z", "data": { "wind_speed": 3.4 } },
    { "time": "2026-04-08T09:00:00Z", "data": { "wind_speed": 3.6 } },
    { "time": "2026-04-08T10:00:00Z", "data": { "wind_speed": 3.7 } },
    { "time": "2026-04-08T11:00:00Z", "data": { "wind_speed": 4.4 } },
    { "time": "2026-04-08T12:00:00Z", "data": { "wind_speed": 3.5 } },
    { "time": "2026-04-08T13:00:00Z", "data": { "wind_speed": 2.8 } },
    { "time": "2026-04-08T14:00:00Z", "data": { "wind_speed": 2.4 } },
    { "time": "2026-04-08T15:00:00Z", "data": { "wind_speed": 1.7 } },
    { "time": "2026-04-08T16:00:00Z", "data": { "wind_speed": 0.5 } },
    { "time": "2026-04-08T17:00:00Z", "data": { "wind_speed": 3.2 } },
    { "time": "2026-04-08T18:00:00Z", "data": { "wind_speed": 2.4 } },
    { "time": "2026-04-08T19:00:00Z", "data": { "wind_speed": 2.6 } },
    { "time": "2026-04-08T20:00:00Z", "data": { "wind_speed": 2.4 } },
    { "time": "2026-04-08T21:00:00Z", "data": { "wind_speed": 1.6 } },
    { "time": "2026-04-08T22:00:00Z", "data": { "wind_speed": 1.7 } },
    { "time": "2026-04-08T23:00:00Z", "data": { "wind_speed": 2.1 } },

    { "time": "2026-04-09T00:00:00Z", "data": { "wind_speed": 2.1 } },
    { "time": "2026-04-09T01:00:00Z", "data": { "wind_speed": 0.6 } },
    { "time": "2026-04-09T02:00:00Z", "data": { "wind_speed": 1.2 } },
    { "time": "2026-04-09T03:00:00Z", "data": { "wind_speed": 1.7 } },
    { "time": "2026-04-09T04:00:00Z", "data": { "wind_speed": 2.2 } },
    { "time": "2026-04-09T05:00:00Z", "data": { "wind_speed": 1.9 } },
    { "time": "2026-04-09T06:00:00Z", "data": { "wind_speed": 2.5 } },
    { "time": "2026-04-09T07:00:00Z", "data": { "wind_speed": 2.9 } },
    { "time": "2026-04-09T08:00:00Z", "data": { "wind_speed": 3.6 } },
    { "time": "2026-04-09T09:00:00Z", "data": { "wind_speed": 3.7 } },
    { "time": "2026-04-09T10:00:00Z", "data": { "wind_speed": 4.4 } },
    { "time": "2026-04-09T11:00:00Z", "data": { "wind_speed": 4.7 } },
    { "time": "2026-04-09T12:00:00Z", "data": { "wind_speed": 4.7 } },
    { "time": "2026-04-09T13:00:00Z", "data": { "wind_speed": 4.6 } },
    { "time": "2026-04-09T14:00:00Z", "data": { "wind_speed": 4.8 } },
    { "time": "2026-04-09T15:00:00Z", "data": { "wind_speed": 4.9 } },
    { "time": "2026-04-09T16:00:00Z", "data": { "wind_speed": 5.1 } },

    { "time": "2026-04-10T00:00:00Z", "data": { "wind_speed": 4.9 } },
    { "time": "2026-04-10T06:00:00Z", "data": { "wind_speed": 4.0 } },
    { "time": "2026-04-10T12:00:00Z", "data": { "wind_speed": 5.2 } },
    { "time": "2026-04-10T18:00:00Z", "data": { "wind_speed": 2.2 } },

    { "time": "2026-04-11T00:00:00Z", "data": { "wind_speed": 2.5 } },
    { "time": "2026-04-11T06:00:00Z", "data": { "wind_speed": 3.6 } },
    { "time": "2026-04-11T12:00:00Z", "data": { "wind_speed": 5.1 } },
    { "time": "2026-04-11T18:00:00Z", "data": { "wind_speed": 4.3 } },

    { "time": "2026-04-12T00:00:00Z", "data": { "wind_speed": 4.5 } },
    { "time": "2026-04-12T06:00:00Z", "data": { "wind_speed": 4.3 } },
    { "time": "2026-04-12T12:00:00Z", "data": { "wind_speed": 7.1 } },
    { "time": "2026-04-12T18:00:00Z", "data": { "wind_speed": 5.5 } },

    { "time": "2026-04-13T00:00:00Z", "data": { "wind_speed": 4.7 } },
    { "time": "2026-04-13T12:00:00Z", "data": { "wind_speed": 5.5 } },

    { "time": "2026-04-14T00:00:00Z", "data": { "wind_speed": 4.4 } },
    { "time": "2026-04-14T12:00:00Z", "data": { "wind_speed": 4.9 } },

    { "time": "2026-04-15T00:00:00Z", "data": { "wind_speed": 3.4 } },
    { "time": "2026-04-15T12:00:00Z", "data": { "wind_speed": 4.0 } },

    { "time": "2026-04-16T00:00:00Z", "data": { "wind_speed": 2.9 } },
    { "time": "2026-04-16T12:00:00Z", "data": { "wind_speed": 4.0 } },

    { "time": "2026-04-17T00:00:00Z", "data": { "wind_speed": 2.9 } },
    { "time": "2026-04-17T12:00:00Z", "data": { "wind_speed": 4.1 } }
  ]
} %}

{% for d in range(1,5) %}
  {{ json.timeSeries
   | selectattr('time', '>=', (utcnow().replace(hour=6)+ timedelta(days= d | int)).isoformat()) 
   | selectattr('time', '<=', (utcnow().replace(hour=12)+ timedelta(days= d | int)).isoformat()) 
   | map(attribute='data')| map(attribute='wind_speed')
   | list | average | round(1)}} m/s

  {{ json.timeSeries
   | selectattr('time', '>=', (utcnow().replace(hour=12)+ timedelta(days= d | int)).isoformat()) 
   | selectattr('time', '<=', (utcnow().replace(hour=18)+ timedelta(days= d | int)).isoformat()) 
   | map(attribute='data')| map(attribute='wind_speed')
   | list | average | round(1) }} m/s
   __________________
{% endfor %}
{%- set fmat = '%Y-%m-%dT%H:%M:%SZ' %}
{%- set tseries = state_attr('sensor.smhi_hourly_2', 'timeSeries') %}
{%- for d in range(1, 5) %}
  {%- for s, e in (('00:00', '06:00'), ('06:00', '12:00')) %}
    {%- set mintime = today_at(s).astimezone(utcnow().tzinfo) + timedelta(days=d) %}
    {%- set maxtime = today_at(e).astimezone(utcnow().tzinfo) + timedelta(days=d) %}
    {{ tseries | selectattr('time', '>=', mintime.strftime(fmat))
               | selectattr('time', '<=', maxtime.strftime(fmat))
               | map(attribute='data.wind_speed')
               | list | average | round(1) }} m/s
  {%- endfor %}
{%- endfor %}
1 Like

There is two missing ) at the end of selectattr.

That seems like a good method.
Thank you!

1 Like

Updated :+1: