Help with automation conditions/logic flow

Hi Everyone,

So I’ve been re-jigging my automations for the last day or so ever since I changed presence to a binary_sensor and my wife ended up waking me up at 3AM telling me the lights were turning on automatically in the middle of the night :stuck_out_tongue:

So rather than putting time delays into my presence detection, I thought I’d try a different method by introducing time checks into the automations themselves. I decided to try small and go from there:

- alias: Home-Lights Auto-On (1800-2000)
  trigger:
    - platform: state
      entity_id: input_select.chris_status_dropdown
      to: 'Home'
    - platform: state
      entity_id: input_select.chris_status_dropdown
      to: 'Home'
  condition:
    condition: and
    conditions:
      - condition: time
        after: '18:00:00'
        before: '20:00:00'
      - condition: or
        conditions:
          - condition: template
            value_template: '{{ as_timestamp(now()) - as_timestamp(states.binary_sensor.chris_presence.last_changed) | int > 60 }}'
          - condition: template
            value_template: '{{ as_timestamp(now()) - as_timestamp(states.binary_sensor.val_presence.last_changed) | int > 60 }}'
  action:
    - service: light.turn_on
      entity_id: light.kitchen_table, light.living_room_east_lamp, light.living_room_west_lamp 

So if I understand this correctly, it should work this way:

  • If my (or my wife’s) status changes to ‘Home’
  • It’s between 6 and 8pm
  • If the last_update for the binary_sensor the tracks hers and my presence fired at least 60 seconds from the time this automation runs

Then run the automation.

Am I understanding this correctly? Been fighting presence detection and automations firing based on it for the last 24 hours and I’m close to giving up and using someone elses procedure for it but I think I’m doing the right thing here based on the following criteria:

  • My wife and I have cellphones with Owntracks installed, a “Home” location setup & shared (HASS sees this as a known_device)
  • We both have a BLE Tile which using @Bit-River’s BLE python script, checks every 3 seconds for presence of Tile
  • A nmap scan of my entire local network, 192.168.1.0/24

