Template to find the last value that was different

I have a number sensor which has state_class: total_increasing. I want to make a dashboard element which shows the last time the state of the sensor was actually changed. I have found that last_changed and last_updated don’t work for this purpose as these values are also updated when HA restarts as stated in this thread:

I think the best way to do this would be to find the timestamp of the last time the state was not equal to the current state (excluding unavailable state caused by reboots) and return that, but I don’t know how I can do this with either the history_stats integration or a template.

Essentially, if the current state is “2” I suppose I could look through the sensor history for the last time the value was “1”? But how would I do that?

As long as the end result displays the date that the sensors state was changed to its current value, I am open to using any integration or templating. Any pointers in the right direction would be appreciated.

This ended up being easier than expected. Writing it out helped me realise the problem somewhat.

- sensor:
  - unique_id: 1705060543
    name: "Counter"
    state: "{{ states('input_number.counter') }}"
    state_class: total_increasing
    attributes:
      last_increased: "{{ states('sensor.counter_last_increased') }}"
      
- trigger:
    - platform: state
      entity_id: sensor.counter
      from:
  sensor:
    - unique_id: 1705060224
      name: "Counter Last Increased"
      state: "{{ as_timestamp(now().replace(microsecond=0)) }}"

This came from this thread:

I created a trigger based template sensor which updated with the current timestamp when the state of the counter is updated. This is then written to an attribute for easier access. The last_increased sensor only updated on a state change of sensor.counter thanks for the from: null so attribute changes to it shouldn’t cause a loop.

I had to use developer tools to manually set the timestamp of the last change but now this sensor is set up, it will be automatic in the future.

I then used this template to get the amount of time since the timestamp in last_increased:

{{ (as_timestamp(now().replace(microsecond=0)) - states.sensor.incidents.attributes.last_increased) | float | timestamp_custom("%-j days and %-H hours", false)

Which returns 6 days and 1 hours

The hyphens are included per this thread which said they didn’t work to remove leading zeros, but apparently now do?

Hope this helps someone else, my title could be better.

I replaced this with

{% set timestamp = (as_timestamp(now().replace(microsecond=0)) - state_attr('sensor.counter','last_increased')) %}
{{ (timestamp | int // 86400 ) | string }} days and {{ ((timestamp | int % 86400) // 3600) | string }} hours ago

I realised %j would add an extra day on because it starts at 1 and not 0. This outputs an accurate time.