YAML: needing help with mixed AND/OR conditions

I have a YAML puzzle, and it’s the conditions section that has me stumped. I’ve made multiple attempts at revising, but so far no luck. I probably just need a fresh pair of eyes.

FWIW, this is related to an automation for the house night time security routine. It’s used it when one or both of my sons is out late. If we accidentally arm the house for bedtime while they’re away, we get a warning message.

Here’s the logic I’m after:

When switch.main_stairs_nighttime_security turns on,
If date_night is off
and if son 1 is away
or son 2 is away and he’s not at the University
Then announce the warning

First version of the code (anonymized a bit):

- alias: Bed Time Warning
  initial_state: on
  trigger:
    - platform: state
      entity_id: switch.main_stairs_nighttime_security
      to: "on"
  conditions:
    - condition: state
      entity_id: input_boolean.date_night
      state: 'off'
    - condition: or
      conditions:
        - condition: state
          entity_id: switch.pres_son_1
          state: "off"
        - condition: and
          conditions:
            - condition: state
              entity_id: switch.pres_son_2
              state: "off"
            - condition: not
              conditions:
                - condition: state
                  entity_id: device_tracker.son_2_phone
                  state: "University"
  action:
    # ...

Second version (conditions only):

  conditions:
    - condition: state
      entity_id: input_boolean.date_night
      state: 'off'
    - condition: or
      conditions:
        - condition: state
          entity_id: switch.pres_son_1
          state: "off"
        - condition: and
          conditions:
            - condition: state
              entity_id: switch.pres_son_2
              state: "off"
            - condition: not
              condition: state 
              entity_id: device_tracker.son_2_phone
              state: "University"
  action:
    # ...

Third version:

  conditions:
    - condition: state
      entity_id: input_boolean.date_night
      state: 'off'
    - condition: or
      conditions:
        - condition: state
          entity_id: switch.pres_son_1
          state: "off"
        - condition: template
          value_template: >
            {{ states('switch.pres_son_2') == 'off' and not is_state('device_tracker.son_2_phone', 'University') }}
  action:
    # ...

Fourth version:

  conditions:
    - condition: state
      entity_id: input_boolean.date_night
      state: 'off'
    - condition: or
      conditions:
        - condition: state
          entity_id: switch.pres_son_1
          state: "off"
        - condition: template
          value_template: "{{ states('switch.pres_son_2') == 'off' and not is_state('device_tracker.son_2_phone', 'University') }}"
  action:
    # ...

I can’t promise that the error message in the logs has been the same each time, but it’s always concerning the conditions, something like this:

Automation with alias 'Bed Time Warning' could not be validated and has been disabled: extra keys not allowed @ data['conditions']. Got [{'condition': 'state', 'entity_id': 'input_boolean.date_night', 'state': 'off'}, {'condition': 'or', 'conditions': [{'condition': 'state', 'entity_id': 'switch.pres_son_1', 'state': 'off'}, {'condition': 'template', 'value_template': "{{ states('switch.pres_son_2') == 'off' and not is_state('device_tracker.son_2_phone', 'University') }}"}]}]

Any help appreciated.

I managed to solve the problem (EDIT: almost… better solution with @123 help below). The solution required a significantly different approach.

- alias: Bed Time Warning
  initial_state: on
  trigger:
    - platform: state
      entity_id: switch.main_stairs_nighttime_security
      to: "on"
  action:
    - choose:
      - conditions:
          - condition: state
            entity_id: input_boolean.date_night
            state: 'off'
          - condition: state
            entity_id: switch.pres_son_1
            state: 'off'
          - condition: and
            conditions:
              - condition: state
                entity_id: switch.pres_son_2
                state: 'off'
              - condition: not
                conditions:
                  - condition: state
                    entity_id: device_tracker.son_2_phone
                    state: 'University'
        sequence:
          - service: # remainder of action continues here

Did you discard the logical OR requirement?

Because the latest example you posted logically ANDs all conditions. In other words, it requires both sons to be away and the second son must not be in ‘University’.

FYI
There’s a typo in the last State Condition. The ‘d’ in ‘device_tracker’ is missing.

I was just faking entity names for this post, but you’re right about the typo. I fixed it, thank you.

This is my first time using the choose and conditions structure, but as I understand it, the automation triggers the action if either of these two scenarios is true:

  • If input_boolean.date_night is off and switch.pres_son_1 is off.
  • If input_boolean.date_night is off and switch.pres_son_2 is off, and the state of device_tracker.son_2_phone is not equal to ‘University’.

Both of the above conditions are evaluated independently, and if either one of them is true, the automation’s action will be executed.

Having said that, the automation hasn’t had a chance to fire in a real-world setup. I may have to come back and eat crow.

Given the way you have composed the conditions, it’s “if both of these two scenarios are true”.

By default, all conditions are logically ANDed. Unless you explicitly indicate OR, they’re all ANDed.

I believe this is what you want:

