Reviving OpenWeatherMap forecast entities using templates

HomeAssistant 2024.7 removed the OpenWeatherMap integration’s forecast sensor entities.

As I use them in several automations that I would prefer not to alter, I emulated the old sensor.openweathermap_forecast_* entities using template sensors that update once per minute from the integration’s cached data.

Assuming that your weather entity is weather.home and you did not alter the friendly names or entity IDs of the sensors, this template will fully replace them:

template:
  - trigger:
      - platform: state
        entity_id: weather.home
      - platform: time_pattern
        hours: /1
    action:
      - action: weather.get_forecasts
        data:
          type: daily
        target:
          entity_id: weather.home
        response_variable: daily
    sensor:
      - name: OpenWeatherMap Forecast Cloud coverage
        unique_id: openweathermap_forecast_cloud_coverage
        state: "{{ daily['weather.home'].forecast[0].cloud_coverage }}"
        unit_of_measurement: '%'
      - name: OpenWeatherMap Forecast Condition
        unique_id: openweathermap_forecast_condition
        state: "{{ daily['weather.home'].forecast[0].condition }}"
      - name: OpenWeatherMap Forecast Precipitation
        unique_id: openweathermap_forecast_precipitation
        state: "{{ daily['weather.home'].forecast[0].precipitation }}"
        unit_of_measurement: mm
        device_class: precipitation
      - name: OpenWeatherMap Forecast Precipitation probability
        unique_id: openweathermap_forecast_precipitation_probability
        state: "{{ daily['weather.home'].forecast[0].precipitation_probability }}"
        unit_of_measurement: '%'
      - name: OpenWeatherMap Forecast Pressure
        unique_id: openweathermap_forecast_pressure
        state: "{{ daily['weather.home'].forecast[0].pressure }}"
        unit_of_measurement: hPa
        device_class: pressure
      - name: OpenWeatherMap Forecast Temperature
        unique_id: openweathermap_forecast_temperature
        state: "{{ daily['weather.home'].forecast[0].temperature }}"
        unit_of_measurement: °C
        device_class: temperature
      - name: OpenWeatherMap Forecast Temperature Low
        unique_id: openweathermap_forecast_temperature_low
        state: "{{ daily['weather.home'].forecast[0].templow }}"
        unit_of_measurement: °C
        device_class: temperature
      - name: OpenWeatherMap Forecast Time
        unique_id: openweathermap_forecast_time
        state: "{{ daily['weather.home'].forecast[0].datetime }}"
        device_class: timestamp
      - name: OpenWeatherMap Forecast Wind bearing
        unique_id: openweathermap_forecast_wind_bearing
        state: "{{ daily['weather.home'].forecast[0].wind_bearing }}"
        unit_of_measurement: °
      - name: OpenWeatherMap Forecast Wind speed
        unique_id: openweathermap_forecast_wind_speed
        state: "{{ daily['weather.home'].forecast[0].wind_speed }}"
        unit_of_measurement: m/s
        device_class: wind_speed

Delete the original, now orphaned entities or rename them and their IDs, put the snipped above into your configuration.yaml, let it check for correctness and reload template entities, and you should be good to go again.

A slightly more comprehensive guide in English and German can by found here:

2 Likes

That’s not how service: weather.get_forecasts works. It only checks a cache that the normal sensor update interval populates from the API. So your sensor is unneeded to mitigate this perceived issue.

Same thing occurs whenever you view a weather card in a dashboard. The data is loaded from cached memory, not the API.

1 Like

Thanks for clarification. I updated the guide accordingly.

Rather than triggering every minute (even when there has been no change) a much more efficient trigger would be:

  - trigger:
      - platform: state
        entity_id: weather.home

This will only trigger if the state or attributes of your weather entity change.

2 Likes

Thanks for the hint, though the forecasts are not part of the entity’s attributes, neither is a timestamp of the last update to the cache, so this would only trigger if there is change to the current weather between two updates.
Of course the current weather will change regularly, as temperature, humidity, … change over time, but it would be at least theoretically/potentially error prone.
Maybe a combination of state trigger plus time_pattern trigger at a longer interval is the way to go.

Go to Developer Tools → States and copy the attributes shown for your weather forecast entity (right hand column) and paste them here. There should be a timestamp.

1 Like

I assume you mean the weather entity, weather.home created by the OpenWeatherMap integration, not my weather forecast entities, which are templates.
I checked weather.home’s attributes before, but there is nothing looking even remotely like a timestamp:

temperature: 17
apparent_temperature: 16.7
dew_point: 12.3
temperature_unit: °C
humidity: 74
cloud_coverage: 75
pressure: 1017
pressure_unit: hPa
wind_bearing: 240
wind_speed: 1.84
wind_speed_unit: km/h
visibility_unit: km
precipitation_unit: mm
attribution: Data provided by OpenWeatherMap
friendly_name: OpenWeatherMap
supported_features: 3

