Add force_update support to template sensor

Give me the full yaml detail for your template sensor and I’ll show you how to get it to update if ANY contributing element updates, or we can just do it on 1 minute intervals if you require it to be as clockwork

Just read the links I posted earlier.
Feel free to reply to the thread behind the second link.

Sebastian

Is this already accomplished in some way? I’m using a trend sensor on a template sensor, but it looks like it doesn’t work properly since the update interval is very low.

Please update topic, force_update also very important for statistics for slowly changes sensors.
Thanks.

3 Likes

Yeah,i also have this problem. I set up a mqtt sensor for temperature in my car, and a template for checking when it was last updated. I thought that states.car_temp.last_updated would contain the time it was last updated, and last_changed would have the time for last change, but in reality they both just reflect when the value is updated AND changed.

Because of this, if the temperature is constant for over 5 minutes, the template shows car as away(template is updated every minute with sensor.time also, since we cant get car temp over wifi if it’s not here).

And there seem to be no way around this? how would you get a new timestamp for last recieved update from a sensor if there is no such timestamp registered if the value is not changed? even worse, the template does not seem to update on duplicate updates, i’m not a 100% on this since i did not try that specifically, but according to what i have seen so far, i could not even create an extra template to update now() into a diy extra car_temp_last_updated, since it only is run on changes or each new minute from the sensor.time.

But might be that my template is monitoring states.car_temp.last_updated, and monitoring states.car_temp itself might make a diy last_updated possible.

But yea, #rantover. i’m suprised that this was like this? OK if there was a universal force_update option, but not updating on new updates seems VERY counterintuitive, and not having an option for it just seems broken.

To illustrate the issue from my original post, here’s the graph of my sensors’ battery levels (from Grafana):
Last 30 days:

Last 2 days:

Last 24 hours:

Grafana can be configured to use the last valid data point inside the time frame to draw a graph (that’s why it’s usually lines and not just dots for each data point), but if no data point falls within the time frame, nothing can be drawn.

Sebastian

2 Likes

Actually, this is ready implemented… and for my use as above, there is also as i found since then, an expire_after parameter that does exactly what i wanted to have… so i guess that HA is keeping track of last updated time in the background, that is in addition to the “official” last_updated, since it expires correctly even if the last values was the same for much longer. in my case, temp == 23 for one hour, timestamp does not update, but power off the temp sensor and it’s shown as unavailable after 5 more mins. Perfect!

However, i updated the code on the sensor firmware itself to add this “expires_after” into mqtt discovery, now i wonder if you can add to a sensors configuration in configuration.yaml?

That is, if i have a sensor with mqtt discovery and updating the firmware myself is not an option, could i add just “force_update: true” in yaml and when that sensor is discovered my custom config would be added to the discovered one?

if you look in the supported abbreviation list you also find “force_update”

Edit: After reading your initial question again, i guess this is still not quite what you wanted… but if you can append the configuration with yaml, i guess that might get you close enough?

I’m not sure what you’re suggesting. The MQTT sensors have nothing to do with template sensors.
Have a look at the referenced threads at the top.

To summarize:
I have a bunch of template sensors ("sensor.bat_device_xyz") that expose the battery levels of various (Z-Wave) devices. This data is fed into an InfluxDB instance.
Each time the state of one of those sensors changes, a new data point is created in the InfluxDB database - or, as long as the state does not change, no new data points are created.

Im graphing these sensor values using Grafana. Grafana needs valid data points to draw a graph for the selected time frame (e.g. 1 day). If there is no valid data for the selected time available, the graph cannot be drawn.

Due to their nature, the battery level values only change very slowly, so there’s often longer time spans where no new data points are created.

HA currently has no means to update a template sensor’s state (not even the last_updated attribute) if the sensor’s value does not change.
Ideally there would be a means to create new data points by updating timestamp of the template sensor’s last_updated attribute even if the sensor’s value hasn’t changed.

Sebastian

1 Like

It seems I have to correct myself.
I just checked the template sensor documentation and it seems there’s now a way to not only template the sensor value but also specify templates for attributes. I had completely missed that.
With that it should be possible to add an attribute to each template sensor that updates regularly and thus changes the state of the sensor, causing a new data point to be created.
I just tried something like:

  bat_mydevice:
    value_template: {{ state_attr("device_tracker.mydevice", "battery") | int }}
    unit_of_measurement: '%'
    attribute_templates:
      hour_last_updated:  "{{ now().hour }}"

