#How to guarantee latest value is used in the automation

1 messages · Page 1 of 1 (latest)

thin jay
#

I have a template sensor that stores the number of doors/windows currently open in the home. This is for external doors only.
I have an automation, that is triggered by the main entrance doors and the condition that checks if number of open doors is more than 1. Idea is to get a warning if any other door beside the entrance door is open when I try to leave the home.

Template sensor for number of doors open includes the entrance door itself. So if the entrance is open, value is more than 0.

- sensor:
    - unique_id: d1c3df62-ddd4-4139-ad5d-1ecec8f94bcc
      name: "Number of doors and windows open"
      state: >
        {{ 
          states.binary_sensor
            | selectattr('entity_id', 'search', '(door|window).*_contact')
            | selectattr('state', '==', 'on')
            | list
            | count
        }}
      state_class: total

Then, I have an automation like so, that is triggered when I open the main door:

alias: Notify user about open doors when leaving
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.entrance_door_contact
    to: "on"
    from: "off"
conditions:
  - condition: numeric_state
    entity_id: sensor.number_of_doors_and_windows_open
    above: 1
  - condition: state
    entity_id: binary_sensor.entrance_motion
    state: "on"
actions:
  - action: notify.alexa_media_echo_spot
    data:
      message: "\"More than one door is open"
mode: single

The condition is that number of doors or windows open must be above 1 (including the entrance door itself).
At the time of writing this message, it is 10:00 AM local time. Automation says it was last triggered 14h ago (see picture), while when I open the automation, it says triggered 08:30 - how is that 14hours ago?

Now the final question - how do I guarantee that HA will use the template sensor value in the conditions part with the latest value, so sensor must be re-evaluated before automation is triggered.

#

Continuing here, I wasn't able to write everything (char limit).

The history shows that 2 doors were open (entrance + another one) at the time of automation trigger. Yet, automation didn't go through.

  • Did the automation use the template sensor value before evaluation?
  • Shall I skip conditions and use the if in the actions with a delay block?
versed lion
#

As both the automation and the template will have the same trigger (the door opening), I do expect a race condition as which is updated first. So it is possible the automation is fired before the template sensor is updated. You could try a 1s delay in the automation. Probably 100ms will already be enough but just make it long to start with to see if that fixes it.

As for the 14h, when a trigger is fired but the automation condition was not true, I think it will not count as "automation ran" but it will make a trace for you.

graceful oak
# thin jay I have a template sensor that stores the number of doors/windows currently open ...

At the time of writing this message, it is 10:00 AM local time. Automation says it was last triggered 14h ago (see picture), while when I open the automation, it says triggered 08:30 - how is that 14hours ago?
The last triggered attribute (and timestamp on the automation GUI overview) shows the last time it reached the action part of the automation. If it fails on a condition, it won't be counted as triggered. The traces also show the times it failed on a condition.

#

Oh wait, I should have read the 2nd paragraph of @versed lion's post as well 🙂

#

And I think the first paragraph form @versed lion is also correct. Instead of adding a delay to the automation (which also would require you to move the condition checking on the template sensor to the actions part) you could also add a short for period to the trigger. Something like this

  - trigger: state
    entity_id:
      - binary_sensor.entrance_door_contact
    to: "on"
    from: "off"
    for:
      seconds: 0.2
#

Not sure if the GUI accepts periods shorter than a second though

thin jay
#

thanks to both of you. It makes a lot of sense. The UI complains but it accepts the value 🙂

dull pasture
#

HOw about switching gears.
MAking the trigger of the automation: Everytime your template sensors changes.

#

So that you avoid the race condition in the first place

graceful oak
#

That could also work, however it might give unwanted triggers if the door sensor has a large timeout, and other doors are openend within the timeout

thin jay
#

That's the possible way too, and then the actual sensor's state is checked in a condition. It is assumed that state of the sensor is set before template fires.

delicate laurel
#

@thin jay FYI I closed the issue as this is by design. Template entities are throttled when using states object and states.<domain> objects.

#

using states, your template will be throttled to at most 1 update per minute

#

using states.<domain> your template will be throttled to at most 1 update per second

#

you are running into states.<domain> throttling.

#

If you change your template entity to:

- sensor:
    - unique_id: d1c3df62-ddd4-4139-ad5d-1ecec8f94bcc
      name: "Number of doors and windows open"
      variables:
        entity_ids: >
          {{ states.binary_sensor | map(attribute='entity_id') | select('search', '(door|window).*_contact') | list }}
      state: >
        {{ 
          entity_ids | selectattr('state', '==', 'on')
                     | list
                     | count
        }}
      state_class: total

You won't be throttled, however the list will only be populated at startup and template reload.

#

I'm sure @graceful oak can come up with something that would work live too

versed lion
#

You could exclude the entrance_door from the template sensor. That way you could just check for >0 without waiting.

thin jay
#

thanks @delicate laurel . based on Your comment, it means that even if I use the for: 0.2 (small delay) in the trigger, it can still happen I miss the update before I continue. So best is to create another template sensor counting all doors excluding the entrance door and do what @versed lion said.

delicate laurel
#

The throttle can happen whenever though

#

so if you have 2 doors/contact sensors that update within the same second, you will only see one of the updates.

#

it's really best to just move away from states.<domain> if you can.

thin jay
#

using variable

delicate laurel
#

There's many things you could do

thin jay
#

let me ask You differently - what's the way you'd tackle this problem?

delicate laurel
#

you can use variables, labels, hardcode

#

I use labels

thin jay
#

thanks, I'll learn about labels

#

talking about this right?

graceful oak
#

You could also group them in a binary sensor group and expand the group, but labels will be a good approach as well

delicate laurel
graceful oak
#

Probably, but not sure how that would help in this case

delicate laurel
graceful oak
#

Ah, right

#
- sensor:
    - unique_id: d1c3df62-ddd4-4139-ad5d-1ecec8f94bcc
      name: "Number of doors and windows open"
      state: >
        {{ 
          this.get('attributes', {}).get('entity_ids', [])
                     | select('is_state', 'on')
                     | list
                     | count
        }}
      state_class: total
      attributes:
        entity_ids: >
          {{ states.binary_sensor | map(attribute='entity_id') | select('search', '(door|window).*_contact') | list }}

Something like this

thin jay
#
- sensor:
    - unique_id: d1c3df62-ddd4-4139-ad5d-1ecec8f94bcc
      name: "Number of doors and windows open"
      variables:
        entity_ids: >
          {{ states.binary_sensor | map(attribute='entity_id') | select('search', '(door|window).*_contact') | list }}
      state: >
        {{ 
          entity_ids | selectattr('state', '==', 'on')
                     | list
                     | count
        }}
      state_class: total

If I use this, it is always 0. I think it is because of the missing expand after entity_ids, no?

#

I've updated the template to this state:

{% set entities = label_entities('window_door_contact') %}
{{ entities | expand | selectattr('state', '==', 'on')
                     | list
                     | count }}

Seems to be working correctly

graceful oak
#

Yes, or use the is_state test like I did above

#

Then you don't need to use expand

thin jay
#

thanks, this worked