Does my logic seem correct here?

With the new updates I am seeing with HA and the powerful automation tools I am moving back from node red to HA. I just wanted to check my logic on this automation is correct. I want to unlock the front door when I return from my walk. Using camera person occupancy as the wait to actually trigger. Seeing if what I made look ok?

alias: unlock door when i walk home
description: ""
trigger:
  - platform: zone
    entity_id: person.hans_van_der_drift
    zone: zone.home
    event: enter
condition:
  - condition: state
    entity_id: sensor.iphone_mini_13_activity
    attribute: Types
    state: Walking
    for:
      hours: 0
      minutes: 0
      seconds: 0
  - condition: state
    entity_id: binary_sensor.konnected_7e1888_zone_10
    state: "off"
action:
  - parallel:
      - wait_for_trigger:
          - type: occupied
            platform: device
            device_id: ffa636b1fa9b8d5e98dd0aa1662b1e7e
            entity_id: binary_sensor.garage_frigate_person_occupancy
            domain: binary_sensor
        continue_on_timeout: false
        timeout:
          hours: 0
          minutes: 2
          seconds: 0
          milliseconds: 0
      - wait_for_trigger: []
        continue_on_timeout: false
        timeout:
          hours: 0
          minutes: 2
          seconds: 0
          milliseconds: 0
  - service: lock.unlock
    data: {}
    target:
      entity_id: lock.front_door_lock
mode: single

type or paste code here

The iPhone activity sensor gives a list. Normally this list contains one item, but keep in mind there can be multiple ones (probably when the certainty isn’t that high). There is a confidence attribute you can check too. Regardless, I think, change that to a template condition and take the first element. I’ve not been able to confirm this, but it seems the first element will always be the best guess.

What is the purpose of the 2nd wait for trigger?

This is perhaps a matter of taste, but I’d use a state trigger for the zone: Just trigger on the state with a to.

For the first wait for trigger (and in general) refrain from using device triggers. A state trigger will be much simpler and more maintainable. There are some posts on the forum explaining this in detail.

Thank you for taking the time to respond.

What is the purpose of the 2nd wait for trigger?

I posted the incorrect code. It should have been a second camera in case I come in from another direction.

This is perhaps a matter of taste, but I’d use a state trigger for the zone: Just trigger on the state with a to.

I have changed it to a “State Trigger”

For the first wait for trigger (and in general) refrain from using device triggers. A state trigger will be much simpler and more maintainable. There are some posts on the forum explaining this in detail.

I did some reading and changed the code to state triggers also.

I think, change that to a template condition and take the first element.

This is the only part I am yet to work out. If you have an example, I would appreciate it. I need to harness the power of templating.

Thanks again.

alias: unlock door when i walk home
description: ""
trigger:
  - platform: state
    entity_id:
      - person.hans_van_der_drift
    from: not_home
    to: home
condition:
  - condition: state
    entity_id: sensor.iphone_mini_13_activity
    attribute: Types
    state: Walking
    for:
      hours: 0
      minutes: 0
      seconds: 0
  - condition: state
    entity_id: binary_sensor.konnected_7e1888_zone_10
    state: "off"
action:
  - parallel:
      - wait_for_trigger:
          - platform: state
            entity_id:
              - binary_sensor.front_door_frigate_person_occupancy
            to: "on"
        continue_on_timeout: false
        timeout:
          hours: 0
          minutes: 2
          seconds: 0
          milliseconds: 0
      - wait_for_trigger:
          - platform: state
            entity_id:
              - binary_sensor.garage_frigate_person_occupancy
            to: "on"
        timeout:
          hours: 0
          minutes: 2
          seconds: 0
          milliseconds: 0
        continue_on_timeout: false
  - service: lock.unlock
    data: {}
    target:
      entity_id: lock.front_door_lock
mode: single

Just found a post you have written on this exact topic. Will come back in a hot minute with an update.

1 Like

Pieter, I think I have it all working now. Will test in the real world tomorrow. Looking at your below code, how would you handle you and a passenger (in my case my wife) with the same automation to open the garage door? In my case the door would close again.

- alias: "Open Garage Door When Arriving By Car"
  initial_state: true
  trigger:
    - platform: state
      entity_id: binary_sensor.pieter_present
      to: "on"
  condition:
    - condition: and
      conditions:
        # prevent a glitch in case the cover was recently closed
        - condition: state
          entity_id: cover.rhs_garage_door
          state: "closed"
          for:
            minutes: 5
        - condition: time
          after: "07:00:00"
          before: "23:00:00"
        # i must be arriving by car
        - condition: state
          entity_id: binary_sensor.pieter_driving
          state: "on"
        # my cover for my car
        - condition: state
          entity_id: binary_sensor.rhs_garage_occupied
          state: "off"
        # proxy for the alarm being off
        - condition: state
          entity_id: binary_sensor.rouve_present
          state: "on"
          for:
            minutes: 5
  action:
    - service: cover.open_cover
      entity_id: cover.rhs_garage_door
1 Like

Glad you got to make some changes!

I’m assuming your door/cover doesn’t have state (i.e. you don’t know whether it’s open or not). Is my understanding right? If that’s the case, I think it would really help to add a door sensor. When you have that, you can add mode: single to your automation and also a condition to check whether the door (cover) is already open. There’s very little cost to triggering an automation that’s then aborted due to a condition.

