Automation: how to re-check state of the same entity that triggered it

I want to create an automation that:

  • Gets triggered by one of several “smart” cameras (“Person detected”)
  • Take some actions
  • Wait a few seconds
  • Now recheck the same camera entity and see if the state has changed
  • And if the same state persists, take more actions.

The part I can’t figure out is how to re-check the same entity after the pause.
I know how to get the name of the entity with trigger.to_state.name; but how do I check the state of that entity? I.e. how do I get the entity object and test its state again?

(Yes, I could create a separate automation for each camera, which would avoid this complication. That kinda sucks and I’d like to do this in a more elegant way if possible.)

Very doable! Use a delay for the seconds. In the visual editor, add action “Wait for time to pass (delay)” then add action select “Building Blocks”, Select “condition” select the entity you want to check before proceeding.

You don’t need to, you can consolidate them into one automation

Here is an example of use triggers for multiple devices in one automation.

alias: Turn door notification
description: 
trigger:
  - platform: state
    entity_id:
      - input_boolean._door_8
      - input_boolean._door_9
      - input_boolean._door_10
      - input_boolean._door_11
      - input_boolean._door_12
    from: "on"
    to: "off"
condition: []
action:
  - if:
      - condition: state
        entity_id: input_boolean._door_8
        state: "off"
    then:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean._door_8
        data: {}
  - if:
      - condition: state
        entity_id: input_boolean._door_9
        state: "off"
    then:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean._door_9
        data: {}
  - if:
      - condition: state
        entity_id: input_boolean._door_10
        state: "off"
    then:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean._door_10
        data: {}
  - if:
      - condition: state
        entity_id: input_boolean._door_11
        state: "off"
    then:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean._door_11
        data: {}
  - if:
      - condition: state
        entity_id: input_boolean._door_12
        state: ""
    then: []
  - service: input_boolean.turn_on
    target:
      entity_id: input_boolean._door_12
    data: {}
mode: single

type or paste code here

Hi @Rodrick thanks!
Yes I was pondering that I could use input booleans to leave a “trail of breadcrumbs” from the initial trigger to the later re-check of the state. That would work… but it’s not very elegant. In the Actions part of the automation, I’ll have to re-trace a tree of IF/THEN statements to find out which boolean was set, then hard-code it to check the related entity again.

I was hoping for a more elegant, programmatic way to identify which entity was the one that triggered the automation, and hold on to that entity object in a variable, and then use that variable to know which entity to re-check in the action conditions.

OR… if I can’t hold on to the object for later: when I get to the Action conditions, can I use trigger.to_state.name to re-identify the entity object, and then test that object’s state? I can’t find any documentation that tells how to get from the entity name to the entity object, and test its state.

One of the cool things about HA is, there are always different ways to achieve the same goal. :slight_smile:

I would do it different to post above, just use what you find better or where you’re more comfortable with. :slight_smile:

In the action block of automations you can always check things, by inserting a condition. There is a nice example in the docs:

automation:
- alias: "Office at evening"
  trigger:
    - platform: state
      entity_id: sensor.office_occupancy
      to: "on"
  action:
    - service: notify.notify
      data:
        message: "Testing conditional actions"
    - condition: or
      conditions:
        - condition: numeric_state
          entity_id: sun.sun
          attribute: elevation
          below: 4
        - condition: state
          entity_id: sensor.office_illuminance
          below: 10
    - service: scene.turn_on
      target:
        entity_id: scene.office_at_evening

You can combine multiple service calls and conditions in a single action, and they will be processed in the order you put them in. If the result of a condition is false, the action will stop there so any service calls after that condition will not be executed.

See here: https://www.home-assistant.io/docs/automation/action/
Or here: https://www.home-assistant.io/docs/scripts/#test-a-condition

If you need more control, eg. you want the automation to continue after that check fails, you can use this:

Both should give you exactly what you want. :+1:

For future reference, it would be better, if you’d post the code of your automation, so people can copy and edit it. Makes it easier for us to help, but it’s not a requirement! Thanks! :slight_smile:

EDIT: I forgot to mention, what you check for in your automation is the state of trigger.to_state.state or trigger.from_state.state. :slight_smile:

@paddy0174 oooh, that might be what I needed !?

So, if I get an initial trigger, then pause for a bit, then in the Actions I set a condition to check trigger.to_state.state,
Does HA recheck the state of that entity at that point?
Or does HA give me the state of that entity as it was captured at trigger time?

To accomplish what I want, I need it to recheck after the pause.

(Yes I understand about sharing my code… I haven’t written it yet.)

The check is exactly at that time, when the condition is run in the automation (does that sentence makes sense? :wink: ).

