Time of last state change of entity

Hello,

How can I get last state change of entity in AD?

My goal is to check if last the state change of entity was changed more than 2h (for example).

you can listen to a state change with listen_state
then in the callback you can put a run_in for 2 hours that will notify when the run_in time is over.
canceling the running run_in every time a new state change happens, makes that it will only end if the state didnt change for 2 hours.

pseudo code:


def initialise(...):
  self.handler = None
  self.listen_state(self.callbackname,"entity.name")

def callbackname(self,...):
  if self.handler != None:
    self.cancel_timer(self.handler)
  self.handler = self.run_in(self.secondcallback,2*60*60)

def secondcallback(self,...):
  self.notify("some message")

Thank you for answer :wink:

It looks bit complicated (for me).

Iā€™m trying to replicate regular hass automation rule (pseudo code):

trigger:
    platform: state
    entity_id: sensor.people_at_home
    from: 'false'
    to: 'true'
conditions: and
  conditions:
    - condition: state
      entity_id: input_boolean.vacation_mode
      state: 'on'
      for:
        hours: 2
action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.vacation_mode

Soā€¦ is there a chance to get some sort of ā€˜last state changeā€™ via get_state() ?

Something like (pseudo idea):
self.get_state('input_boolean.vacation_mode', attribute=?!?)

Greetings, M

If you only want to trigger the callback if a state is the same for 2 hours, you need the duration parameter to listen state

  self.listen_state(self.callbackname,"entity.name", duration=2*60*60)

and just to complete, if you want the callback when the state is on for 2 hours,

  self.listen_state(self.callbackname,"entity.name", new="on", duration=2*60*60)

@macle,

You can use this for example self.entities.media_player.kodi.last_changed

Regards

Thats interesting idea. Thank you.

In my case, my entity:
self.entities.input_boolean.vacation_mode.last_changed

returns
2018-08-02T15:04:43.936948+00:00

But how can I compare with current time in AD??

Greetings, M

Like this:

datetime.now().timestamp() - self.convert_utc(self.entities.input_boolean.vacation_mode.last_changed).timestamp()

Since you looking for 2 hours, check if its more than 2 * 60 * 60 which is 7200

Regards

EDIT:

First add from datetime import datetime, time to your code before running the above

3 Likes

@Odianosen25: It works perfectly. Thank you!

I successfully made another AppDaemon automation! :wink:

Greetings, M

2 Likes

You welcome boss :facepunch:t5:

How would you substitute ā€˜input_boolean.vacation_modeā€™ with some entity from the configuration?
I tried to use

datetime.now().timestamp() - self.convert_utc(self.entities.**self.args["door"].**last_changed).timestamp()

and it did not work?

I think it should be

datetime.now().timestamp() - self.convert_utc(self.entities.self.args["door"].last_changed).timestamp()

i dont think that would work either but i am not sure.

i would try

datetime.now().timestamp() - self.convert_utc(self.entities[self.args["door"]][last_changed]).timestamp()

Yeah @ReneTode is right and thanks for that @ReneTode, not sure what I was thinking when I wrote that. @anilet, apologies for the wrong answer, and that is the right way to do it. self.entities is essentially a dictionary object of all entities in HA. So one can access everything as just accessing a regular dictionary

1 Like

Thank you @ReneTode and @Odianosen25, Will try later.

2 Likes

Finally I had some time to try this and unfortunately did not work

newtime = datetime.now().timestamp() - self.convert_utc(self.entities[self.args["door"]][last_changed]).timestamp()
KeyError: 'binary_sensor.master_bath_door'

when I do

print(self.entities)
{}

Am I missing something?

probably. :wink:
and i have no experience with this way of working, because i still use get_state

self.entities[self.args["door"]][last_changed]

should probably be:

self.entities.[self.args["door"]][attributes][last_changed]

Good pointer

newtime2 = datetime.now().timestamp() - self.convert_utc(self.get_state(self.args["door"], attribute = 'last_changed')).timestamp()

is working
I donā€™t know why the entities route is not.

did you try the last one i showed you?

by the way its better to use self.log() instead of print()

I did try and it did not work, you can see from above print(self.entities) prints out an empty dictionary.
Yes I know about the log() and I use it extensively. This is just a quick test to see if self.entities has anything in it.

i did try it.
self.entities returns empty, but self.entities.light.some_light did return state attributes, etc from the entity

the reason why it didnt work in your case is because you need to split up the component and entity before you retrieve.

and last_changed should have been quoted.

so it would work like:

device, entity = self.split_entity(self.args["door"])
last_changed = self.entities[device][entity]["last_changed"]