Add force_update support to template sensor

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

Is there a way to make a sensor update every 15 seconds?

I’m trying something like this but it doesn’t seem to be working:

sensor:
  - platform: template
    sensors:
      airtemp_hack:
        friendly_name: "AirTemp Hack"
        value_template: "{{ states('sensor.AirTemperature') }}"
        attribute_templates:
          update_now: "{{ (now()).second / 15 | round(0, 'floor') }}"

It only updates when the value of sensor.AirTemperature changes. I want it to update and store it in airtemp_hack every single time.

You probably need to add a set of parentheses for the update_now template to make it render to 0,1,2,3:

update_now: "{{ ( (now()).second / 15 ) | round(0, 'floor') }}"

Not sure if this solves the issue though…

Sebastian

I tried that. It didn’t work. I also tried this:

sensor:
  - platform: template
    sensors:
      airtemp_hack:
        friendly_name: "AirTemp Hack"
        value_template: "{{ states('sensor.AirTemperature') }}"
        attribute_templates:
          update_now: "{{ ( now().second / 15 ) | round(0, 'floor') }}"

As a sanity check I tried now().minute by itself:

update_now: "{{ now().minute }}"

This consistently updates once a minute and sets the value of update_now to the current minute, eg at 10:12:00 I get 12 back with my value.
That seems right.

Next I’m trying now().second by itself:

update_now: "{{ now().second }}"

This always returns 0.00 for update_now when I do see updates, but as far as I can tell it only updates when the values changes, which is no different from usual.
So it seems like now().second is broken as it doesn’t actually report the second.

This probably means you can’t get second level precision in updates using this trick.

sebk-666 What is the significance of the 0,1,2,3 sequence you typed? I still am not quite clear why it works when you divide now().minute / 15 to make it happens every 15 minutes.

The intention of the

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

template is to change its value every 15 seconds, counting from 0 (seconds :00 to :14) up to 3 (seconds :45 to :59).

Without the additional parentheses, the template does not divide the current second value by 15 and round it down to the nearest integer (0, 1, 2 or 3).
Instead it is dividing the current seconds value by the result of “15, rounded down to zero decimal digits” - which is still 15.
The result is that the template is updating every second with what’s mostly floating point numbers.
Go, try it out in the template-editor in the Dev Tools section.
Adding the parentheses will cause the result of the “now.seconds()/15” division to be rounded and floored as expected.

Now, regarding your issue - there could be a possibility that templates are not rendered more often than once per minute which might explain what you’re seeing.
But I’m not that familiar with the template internals of HA.

Edit: Yeah, it looks like this is the cause. Check out the “Rate limiting updates” section here:

Sebastian

So if you have a sequence that goes 0,1,2,3, is there code somewhere in the system that updates when the sequence is at 0?

Also the doc you posted has a few interesting notes on changing state.

In the below example, re-renders are limited to once per minute because we iterate over all available entities:

template:
  - binary_sensor:
      - name: "Has Unavailable States"
        state: "{{ states | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | count }}"

In the below example, re-renders are limited to once per second because we iterate over all entities in a single domain (sensor):

template:
  - binary_sensor:
      - name: "Has Unavailable States"
        state: "{{ states.sensor | selectattr('state', 'in', ['unavailable', 'unknown', 'none']) | list | count }}"

Those could be interesting directions to explore.

It seems like some people claim they get this sort of thing working with Trigger-based Template sensors with a Time Pattern Trigger so I will probably try that next as that is not beholden to the rate limiting.

The template-editor is really useful, thanks for all the help.

This still works in 2023 and is needed for certain uses of the statistics sensor. For example, if your statistics sensor is monitoring another source sensor it can result in the “unknown” value for the statistics sensor. What triggers this “unknown” state is if the source sensor value does not change for lengthy periods. The HA database is not updated until the value changes, meaning the statistics sensor has no values to work from within the required time period.
The workaround is simple, you just add a time-based attribute to your source sensor. The syntax has changed slightly since the earlier comments in this thread, here is an example that works today on HA 2023.2.5:

 - sensor:
      - name: "Desired Charge Current"
        unit_of_measurement: "A"
        state_class: "measurement"
        state: >
            {{ charge_current }}
        attributes:
            minute_counter: "{{ now().minute }}"

This Github issue was raised for the statistics problem I mention: Statistics sensor doesn't handle zero values correctly · Issue #67627 · home-assistant/core · GitHub

3 Likes

I came across this topic when setting up a statistic sensor.
I want to filter out some odd values from a power sensor that from time to time will measure zero.
I’m planning to use the max statistics, so that zero is never considered if another value was taken.
But, if the sensor stays at zero for a long time that means it is a valid value so I want to keep it.
I would normally force that with the max_age. But then, I might stumble upon this issue where it will appear as ‘unkown’ if it doesn’t change for long.

While adding a force_update is one option, I think it would generalize better if instead theres an:
‘unkown_value_template’ entry on the configuration so we can define what value should the statistics sensor display when it enters in the ‘unkown’ scenario. For OP that can be the latest state value of an entity, for other cases we could force to zero.

Voted.

Example of what i want to filter:
First chart, examples of what i want to filter (high frequency zero’s skips).
Second chart, examples of what shuold be kept (long staying zero values):

For me this was the solution:
I have added a small zero symmetric “noise” to the not changing value, so the integral of the value will not change but everything is updating in each 15 seconds:

template:
  - trigger:
      - platform: time_pattern
        seconds: "/15"
    sensor:
      - name: "Device power periodic"
        unit_of_measurement: "W"     
        state: "{{ (states('sensor.device_plug_power')|float) + ((((now().second / 15) | float) - 1.5) / 1000.0) }}"
        state_class: measurement
        device_class: power

Thanks for this. Here’s a stupid question: How do I create two more? I’ve tried with and without multiple “templates” and with and without multiple "sensor: " to no avail…

This was the solution:

template:
    - trigger:
        - platform: time_pattern
          seconds: "/15"
      sensor:
        - name: "Indoor_Derivative"
          unit_of_measurement: "gal"     
          state: "{{ (states('sensor.inside_water_meter_consumption')|float) + ((((now().second / 15) | float) - 1.5) / 1000) }}"
          state_class: measurement
#          device_class: sensor

        - name: "Outdoor_Derivative"
          unit_of_measurement: "gal"
          state: "{{ (states('sensor.outside_water_meter_consumption')|float) + ((((now().second / 15) | float) - 1.5) / 1000) }}"
          state_class: measurement
#          device_class: sensor

        - name: "Gas_Derivative"
          unit_of_measurement: "ft³"
          state: "{{ (states('sensor.gas_meter_consumption')|float) + ((((now().second / 15) | float) - 1.5) / 1000) }}"
          state_class: measurement
#          device_class: sensor

        - name: "Indoor Water Cost"
          unit_of_measurement: "$"
          state: "{{ (states('sensor.indoor_water_month')|float) * 15.66}}"
          state_class: total_increasing

        - name: "Outdoor Water Cost"
          unit_of_measurement: "$"
          state: "{{ (states('sensor.outdoor_water_month')|float) * 5.02}}"
          state_class: total_increasing

I believe the problem was “device_class: power” is not a valid device class. That said, there were no errors generated when I went to restart HA. Once I commented this out everything works.

        attributes:
            minute_counter: "{{ now().minute }}"

Thank you - this fixed an issue I’ve been fighting all weekend trying to figure out why the battery I’m charging kept showing 53W (correct) for a while, and then after the average-interval went to “unknown” in spite of the input sensor still reading a correct 53W input.

Maddening!

1 Like

this worked for me on 2024.1.1