If you don’t have state, then I’d still add mode: single, but it will only cover you if both devices changes (update) their location very close apart. I think the optimistic mode of a template cover might help you. Otherwise, you could create your own helper (like an input boolean) to try and maintain a synced state. These things just tend to get out of sync… The optimistic mode probably has the same challenge.

Perhaps the most robust option for this scenario (where you don’t know the cover’s state), is to simply check when last the lock’s status was triggered. Putting this in a condition under your actions will say: Only if the lock’s status has changed more than a minute ago, I will attempt to unlock it. If you then trigger the automation on both people, they will race towards the unlock call, but once one is past this point, the other will fail (given internal states have updated quickly enough).

{{ (utcnow() - lock.front_door_lock.last_changed).seconds >= 60 }}

Regarding my code, we have split garage doors (two singles) and my wife doesn’t like the automatic opening. Since I haven’t yet automated my alarm or connected it to HA, I’m using her being home as a proxy for the alarm being off.

:+1:

I am close, just need a little bit of help with the template:

This one:

{{ (utcnow() - cover.garage_door.last_changed).seconds >= 60 }}

Gives me this error: Error occurred while testing condition

In ‘template’ condition: UndefinedError: ‘cover’ is undefined

and this version:

     {{ (utcnow() | as_timestamp -
      state_attr('cover.garage_door', 'last_triggered')  |
      as_timestamp) | default(0) | int > 60 }}

Gives this error: Error occurred while testing condition

In ‘template’ condition: ValueError: Template error: as_timestamp got invalid input ‘None’ when rendering template ‘{{ (utcnow() | as_timestamp - state_attr(‘cover.garage_door’, ‘last_triggered’) | as_timestamp) | default(0) | int > 60 }}’ but no default was specified

Right, so here’s the issue: You can only get to last_changed by accessing the main states object directly. Thus, try this:

{{ (utcnow() - states.cover.garage_door.last_changed).seconds >= 60 }}

The last_changed “attribute” isn’t accessible via the state_attr function (but you’re entirely right to have tried this, because intuitively it makes sense). It’s actually a property of the state object(s). You’ll see e.g. the attributes is then a property that contains all the attributes.

More info: Last_updated State and last-changed in Lovelave.

1 Like

Thank you Pieter, helped solved my solution, and I learnt a lot.

1 Like

You’re welcome!

Perhaps also post the complete solution to help others.

My automation. (I have made two, one for garage opening, one for door unlocking) have yet to work as intended in real life testing… Ill post both after I get it to work.

Sorry for all the questions, your answers make me ponder and sometimes the logic baffles me.

- alias: "Set Pieter's Driving State"
  id: "2cc8c07c-384d-4fce-ab9e-11e2c7a25b60"
  initial_state: true
  trigger:
    - platform: state
      entity_id: sensor.pieter_activity_type
      to: "Automotive"  # from anything else
    - platform: state
      entity_id: sensor.pieter_activity_type
      from: "Automotive"  # to anything else
  action:
    - service: "input_boolean.turn_{{ 'on' if is_state('sensor.pieter_activity_type', 'Automotive') else 'off' }}"
      entity_id: input_boolean.pieter_driving

I have emulated your code and it works great, in a bi-directional mode. So, if I drive, the input will toggle, or if I toggle, the boolean will toggle.

But this code for Hans Presence works only one way. Meaning the Boolean will toggle the input, but when I leave the zone the input boolean remains ON.

Here is my code:

alias: Toggle Input B of Hans present or away
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.hans_present
    to: "on"
    id: hans-on
  - platform: state
    entity_id:
      - binary_sensor.hans_present
    id: hans-off
    from: "on"
condition: []
action:
  - service: >-
      input_boolean.turn_{{ 'on' if is_state('binary_sensor.hans_present', 'on')
      else 'off' }}
    entity_id: input_boolean.hans_present
    enabled: true
mode: single

image

What is the definition of binary_sensor.hans_present?

Were there perhaps any errors in your log?

This version is a bit more compact and pretty much does the same thing. I can’t see anything wrong immediately, unless there’s a circular reference where the binary sensor uses the input boolean, which triggers the automation, etc.

alias: Toggle Input B of Hans present or away
trigger:
  - platform: state
    entity_id:
      - binary_sensor.hans_present
action:
  - service: >-
      input_boolean.turn_{{ 'on' if is_state('binary_sensor.hans_present', 'on') else 'off' }}
    entity_id: input_boolean.hans_present
mode: single

There was also a enabled: true that I removed that looks unfamiliar to me. Was that perhaps added by mistake?

Falling asleep last night, I believe this is the culprit!

    hans_present:
      friendly_name: "Hans Present"
      value_template: >-
        {{ is_state("input_boolean.hans_present", "on") or
          is_state("person.hans_van_der_drift", "home") }}

So, it seems when the automation turns the input booean on it stays on, as there are two states that triger the state.

Which leads me to another question, why do you have Input Booleans and a Bianry sensor? I can see the input it useful for testing but what other cased would you use one over the other?

The binary sensor uses the combination of the input boolean and the person state (if either is home/on, the person is definitely home).

The person entity is linked to the companion app (and hence uses GPS location). The input boolean is set by a home automation (iOS shortcuts app with my Apple TV being a home hub), since the home hubs can check presence too.

Lots of people uses multiple inputs for faster and more certain updates, typically using a Bayesian sensor, but I’ve found this simplified version to work well for me. It’s from a time when the companion app updates weren’t that reliable (a few years ago). Not it’s just a backup.

So, in short, I only ever use the binary sensor. The input boolean is only references by the sensor and set externally.