Help with automation based on room presence

Hi.
Using mqtt_room to determine mobile is in room (office) vs. not_home.

I have an automation that turn on light based on zigbee motion sensor.
I want to leverage the ESPresense module to determine that if my mobile phone is in the room, to NOT turn off the lights.

The reason is that the motion sensor doesn’t always detect my motion so it turns off the lights while I’m in the room.

I also don’t want to use the automation to turn on the lights based on espresense, because it’s too hard to calibrate it.

So I thought why not utilize motion detection and espresense to decide if and when to turn off the lights.

The problem is that I’m not successful in creating the automtion.
I get If: Error: undefined when viewing the Trace Timeline.

This is my yaml:

alias: Gil's office light automation - v2
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.0xa4c13856fb9322ff_occupancy
    from: "off"
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 0
  - platform: state
    entity_id:
      - binary_sensor.0xa4c13856fb9322ff_occupancy
    from: "on"
    to: "off"
    for:
      hours: 0
      minutes: 0
      seconds: 0
condition: []
action:
  - if:
      - condition: state
        entity_id: binary_sensor.0xa4c13856fb9322ff_occupancy
        state: "on"
      - condition: and
        conditions:
          - condition: sun
            after: sunrise
            before: sunset
        alias: Daytime
    then:
      - service: scene.turn_on
        target:
          entity_id: scene.daytime_light_color
        metadata: {}
    else:
      - if:
          - condition: state
            entity_id: binary_sensor.0xa4c13856fb9322ff_occupancy
            state: "on"
          - condition: and
            conditions:
              - condition: sun
                after: sunset
                before: sunrise
                alias: Evening
        then:
          - service: scene.turn_on
            target:
              entity_id: scene.evning_light_color
            metadata: {}
        else: []
  - if:
      - condition: state
        entity_id: binary_sensor.0xa4c13856fb9322ff_occupancy
        state: "off"
        for:
          hours: 0
          minutes: 0
          seconds: 0
      - condition: state
        entity_id: sensor.galaxy_s23
        state: not_home
        enabled: true
    then:
      - service: light.turn_off
        data: {}
        target:
          entity_id: light.gil_s_office_lights
mode: queued
max_exceeded: silent
max: 10

Please let me know how can I fix this. Thank you!

  1. Don’t nest If/then actions, use a Choose action instead.

  2. Take care with you selection of conditions. Using a state condition re-checks the state. This may not be an issue most of the. But, when you are using something that is “hard to calibrate” or that changes often enough that you need to use a mode other than “single”, and you’re using the same entity as the trigger… consider using Template conditions based on the trigger variable or a Trigger condition.
    Another option would be to add a for/duration to the state condition so that momentary bounces of the occupancy sensor don’t cause unexpected results.


alias: Gil's office light automation - v2
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.0xa4c13856fb9322ff_occupancy
    from: 
      - "off"
      - "on"
    to: 
      - "off"
      - "on"
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ trigger.to_state.state == 'off' }}"
          - condition: state
            entity_id: sensor.galaxy_s23
            state: not_home
        sequence:
          - service: light.turn_off
            data: {}
            target:
              entity_id: light.gil_s_office_lights
      - conditions:
          - condition: sun
            after: sunrise
            before: sunset
            alias: Daytime
          - condition: template
            value_template: "{{ trigger.to_state.state == 'on' }}"
        sequence:
          - service: scene.turn_on
            target:
              entity_id: scene.daytime_light_color
            metadata: {}
      - conditions:
          - alias: Evening
            condition: sun
            after: sunset
            before: sunrise 
          - condition: template
            value_template: "{{ trigger.to_state.state == 'on' }}"
        sequence:
          - service: scene.turn_on
            target:
              entity_id: scene.evening_light_color
            metadata: {}
mode: queued
max_exceeded: silent
max: 10

I don’t know how to create a for loop. I’m still learning this automation bit.
nesting the if/then statements seems logical, why is it not recommended?

how does one know when to use templates? how did you create it?

p.s. - may I DM you for assistance with another automation of a rotating knob controlling light hue/temp? willing to pay for your time.

p.p.s - I just tested the automation you kindly provided. I covered the motion sensor and made sure my phone is not in the room (== not_home).
What I got was:

expected: turn off the lights.
could it be that I’m using the sensor.galaxy_s23 incorrectly? this entity has only a distance attribute.
The not_home is something I wrote manually. It’s not auto populated by HA in the drop-down menu.

There are no loops in what you posted. Please clarify.

I don’t know if there is a technical reason or if it’s more an anti-branching philosophy… but, the docs specifically say:

This action supports nesting, however, if you find yourself using nested if-then actions in the else part, you may want to consider using choose instead.

The automation I posted using choose could be simplified/reorganized a bit more to reduce the number of condition checks necessary.