Exactly! :slight_smile:

But, it depends on what you want to check for, if it is a simple condition or if a choose would be better. :slight_smile:

Please, setup some code, so we can copy and edit it. Otherwise I need to setup an automation only for you. :wink: :slight_smile: Just do the automation as far as you get, leaving out the condition bits and such. It just makes it so much easier to add to that, the entity names are there, all these things. Thanks! :slight_smile:

OK I think I finally found part of the answer here:

I think I can use a template as my condition, as I did below. I’ll test this.
Meanwhile, this raises a second problem. How do I take the snapshot from the appropriate camera? How do I turn the trigger.entity_id into a Device that the Snapshot action can use?

alias: test conditional snapshot
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.back_porch_cam_person
      - binary_sensor.pool_cam_person
      - binary_sensor.driveway_person
      - binary_sensor.front_cam_person
    to: "on"
condition: []
action:
  - service: camera.snapshot
    metadata: {}
    data: {}
    target:
      device_id: {{ my device id }}
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - condition: "{{ trigger.entity_id.state }} = 'on' "
  - service: notify.notify
    metadata: {}
    data:
      message: test
      title: test
      data: /mysnapshot
mode: single

I believe what you want is this:

  - condition: "{{ is_state(trigger.entity_id, 'on') }}"

FWIW, this is not a valid template:

"{{ trigger.entity_id.state }} = 'on' "
    target:
      device_id: "{{ device_id(trigger.entity_id) }}"

Reference

Templating - Devices

The example is for using if-then, not for just for booleans

OK I tested with this condition statement in the Automation’s Actions section, and it works. And it definitely retests the state of the entity; it does not simply give you the state from the time of the trigger. (I verified this by extending the time of the Wait statement, and sending myself alerts with the state before and after the Wait.)

- condition: "{{ is_state(trigger.entity_id, 'on') }}"

Great.
So, my one remaining problem is: how can I tell the Snapshot command which camera to take a snap from? I.e. how can I turn trigger.entity_id into a Camera device_id ?

(Again, I see how I could do this the ugly way, by setting up an input boolean for each camera, and turning them on and off at Trigger time. I’m looking for a more elegant answer where I don’t need to have any Camera identifiers hard coded, but can identify the camera device using the trigger’s entity.)

Edit: I figured it out!!
Finishing up and will post the final code here in a few.

Super grateful for the responses and support.
Here’s the final code, and it works great!

alias: Send conditional snapshot
description: Receive a camera alert. Take a snapshot. Recheck after 10s and see if the alert is still on. Send email with snapshot.
trigger:
  - platform: state
    entity_id:
      - binary_sensor.back_porch_cam_person
      - binary_sensor.pool_cam_person
      - binary_sensor.driveway_person
      - binary_sensor.front_cam_person
      - binary_sensor.pool_cam_animal
      - binary_sensor.front_cam_animal
      - binary_sensor.driveway_animal
      - binary_sensor.back_porch_cam_animal
    to: "on"
condition: []
action:
  - service: camera.snapshot
    metadata: {}
    data:
      filename: /config/www/camera_snapshots/{{ device_id(trigger.entity_id) }}_snapshot.jpg
    target:
      device_id: "{{ device_id(trigger.entity_id) }}"
  - delay:
      hours: 0
      minutes: 0
      seconds: 10
      milliseconds: 0
  - condition: "{{ is_state(trigger.entity_id, 'on') }}"
  - service: notify.gmail_notification
    data:
      title: Camera alert {{trigger.to_state.attributes.friendly_name }}
      message: Alert persisted for over 10s. Snapshot attached.
      data:
        images:
          - /config/www/camera_snapshots/{{ device_id(trigger.entity_id) }}_snapshot.jpg
mode: single
1 Like

Two key lessons learned for me:

  1. This is how you get the device related to a triggering entity in an automation:
{{ device_id(trigger.entity_id) }}
  1. This is how you re-check the state of the same entity that triggered your automation, later in the automation code (e.g. after a pause, or after other actions are taken), without explicitly coding the entity ID:
condition: "{{ is_state(trigger.entity_id, 'on') }}"

Great you got it solved! :slight_smile:

Just one thing: wouldn’t it make more sense to run this automation not in single but rather in parallel or queued mode? Right now, when a camera is in that 10s delay, another camera can’t react, as it will error out (with a log entry, but without pics).

You’re welcome!

Please consider marking my post above with the Solution tag. It will automatically place a check-mark next to the topic’s title which indicates to others that the topic has been solved. It also helps other users find answers to similar questions.

For more information about the Solution tag, pleade refer to the FAQ.