So even if the sensor value does not change, the hour_last_updated attribute should change hourly, which should solve this whole issue.

Sebastian

Talking to myself here… :wink:
Apparently the above does not work - a change in the attribute’s template does not trigger reevaluation of the template sensor, i.e. when now().hour changes at the top of an hour, nothing happens.
The template sensor attribute keeps its old value - I’m assuming an update still only happens when the sensor’s value changes.

Looking at influxdb shows that no additional data points are created:
(HA does create a data point when restarted, that’s why multiple records for the same value are present)

> select time,entity_id,hour_last_updated,value from "%" WHERE ("entity_id" = 'bat_aeotec_ms6_kitchen') order by time desc limit 5;
name: %
time                entity_id              hour_last_updated value
----                ---------              ----------------- -----
1603808842819112960 bat_aeotec_ms6_kitchen 15                100
1603807856891645952 bat_aeotec_ms6_kitchen                   100
1603628796677989120 bat_aeotec_ms6_kitchen                   100
1603368964196990976 bat_aeotec_ms6_kitchen                   100
1603190444560261888 bat_aeotec_ms6_kitchen                   100

So, unfortunately, adding a templated, regularly changing attribute doesn’t help anything.

Sebastian

And another update: With just released v0.117, the above does work now.
Likely it’s related to bdraco’s change: https://github.com/home-assistant/core/pull/41147

> select time,entity_id,hour_last_updated,value from "%" WHERE (entity_id = 'bat_aeotec_ms6_kitchen') order by time desc limit 3
name: %
time                entity_id              hour_last_updated value
----                ---------              ----------------- -----
1603962000013168128 bat_aeotec_ms6_kitchen 10                100
1603958400019803136 bat_aeotec_ms6_kitchen 9                 100
1603956896818607104 bat_aeotec_ms6_kitchen 8                 100

Sebastian

3 Likes

Right, nice!

Before 117 you had to include a reference to some other sensor, such as sensor.time, and before 115 you could do that with entity_id: sensor.time.

as you noted now() did not trigger a refresh. A bit strange but since it’s fixed now no matter, same function but much clearer now!

This is great Information. Thank you very much - helped me a lot! Would you also know how to update the hour_last_updated e.g every 15 minutes?

You can use

{{ (now().minute / 15) | round(0, 'floor') }}

as the expression which will change every 15 minutes; from 0 to 3 during the course of an hour.

Sebastian

I’m looking for this implementation!

I want this implementation

I’m attempting to use this format to get a template to update every minute, but it doesn’t seem to update the whole template. Any idea what I’m doing wrong here?

  - sensor:
      - name: katniss_since
        state: >
          {{ relative_time(strptime(state_attr('binary_sensor.katniss', 'since'), '%Y-%m-%dT%H:%M:%S%z')) }}
        attributes:
          last_updated: >-
            {{ now() }}

I see the last_updated getting updated, but the rest of the template doesn’t get reevaluiated.

Managed to get this working by using a time trigger.

  - trigger:
      - platform: time_pattern
        minutes: "*"
    sensor:
      - name: katniss_since
        state: >
          {{ relative_time(strptime(state_attr('binary_sensor.katniss', 'since'), '%Y-%m-%dT%H:%M:%S%z')) }}

I tried with

template:
  - sensor:
      - unique_id: power_in_enel
        state: "{{ state_attr('sensor.ensolar_rest_api', 'SCUKW') }}"
        attributes:
          test: "{{ now().minute }}"  # <===== HERE
        device_class: power
        unit_of_measurement: "W"

and also with

template:
  - trigger:   # <===== HERE
      - platform: state
        entity_id:
        - sensor.ensolar_rest_api # <-- this is updating fine
    sensor:
      - unique_id: power_in_enel
        state: "{{ state_attr('sensor.ensolar_rest_api', 'SCUKW') }}"
        device_class: power
        unit_of_measurement: "W"

But none of them achieve the behavior of the force_update.
@sebk-666 how did you manage to make it work? Can you help me?

This should work as a minimal example for a template sensor:

platform: template
sensors:
  foo:
    value_template: {{some template generating a value}}
    attribute_templates:
      hour_last_updated:  "{{ now().hour }}"
1 Like