- alias: Bed Time Warning
  initial_state: on
  trigger:
    - platform: state
      entity_id: switch.main_stairs_nighttime_security
      to: "on"
  action:
    - choose:
      - conditions:
          - condition: state
            entity_id: input_boolean.date_night
            state: 'off'
          - condition: or
            conditions:
              - condition: state
                entity_id: switch.pres_son_1
                state: 'off'
              - condition: and
                conditions:
                  - condition: state
                    entity_id: switch.pres_son_2
                    state: 'off'
                  - condition: not
                    conditions:
                      - condition: state
                        entity_id: device_tracker.son_2_phone
                        state: 'University'
        sequence:
          - service: # remainder of action continues here

What it’s doing:
(Date_night off) AND ((Son1 off) OR ((Son2 off) AND (Son2_phone != University)))


NOTE

Does the choose only have one choice?

If it does then you don’t need a choose. Simply put all conditions in the automation’s condition section.

I really appreciate the reply. Is this the revision you’re suggesting?

- alias: Bed Time Warning
  initial_state: on
  trigger:
    - platform: state
      entity_id: switch.main_stairs_nighttime_security
      to: "on"
  conditions:
    - condition: state
      entity_id: input_boolean.date_night
      state: 'off'
    - condition: or
      conditions:
        - condition: state
          entity_id: switch.pres_son_1
          state: 'off'
        - condition: and
          conditions:
            - condition: state
              entity_id: switch.pres_son_2
              state: 'off'
            - condition: not
              conditions:
                - condition: state
                  entity_id: device_tracker.pres_son_1_phone
                  state: 'University'
  action:
    # ...

If so, that’s exactly what I had initially (it’s at the top of my first post, First version of the code). I get this error:

Automation with alias 'Bed Time Warning' could not be validated and has been disabled: extra keys not allowed @ data['conditions']. Got [{'condition': 'state', 'entity_id': 'input_boolean.date_night', 'state': 'off'}, {'condition': 'or', 'conditions': [{'condition': 'state', 'entity_id': 'switch.pres_son_1', 'state': 'off'}, {'condition': 'and', 'conditions': [{'condition': 'state', 'entity_id': 'switch.pres_son_2', 'state': 'off'}, {'condition': 'not', 'conditions': [{'condition': 'state', 'entity_id': 'device_tracker.pres_son_2_phone', 'state': 'University'}]}]}]}]

Here’s another version that doesn’t result in errors in the log:

- alias: Bed Time Warning
  initial_state: on
  trigger:
    - platform: state
      entity_id: switch.main_stairs_nighttime_security
      to: "on"
  action:
    - delay: "00:00:20"
    - condition: state
      entity_id: input_boolean.date_night
      state: 'off'
    - condition: or
      conditions:
        - condition: state
          entity_id: switch.pres_son_1
          state: 'off'
        - condition: and
          conditions:
            - condition: state
              entity_id: switch.pres_son_2
              state: 'off'
            - condition: not
              conditions:
                - condition: state
                  entity_id: device_tracker.pres_son_2_phone
                  state: 'University'
    - service: # remainder of action continues here

Almost. You got the error message because you used the word conditions instead of condition.

This should pass validation:

- alias: Bed Time Warning
  initial_state: on
  trigger:
    - platform: state
      entity_id: switch.main_stairs_nighttime_security
      to: "on"
  condition:
    - condition: state
      entity_id: input_boolean.date_night
      state: 'off'
    - condition: or
      conditions:
        - condition: state
          entity_id: switch.pres_son_1
          state: 'off'
        - condition: and
          conditions:
            - condition: state
              entity_id: switch.pres_son_2
              state: 'off'
            - condition: not
              conditions:
                - condition: state
                  entity_id: device_tracker.pres_son_1_phone
                  state: 'University'
  action:
    # ...

In your latest example, there’s no point in putting a 20 second delay immediately after the automation has triggered. If the goal is to trigger only if the switch turns on and remains on for at least 20 seconds, use the State Trigger’s for option.

- alias: Bed Time Warning
  initial_state: on
  trigger:
    - platform: state
      entity_id: switch.main_stairs_nighttime_security
      to: "on"
      for:
        seconds: 20
  condition:
    - condition: state
      entity_id: input_boolean.date_night
      state: 'off'
    - condition: or
      conditions:
        - condition: state
          entity_id: switch.pres_son_1
          state: 'off'
        - condition: and
          conditions:
            - condition: state
              entity_id: switch.pres_son_2
              state: 'off'
            - condition: not
              conditions:
                - condition: state
                  entity_id: device_tracker.pres_son_1_phone
                  state: 'University'
  action:
    # ...

Geez Louise. It’s always some little niggling thing, right??? Sure enough, this passes validation, no errors in the logs.

The :20 second delay is there to stay out of the way of other announcements that occur each night (whether there’s a wake up alarm, what time it’s set for, etc.). I meant to remove it to avoid confusion, but … confusion’s been my middle name for this exercise, so…

THANKS for your help!

1 Like