Weather forecast - syntax understanding issue

Hi !

I really need help to make a very simple wind sensor that takes the average of the next 3 hours from the integrated weather forecast for wind… I’ve looked at many discussions here and the doc, and I though I understood but obviously not. It updates each hour with no values in it,
any advice ?
Thanks

  - trigger:
      - trigger: time_pattern
        hours: "/1"
    action:
      - action: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id: weather.forecast_maison
        response_variable: hourly_forecast
    sensor:
      - name: "wind_speed_forecast_avg"
        unique_id: wind_speed_forecast_avg
        state: >
          {% set forecast_hours = 3 %}
          {% set wind_speeds = state_attr('weather.forecast_maison', 'forecast')[:forecast_hours] | map(attribute='wind_speed') | list %}
          {% if wind_speeds | length > 0 %}
            {{ (wind_speeds | map('float') | sum / wind_speeds | length) | round(2) }}
          {% else %}
            0
          {% endif %}
        unit_of_measurement: "m/s"
        device_class: wind_speed
        state_class: measurement
        icon: mdi:weather-windy

The response from your weather.get_forecasts action will be in your response variable hourly_forecast. As far as I can tell you never do anything with that variable…?

yes, that’s totally stange, though I’ve read so many examples like this :see_no_evil:
maybe better if I replace this

{% set wind_speeds = state_attr('weather.forecast_maison', 'forecast')[:forecast_hours] | map(attribute='wind_speed') | list %}

with that ?

{% set wind_speeds = hourly_forecast[:forecast_hours] | map(attribute='wind_speed') | list %}

I have never used that action and it sure sounds like you haven’t either, so I’d start by running it manually in the Developer Tools > Action panel (or an automation/script) so you can see exactly how the response looks.

AFAIK a response variable always contains a dict/mapping at its root level, so you probably cannot assume to use list syntax directly at the root. The example you linked to uses the entity id of your forecast service as its initial key, probably so that multiple services can be queried in the same action.

I’m desperately trying to run it in developer tools too, and I can see that’s wrong
I can get current weather with that:

{{ states('weather.forecast_maison') }}

but value is none for that:

{{ state_attr('weather.forecast_maison','forecast') }}

The forecast is not an attribute. Why are you trying to access it as an attribute? You need to run the weather.get_forecasts action, then process the response variable.

To see what the response variable contains, use the Developer Tools > Actions panel. Do not attempt to use the Developer Tools > Template panel, it will not help you.

1 Like

Now that I am no longer on the phone but in front of a computer I looked at how the weather.get_forecasts action works, and it was pretty much exactly as expected. Something like this should produce what you are after:

{% set forecast_hours = 3 %}
{{ (hourly_forecast['weather.forecast_maison']['forecast'][:forecast_hours]
| map(attribute='wind_speed') | sum / forecast_hours) | round(2) }}

I might move the definition of forecast_hours out of the template and into a YAML-level variable instead though. Looks a little cleaner and more obvious if you want to change it later, or make a blueprint out of it or whatever. If so maybe also put the entity id of the weather service into a variable rather than hardcoding it in multiple places.

1 Like

Thanks a lot for the explanations and your patience :pray: (I’m a noob, but the action panel is really cool :+1: )
And you’re solution is working perfectly in a single line of code that’s perfect :slight_smile:

And I agree that I need to clean several things (but I was trying to make it work first):

  • agree tthat forecast hours should be defined in a more cleaner way to adapt to the situation
  • but I want a more general / cleaner way to call the weather service something like this has proved to work to set a wind speed template sensor:
{% set weather_entities = states.weather | selectattr('attributes.wind_speed', 'defined') | list %}
{{ (weather_entities[0].attributes.wind_speed | float) / 3.6 }}

But I don’t know how to use it in the action get_forecasts as I need the entity_id…
I tried this terrible thing :no_mouth: (and that’s not working)

action: weather.get_forecasts
data:
  type: hourly
target:
  entity_id: >
    {{ states.weather | selectattr('attributes.wind_speed', 'defined') }}
response_variable: hourly_forecast

That expression produces a generator object, and if use a list filter what you get is a list of state objects. So you may as well turn those state objects into entity ids first, then finish by turning the generator into a list (which is what the action expects to get, either a single entity id (string) or a list of them). Thus:

{{ states.weather | selectattr('attributes.wind_speed', 'defined')
| map('attr', 'entity_id') | list }}

So if you feed that into weather.get_forecasts, you will end up with a dict containing separate forecasts from each weather service for which you have an integration in HASS.

1 Like

Thanks :+1:
Finally, I think that the sensor should work now, but I need to wait next hour to be sure as I understood the hourly trigger will happen each hour :slight_smile: (but I successfully tested the lines in action panel and model panel)

Here is my sensor definition now

  - trigger:
      - trigger: time_pattern
        hours: "/1"
    action:
      - action: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id: >
            {{ states.weather | selectattr('attributes.wind_speed', 'defined') | map('attr', 'entity_id') | list }}
        response_variable: hourly_forecast
    sensor:
      - name: "wind_speed_forecast_avg"
        unique_id: wind_speed_forecast_avg
        state: >
          {% set forecast_hours = 3 %}
          {% set weather_entities = states.weather | selectattr('attributes.wind_speed', 'defined') | map('attr', 'entity_id') | list %}
          {{ (hourly_forecast[weather_entities[0]]['forecast'][:forecast_hours] | map(attribute='wind_speed') | sum / forecast_hours) | round(2) }}
        unit_of_measurement: "m/s"
        device_class: wind_speed
        state_class: measurement
        icon: mdi:weather-windy

EDIT I took the first weather entity as I need only one :slight_smile:
EDIT2: after the hour passed, it worked :+1: