State condition after change + some time in previous state

tldr: I want to execute an action if some state changes from off to on, but only if it has been off for more than a minute. Is this possible and what would be the best approach?

I have an LG OLED webos tv which automatically runs a compensation cycle after every few hours of playing. This cycle runs instantly when the tv is turned off (but is not actually visible to the user). Due to a bug (?) in the firmware, the tv API says it’s “on” while the compensation cycle is running.

A recent HA update seems to have made a change to how (on/off) state changes are handled. If you use an action to change the state of something, the internal state is modified instantly instead of waiting for the component to update it.

I have a bedtime routine that shuts down the tv, receiver and lights. When I trigger this, the internal state of the tv is changed to “off” instantly, but if the compensation cycle runs on the tv, the next time the component checks the state of the tv, it changes back to “on”.

This change from “off” to “on” triggers my “watching tv” script that turns on my receiver, partly negating my bedtime routine. I want to prevent this from happening by only triggering the “watching tv” script when the tv has been off for some time. Is this possible and what would be the best way to do this?

2 Likes

This may not be be best approach, but you could make an input_boolean that gets turned on when the tv is turned off, then use its state with a time value as a condition in your watching tv automation. ie the boolean needs to have been on for 1 minute in order for the watching tv automation to fire.

Try a conditional template

if {{ relative_time(states.media_player.lg.last_updated) }} is greater than 30 mins and its after before your bedtime.

There is a built in function for that. Just use “for”.

# If given, will trigger when condition has been for X time.
for:
  hours: 1
  minutes: 10
  seconds: 5

The for statement would work in the turn off automation, but not in the turn on automation, same with the template, what should work is to set a delay in your turn off script, then either set a condition in your turn on script that says the other automation is not running, or use an input_boolean that you turn on at the beginning of your script and off at the end.

This does not seem to have been resolved, and I’m interested in it, too.

Seems like what the OP wants is to be able to use a condition such that the previous state has been active for a specified time.

RobDYI said “if {{ relative_time(state.media_player.lg.last.updated) }} is greater than 30 mins”

This is close but not quite what is desired.

In this discussion someone says that the previous state can be accessed as a condition like this

condition:
    platform: template
    value_template: '{{ trigger.to_state.state <> trigger.from_state.state }}'

So, in the current request, I imagine it would look something like this, though I’m not sure of the exact syntax

condition:
    platform: template
    value_template: '{{ relative_time(trigger.from_state.updated) > 30 minutes }}'

Any pointers on if this will actually work this way, and the exact syntax would be much appreciated.

P.S.

My specific use case is to check a binary sensor “is_almost_home” which is updated by a narrow rectangular geo-fence that covers the road in front of my house for a few hundred meters. To “debounce” this signal, I want to only trigger if the “off” state has been off for some threshold before becoming ‘on’ again. E.G. I actually left the house and have been gone for several minutes vs a spurious GPS update showing me outside of that bounding box for only one update cycle, then upon returning the garage door opens automatically.

Any news on this? Did anybody resolve?

What I would like to do is, turn on my entrance light when I’m detected home but only if I haven’t been at home for one hour or more.
In my case I’m using my router as a presence detection and the mobile phones as the tracked devices. They get disconnected from time to time. So to avoid turning on the light randomly I must be away for more than an hour.

@vontrapp did you get your code to work?

Regards, Jure

2 Likes

Here’s what I’m thinking about implementing:

  • Have a boolean called “leaving_home” that is initially off
  • Automation 1: turn on “leaving_home” when zone changes to anything but home
  • Automation 2: trigger: arriving home, condition: “leaving_home.last_changed” > 15 minutes, action: turn on lights
  • Automation 3: trigger: arriving home, action: delay 10 sec then turn off “leaving home”

Thinking it through:

  • If you leave for a short period, including a spurious GPS reading, “leaving_home” will turn on, but back in the Home zone the last_changed will be too short, so nothing will happen with the lights, and “leaving_home” will be turned off.
  • If you’re away from the Home zone for more than 10 minutes, coming back will result in the lights turning on.
  • The delay in Automation 3 is intended to give Automation 2 long enough to process the condition before the boolean gets changed again. 10 seconds should be WAY more than enough.

Does this seem reasonable?

juuurc, not that code/idea, no.

wixoff, I’ve tried this now and so far (2 days) it’s working great! thanks

- alias: "Garage open door"
  trigger:
    - platform: state
      entity_id: device_tracker.vontrapp_tardis
      to: "garage"
    - platform: state
      entity_id: device_tracker.vontrapp_tardis
      to: "home"
  condition:
    condition: and
    conditions:
      - condition: time
        after: '06:00:00'
        before: '23:00:00'
      # been closed for more than 5 minutes
      - condition: state
        entity_id: binary_sensor.garage_closed
        state: "on"
      - condition: template
        value_template: '{{ as_timestamp(states.binary_sensor.garage_closed.last_changed) + 300 < as_timestamp(now()) }}'
      # been away for more than 15 minutes
      - condition: state
        entity_id: input_boolean.tardis_away
        state: "on"
      - condition: template
        value_template: '{{ as_timestamp(states.input_boolean.tardis_away.last_changed) + 900 < as_timestamp(now()) }}'
  action:
    - service: cover.open_cover
      entity_id: cover.garage
    - service: mqtt.publish
      data:
        topic: "garage/auto"
        payload: "open"

# reduce false triggers
- alias: "Garage Change tardis to away"
  trigger:
    - platform: state
      entity_id: device_tracker.vontrapp_tardis
      from: "home"
  action:
    - service: input_boolean.turn_on
      entity_id: input_boolean.tardis_away
- alias: "Garage Tardis reset"
  trigger:
    - platform: state
      entity_id: device_tracker.vontrapp_tardis
      to: "home"
      for:
        seconds: 10
  action:
    - service: input_boolean.turn_off
      entity_id: input_boolean.tardis_away
2 Likes