Templating is one of the most powerful and useful features in HA, but it isn’t necessary for most automation. You could accomplish the same thing using a Trigger condition. But, once you learn to use templates, you may find that you use them everywhere because they are more flexible and faster to set up than other options.

There are quite a few tutorial videos on YouTube that cover templates such as SlackerLabs, Everything Smart Home, and Smart Home Makers.

Yes, it could definitely be an issue if you are requiring a state that the sensor is never going to be in… What integration did the sensor originate from? Post a screen shot of the entity’s info from the Developer Tools > States tool and/or post the Trace json so we can see exactly what happened (From the Trace viewer, go to the top right and click the 3-dot expansion menu, then select “Download trace”. Copy/paste the contents of the json file to a new forum post)

I’m using espresense and the phone is transmitting ibeacon.

trace

I don’t use Espresence, but you likely want either a Not condition…

        - not:
            - condition: state
              entity_id: sensor.galaxy_s23
              state: gil_s_office

or a Template condition that does the same type of thing…

        - condition: template
          value_template: "{{ not is_state('sensor.galaxy_s23', 'gil_s_office') }}"

Looking at the trace, the sensor’s state when the automation was triggered was gil_s_office, so you may need to just turn off the phone for a few minutes before you test again.

Thanks for the explanation.

I’m trying to test several scenarios with the phone’s state.

If detection is true and phone location is not home, then switch off lights after 2 minutes.

If detection is true and phone is in office, then phones becomes not home, do the same as above once the sensor detection is cleared.

That second scenario didn’t work.

I repeated that but then also covered the motion sensor and expected the lights to go off but they remained on.

I need to wrap my head around this since it turns out to be more complicated than I expected.

p.s. have you seen my offer with thr DM in my post above?

Is there a case where the phone becomes not home and you want the lights to stay on? If so, you may need an automation/script to handle that side of the light control with it’s own logic. If not add that as the trigger instead of chaining triggers and waiting. There are definitely cases where waits and delays are needed, but most of the time using the event closest in time to your desired action is the best option.

while it is possible for this happen, I’m less concerned about covering this scenario.

by the way, if I remove this:

- conditions:
          - condition: template
            value_template: "{{ trigger.to_state.state == 'off' }}"
          - condition: state
            entity_id: sensor.galaxy_s23
            state: not_home

just to test the scenarios of switching on, then the automation doesn’t work at all.
I expected the lights to turn on without a scenario of switching off.

Did you remove the action sequence as well…? An action sequence without conditions will cause an configuration error for the choose action.

I got it working now on all scenarios. What was missing in the conditions is the AND operator. It seems to have fixed it:

alias: Gil's office light automation - v3
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.0xa4c13856fb9322ff_occupancy
    from:
      - "off"
      - "on"
    to:
      - "on"
      - "off"
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ trigger.to_state.state == 'off' }}"
            alias: No motion detection
          - condition: and
            conditions:
              - condition: state
                entity_id: sensor.galaxy_s23
                state: not_home
        sequence:
          - service: light.turn_off
            data: {}
            target:
              area_id: gil_s_office
      - conditions:
          - condition: template
            value_template: "{{ trigger.to_state.state == 'on' }}"
          - condition: and
            conditions:
              - condition: sun
                before: sunrise
                after: sunset
                after_offset: "-02:00:00"
        sequence:
          - service: scene.turn_on
            target:
              entity_id: scene.evning_light_color
            metadata: {}
      - conditions:
          - condition: template
            value_template: "{{ trigger.to_state.state == 'on' }}"
          - condition: and
            conditions:
              - condition: sun
                before: sunset
                after: sunrise
                before_offset: "-01:00:00"
        sequence:
          - service: scene.turn_on
            target:
              entity_id: scene.daytime_light_color
            metadata: {}
mode: queued
max_exceeded: silent
max: 10

p.s. - have you seen my DM?

That cannot be the case, because none of those And conditions are actually doing anything.

First, the basic logical behavior of a list of conditions is AND. You do not need to use an And condition unless it is within an Or or Not condition.

#These conditions follow AND logic

- conditions:
    - condition: template
      value_template: "{{ trigger.to_state.state == 'on' }}"
    - condition: sun
      before: sunset
      after: sunrise
      before_offset: "-01:00:00"

Second, And conditions only act on the conditions that are nested underneath them. An And with only one condition listed under its conditions is functionally the same as not having an And condition.

#And conditions work as follows

    - condition: and
      conditions:
        - condition: sun
          before: sunset
          after: sunrise
          before_offset: "-01:00:00"
        - condition: template
          value_template: "{{ trigger.to_state.state == 'on' }}"

I thought exactly as you explained it. however, I just tried it and it worked. I’ll revert things back and try again with the AND operand.

Thanks again for your continued help and explanations.