My presence detection works like so (based on @philhawthorne presence-not-so-binary article which you can find here: https://pastebin.com/UuPL8dUL

(I copied out the relevant sections…)

Hoping someone can spot something or give me some pointers on this and also clarify I understand the logic in the above automation in this post as I think I do.

-Chris

I think I got it working – made some small adjustments to the configuration but synthetic testing seems to be working as I expect it to.

Do I have my tired eyes on or do you have two identical triggers ?

1 Like

im looking to do the same thing… sometimes my Bluetooth LE device drops randomly for a minute or so in the middle of night causing a trigger when the state changes… can you tell me how you accomplished this? I am playing with the following config:

- id: welcome_message
  alias: Welcome Message  
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.keys
      from: 'not_home'
      to: 'Bedroom'
  condition: 
    - condition: template
      value_template: '{{(as_timestamp(now()) - as_timestamp(states.sensor.keys.last_changed) > 1)}}'
    - condition: state
      entity_id: binary_sensor.bedroom_sensor
      state: 'on'
  action:
    service: tts.amazon_polly_say
    entity_id: media_player.boss
    data_template:
      message: >-
        {{ [
        "Hello Andrew. " ,
        "Good evening. " ,
        "Welcome home. " ,
        "Hey there. " ,
        "Nice to see you again. "
        ] |random }}

No, your eyes are fine :slight_smile: Was supposed to be myself and my wife, this was fixed later on after that post. Good catch nonetheless.

The original post automation is still the same (typo fixed) and I increased the time-check to 5 minutes. Been working well. I also changed my presence routines around a little by removing timers (except for away/extended away) and adding the 5 minute check into the automation itself.

- alias: Just Arrived-Entry Lights (After Sunset)
  trigger:
    - platform: state
      entity_id: input_select.chris_status_dropdown
      to: 'Just Arrived'
    - platform: state
      entity_id: input_select.val_status_dropdown
      to: 'Just Arrived'
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: sun.sun
        state: 'below_horizon'
      - condition: or
        conditions:
          - condition: template
            value_template: '{{ as_timestamp(now()) - as_timestamp(states.binary_sensor.chris_presence.last_changed) | int > 300 }}'
          - condition: template
            value_template: '{{ as_timestamp(now()) - as_timestamp(states.binary_sensor.val_presence.last_changed) | int > 300 }}'
  action:
    - service: light.turn_on
      entity_id: light.mudroom_door, light.kitchen_table

I also modified the persistence automation to delay one minute after HASS starts and then toggles state:

- alias: Set Presence:Chris on HA start
  trigger:
    - platform: homeassistant
      event: start
  condition:
    condition: and
    conditions:
      - condition: state
        entity_id: binary_sensor.chris_presence
        state: 'off'
  action:
    - delay: '00:01:00'
    - service: input_select.select_option
      data:
        entity_id: input_select.chris_status_dropdown
        option: Away

I use the python BLE script that @Bit-River provided which checks every 3 seconds. I sometimes get gaps of a minute (rarely but it happens) but usually the gaps are 30-40 seconds at best. I also use a binary sensor for my wife and myself for presence which may help you:

 - platform: template
    sensors:
      val_presence:
        value_template: >-
          {{ is_state('device_tracker.val_iphone', 'home')
             or is_state('sensor.val_tile', 'true') }} 

So in this case, if the phone goes into deep-sleep I’m covered. If the tile is missed during the scan window, I’m still covered. As long as one of the two is true, my presence routines (which is based on this binary sensor) sees us as home. We’re not marked away until 10 minutes has passed which makes the assumption that after that much time, we’ve either suffered an EMP pulse or we’re really gone :slight_smile:

- alias: Presence-Away
  trigger:
    - platform: state
      entity_id: input_select.chris_status_dropdown
      to: 'Just Left'
      for:
        minutes: 10
    - platform: state
      entity_id: input_select.val_status_dropdown
      to: 'Just Left'
      for:
        minutes: 10
  action:
    - service: input_select.select_option
      data_template:
        entity_id: >
          {% if trigger.entity_id == 'input_select.chris_status_dropdown' %}
            input_select.chris_status_dropdown
          {% else %}
            input_select.val_status_dropdown
          {% endif %}
        option: Away 

These changes greatly improved presence detection for my particular use-case. No more lights turning on at 3am and my wife shaking me awake telling me to get up and turn them off :stuck_out_tongue:

Hope this helps. Refer to my pastebin link to see the surrounding bits for the above to make more sense.

-Chris

edit: missed a bit of automation code

Looking at it again, I think you’re condition isn’t right. Check mine out to see how I did it. You’re doing an AND operation but missing the code to support it based on how I read that, ie:

condition:
  condition: and
  conditions:
    check time stamp
    check sensor

In your case is how I think it needs to be. See the “Just Arrived-Entry Lights (After Sunset)” for a better idea as it appears we’re both checking two conditions.

1 Like

i think i just fixed it using the following template

`

  value_template: "{% if as_timestamp(now()) - as_timestamp(states.automation.welcome_message.last_updated) > 900%}true{% else %}false{% endif %}"

`

Glad you got it sorted out. Condition still looks off to me, not sure how that’ll work without the AND operation :slight_smile: as you’re testing the sensor for state=on and timestamp > # seconds

edit: I would also pass the timestamp through int(eger) to get a sane value as I believe it’ll be a decimal value (as you can see, I did this originally and then used ‘int’) as in my case it was never validating. Was very painful restarting X # of times watching for something that’d never fire, ie:

now - last_changed | int > seconds

Here is the full automation i would like to include my binary motion sensor as a condition too but im not quite sure how to do that yet… would i have have to use the AND operation for that? Any help on that would be appreciated

- id: welcome_message
  alias: Welcome Message  
  initial_state: 'on'
  trigger:
    - platform: state
      entity_id: sensor.keys
      from: 'not_home'
      to: 'Bedroom'
      for:
        seconds: 5
  condition: 
    - condition: template
      value_template: "{% if as_timestamp(now()) - as_timestamp(states.automation.welcome_message.last_updated) > 900%}true{% else %}false{% endif %}"
  action:
    service: tts.amazon_polly_say
    entity_id: media_player.boss
    data_template:
      message: >-
        {{ [
        "Hello Andrew. " ,
        "Good evening. " ,
        "Welcome home. " ,
        "Hey there. " ,
        "Nice to see you again. "
        ] |random }}

This change to your original example you posted:

  condition:
    condition: and
    conditions:
      - condition: template
        value_template: '{{ as_timestamp(now()) - as_timestamp(states.sensor.keys.last_changed) | int > 1 }}'
      - condition: state
        entity_id: binary_sensor.bedroom_sensor
        state: 'on'

edit: small fixups
edit: the above would imply (to me) that timestamp>1second AND binary_sensor.bedroom_sensor=on to validate and proceed to action portion of the automation.

1 Like

I will give this a try thanks again for the help