Check an entity's previous state

Here’s a problem/use-case I run into every weeks when trying to automate things:

I need the previous state of an entity.

One example:

“If device_tracker.abc changes to “home” AND was “not_home” for the —last— 10 minutes”

It seems to be almost IMPOSSIBLE. And no, the “for: 10 minutes” is no good here, because I don’t want to check and wait until the CURRENT state is “home” for 10 minutes, but want to check for the !past! state.

To make matters worse, I can NOT use “as_timestamp(states.device_tracker.abc.last_changed)” because the entity is updated regularly - without a status change - and this behavior cannot be influenced.

Is there anything possible via template? I don’t want any ugly workarounds such as additional template entities, accessing the database via SQL sensor or similar - but I am generally interested in any functional (smart) solution for this recurring requirement. Thank you for your solutions :+1:


edit: on a second search attempt I found similar topics with either no or no real smart solutions. It would be so great to have a native template function for this (do I hear a feature request here, do I? :smiley: ).

1 Like

Can you clarify what you mean with the above statement?

Of course.

My entity from aboves example will stay home, even it gets updated (not in terms of “a new state” but of “confirm the current state”) every 30 to 60 seconds. So the last_changed AND last_updated get modified, even there’s no state change.

grafik

That seems like you have either a faulty device, unstable network, or a faulty integration. As I understand it, the last_changed property should only change when the state changes. Check the log book to see if the entity is going “unavailable” or “unknown” for brief intervals.

If the device, network, or integration are malfunctioning, there isn’t going to be a way to solve your issue without using an auxiliary entity like a History Stats sensor, Trigger-based template sensor, etc.

I’m not sure if the integration is doing something wrong here. I thought this is the way it works. So for the current example from above:

it’s a device_tracker entity provided via MQTT integration and originally generated by OMG (https://docs.openmqttgateway.com). Do you think this might be a bug @DigiH?

(because usually I would just try to use this like I do at other places in a similar way:

{{
   states('device_tracker.abc') == 'home' and as_timestamp(now()) - as_timestamp(states.device_tracker.abc.last_updated) <= 600
}}

)

But TBH the perfect solution would simply be a native function to check the previous state of an entity like was_state('entity.name','home','60') which checks if the entity was in state “home” within the last 60 seconds.

Everything else out there currently is a hacky workaround at best, hard to read and understand looking at it a few months after being created :frowning:

There is of course trigger.from_state object in automations, but it does not help to see how long if the timestamps in it are not reflecting what you wanted to know.

The reason the timestamps are equal is likely because the state object has changed - namely the gps coordinates in the attributes, even though those still within the home zone.

Because what you need can be done using an extra entity (that you do not want) I do doubt that something will be done to add the functionality you’re looking for. Adding entities to provide information you miss is basically the core of how Home Assistant tackles any problem.

That should not change the last_changed property. A change of state will update the last_updated, but a change to an attribute shouldn’t affect last_changed.

image

1 Like

I may be misunderstanding this, but wouldn’t this be handled by an automation like this;

Trigger :“not_home” for 10m
followed by a “wait for trigger” state = “home”

3 Likes

That’s not really addressing the same condition. The desired condition, as I understand it, is “The device tracker was ‘not home’ for at least 10 minutes immediately prior to coming 'home”… not “The device tracker was ‘not home’ for 10 minutes at some time prior to it coming home”. With additional triggers to cancel the automation if other zones are entered, it might be made to serve OP’s purpose. However, it would hold the automation in a waiting state for an undetermined amount of time, which has it’s own risks in regards to reliability.

Yes @Didgeridrew is right, that sounds similar in the first place (pretty close) but looks at the actual scenario from the other side - which as already mentioned has its unwanted side effects (simplest one: not able to survive a HA restart and I don’t want helper entities for every simple stuff HA is not capable of out of the box).

Still looking for the holy grail here…

…BUT until that is found… I might give this a try (not_home for XX minutes first, then wait until home) and see if it works in reality or how often it fails.

@DigiH @1technophile worth reporting the OMG provided device_tracker entities not respecting HA „last_changed“ rules as a bug?
And please note: while using several OMGs/TheengsGateways, there’s only a single one close enough to the particular device (because I know that‘d be your first question :slight_smile: ).

I use a trigger based template to capture the current and past state of another sensor. Maybe this or something similar would be applicable for you?

  - trigger:
    - platform: state
      entity_id: counter.ceiling_fan_active_counter
    sensor:
      - name: Ceiling Fan Active Counter Last Updated
        unique_id: ceiling_fan_active_counter_last_update
        state: >
          {{ now() }}
        attributes:
          old_state: "{{ trigger.from_state.state }}"
          new_state: "{{ trigger.to_state.state }}"
          prev_time: "{{ this.state }}"

The state reports the time the source sensor state changed. The attributes report the old state, new state, and the time of the previous state change.

1 Like

What would be the bug, I’m not sure I get the OMG issue here.

Have a look at post #4 Check an entity's previous state - #4 by Didgeridrew

@e-raser this is what you are seeing ?

Kind of:

The interesting thing (and the point here) is: even when the state does NOT change (home → home → home → home → …) the HA attributes get updated („last_changed“ e.g.).

What is the corresponding event when there is a change of “last_changed”

How to precisely get this information? Nothing in /developer-tools/event when listening to state_changed event (obviously, that’s only for changes so “A → B”). Where should I look at?

Edit:
I could catch one (listening to state_changed) of a fitness tracker:

event_type: state_changed
data:
  entity_id: device_tracker.abc
  old_state:
    entity_id: device_tracker.abc
    state: home
    attributes:
      source_type: gps
      icon: mdi:watch-variant
      friendly_name: ABC
    last_changed: "2024-06-08T18:28:37.618289+00:00"
    last_updated: "2024-06-08T18:28:37.618289+00:00"
    context:
      id: 01HZWHR4KJX25MA3YP8CAJKCB1
      parent_id: null
      user_id: null
  new_state:
    entity_id: device_tracker.abc
    state: home
    attributes:
      source_type: gps
      icon: mdi:watch-variant
      friendly_name: ABC
    last_changed: "2024-06-08T18:30:10.995887+00:00"
    last_updated: "2024-06-08T18:30:10.995887+00:00"
    context:
      id: 01HZWHTZSKJP1E8PCGN6VFDWC4
      parent_id: null
      user_id: null
origin: LOCAL
time_fired: "2024-06-08T18:30:10.995887+00:00"
context:
  id: 01HZWHTZSKJP1E8PCGN6VFDWC4
  parent_id: null
  user_id: null

Please note the state kept “home” during that time.