Yeah ok that’s not good. You should probably open an issue for that integration. It needs a timestamp attribute so you don’t have to keep polling it for updates.

3 Likes

I opened issue #121595 for this earlier. Let’s see whether it gets implemented.

3 Likes

Is it possible that your template isn’t working? Under the created template
Entities I get the value Unknown.

My guess is that you did not change the entity_id of the OWM integration instance (in my example weather.home) to fit your configuration. The default name changed several times in the past and might also depend on how you named your home location.

If your entity_id is correct, does the details dialog show a forecast?

You are right.
The value was not correct. A look in Settings → Devices & services → Entities → OpenWeatherMap showed the mismatch.

target:
        entity_id: xyz

Therefore

  sensor:
        state: "{{ daily['yxz'].forecast[0].cloud_coverage }}"
...

Shame on me, @veitw explained it clearly in his blog.

I think I lack some skills to do correct templating. Maybe someone knows a good tutorial.

Thanks @veitw !

One part of the result, that is unclear to me is that the forecast graph doesn’t show the predicted future. I did the code fix around noon today (Aug 5) and now we have a few minutes before midnight.

This is correct, the original forecast entities showed the forecast for the current day, thus instead of showing the current conditions, it is showing percipation totals, maximum and minimum temperatures, … to expect for today. Hence it is normal for it to change over time and converge to a value as time progresses, and to reset to a new value at midnight.

If you want the values to represent the forecasts for tomorrow instead of today, you may change forecast[0] to forecast[1].

Is this still supposed to be working?
I tried the template yaml in the OP but don’t get any values, It won’t update for some reason.
Pretty frustrated over the removal of forecast, all of my TTS scripts that have been disabled during summer/vacation are now non functional =(

@BB9 Yes, it is working well. Most likely the reason for it not working is either you missed to replace all occurrences of weather.home by the entity_id of your OpenWeatherMap weather class entity, or you might have not migrated to the OpenWeatherMap API version 3.0, which OWM requires for all service calls since June 2024.

Could you please elaborate?

My plan is to completely get rid of OWM and to use your snippet to create OWM template entities, so that I can keep the temperature history of the last years and continue those graphs without interruption.

So it was somehow clear to me that I create template sensors having the name of the OWM integration, but getting their values from ‘weather.home’, which is in my case met.no.

I gave this a try, but I’m not getting any values and therefore I came back to read your last comment once again.

Am I completely wrong or what did you want to express?

Thanks

My guesses here were the two most common errors. If you are no longer using OWM at all, of course you don’t have to migrate to their new API version.

I do not use met.no, but as a core integration I expect it to support the weather.get_forecasts service, which is all my template needs.
To test this, you might want to try this via Developer Tools → Actions, with weather.home replaced by the entity_id of your met.no integration instance:

action: weather.get_forecasts
target:
  entity_id: weather.home
data:
  type: daily

Update 2024-10-20: In Home Assistant 2024.8 services have been renamed to actions, which also changes the keyword service to action. The listing has been updated accordingly.
Also the trigger has been changed from once per minute to changes of state of the weather entity, with additional trigger once per hour for fallback reasons, as the OpenWeatherMap integration does not guarantee a state change for every update.

1 Like

Thanks a lot for your comment.

Yesterday I tried out many things until late and something (like getting the temperature this way) worked nicely. But the cloud_coverage did not.
This morning, when I checked the state in the dev tools, like I did yesterday a hundered times, the coverage is there.

So maybe it is only something about this attribute? But the weather.home entity always showed a coverage the whole time … just the newly created sensor could not get it.
I have no ideas anymore.

As it is now working, I’ll set up sensors for all of my values and hope that it will heal itself until the next morning.

Which weather service are you using and why, if I’m allowed to ask?

Nope, seems I still don’t get it :frowning:

My Automation:

template:
  - trigger:
      - trigger: time_pattern
        minutes: /1
    action:
      - action: weather.get_forecasts
        data:
          type: daily
        target:
          entity_id: weather.home
        response_variable: daily
      - variables:
          today: "{{ daily['weather.home'].forecast[0] }}"
    sensor:
      - name: "OpenWeatherMap Forecast Cloud coverage_own_my"
        unique_id: openweathermap_forecast_cloud_coverage_own_my
        state: "{{ today.cloud_coverage }}"
        unit_of_measurement: "%"

recorder:
  exclude:
    entities:
      - sensor.openweathermap_forecast_cloud_coverage_own_my

My weather entities:


OWM still to be deleted, but to show what I currently have.

My result:

So, where did I take the wrong turn?