SOLVED: Using choose for OR IF instead of ELSE IF

Choose is a nice addition to automations, but after having looked at it, I’ve realized there’s very few of my automations which would benefit from it. What is far more needed in my opinion is an OR IF type statement, where we can group multiple conditions and actions under a single trigger. I have tons of automations which use the same trigger but slightly different conditions to notify different people for example. In these cases, it would need to evaluate each set of conditions and actions and launch all the ones that apply, instead of only one.

Seems like if we can do else, we could also do multiple IF’s… Here’s an example using choose of what I would want, only difference being that all the chooses should be applied if the conditions are right.

- id: someone_through_gate
  alias: someone_through_gate
  initial_state: 'true'
  trigger:
    platform: state
    entity_id: binary_sensor.person_inside_gate
    to: 'on'
  action:
    - choose:
        - conditions:
            - condition: and
              conditions:
              - condition: template
                value_template: '{{ (as_timestamp(now()) - as_timestamp(states.automation.person_in_front.attributes.last_triggered | default(0)) | int > 600)}}'
              - condition: state
                entity_id: device_tracker.sean_s_iphone_12
                state: 'home'
          sequence:
            service: notify.mobile_app_sean_s_iphone_12
            data:
              title: "Person Coming Through Gate"
              message: "Looks like someone is going to or coming from the front gate to the front door"
              data:
                push:
                  category: camera
                  thread-id: "security"
                entity_id: camera.front_stream
                clickAction: /lovelace/4
    - choose:
        - conditions:
            - condition: and
              conditions:
              - condition: template
                value_template: '{{ (as_timestamp(now()) - as_timestamp(states.automation.person_in_front.attributes.last_triggered | default(0)) | int > 600)}}'
              - condition: state
                entity_id: device_tracker.alena_s_iphone
                state: 'home'
          sequence:
            service: notify.mobile_app_alena_s_iphone
            data:
              title: "Person Coming Through Gate"
              message: "Looks like someone is going to or coming from the front gate to the front door"
              data:
                push:
                  category: camera
                  thread-id: "security"
                entity_id: camera.front_stream
                clickAction: /lovelace/4
        - conditions:
            - condition: and
              conditions:
              - condition: template
                value_template: '{{ (as_timestamp(now()) - as_timestamp(states.automation.person_in_front.attributes.last_triggered | default(0)) | int > 600)}}'
              - condition: state
                entity_id: device_tracker.sean_s_iphone_12
                state: 'home'
          sequence:
            - service: mqtt.publish
              data:
                topic: !secret genesys_5490_notify_topic
                payload: '{ "title": "Person Coming Through Gate", "message": "Looks like someone is going to or coming from the front gate to the front door", "iconUrl": "", "launchParams": "toast://open/http://10.10.10.20:8123/lovelace/8" }'

They will be. Pseudo code:

action: 
  - choose:
      - conditon: {{ blah 1 }}
      - sequence
          - ...
  - choose:
      - conditon: {{ blah 2}}
      - sequence
          - ...
  - choose:
      - conditon: {{ blah 3 }}
      - sequence
          - ...
  - choose:
      - conditon: {{ blah n-1 }}
      - sequence
          - ...
  - choose:
      - conditon: {{ blah n }}
      - sequence
          - ...

If any or all of the conditions blah 1 though blah n are met those actions will be executed.

2 Likes

Yes. That’s correct. If the condition is met for the specific choose option, the sequence will always be launched, regardless of how many other chooses in the statements have also already been launched. If all the choose conditions are met, all sequences are launched. If none are met, none are launched.

I showed my example with the standard choose statement in place today which will result in an ELSE IF instead of an OR IF… So the syntax would somehow have to be modified to express that this is an OR IF instead… Could be

  action:
    - choose-and:

or choose-all or whatever…

I don’t understand what you mean. If you want all the actions to be executed just put them under the one choose action.

If I put them all under one choose action, they will all have the same condition. I want a single trigger to allow multiple actions, each depending on different conditions.

In the example I gave, I am trying to do this:

IF I see someone inside the gate
THEN:
-Notify my wife if she is home and if no one has been spotted in front in 10 minutes
AND:
-Notify me on my phone if I am home and no one has been spotted in front in 10 minutes
AND:
-Notify me on my computer if I am home and no one has been spotted in 10 minutes

(to be fair the last 2 could be grouped together now, but I plan to add another condition to the 3rd case where it checks if my computer is in use or not).

With the current choose statement you can only get this:

IF I see someone inside the gate
THEN:
-Notify my wife if she is home and if no one has been spotted in front in 10 minutes
OR:
-Notify me on my phone if I am home and no one has been spotted in front in 10 minutes
OR:
-Notify me on my computer if I am home and no one has been spotted in 10 minutes

Which is what my example above shows.

Maybe I’m not understanding something, but I think your example will result in an ELSE IF, not an OR IF with current choose statement. With a new type of choose that can make an AND IF, it would work for the case I am asking for.

You just nest the choose actions for AND. e.g. condition 1 AND 2 must be true:

action:
  - choose:
      - condition: {{ condition 1 }}
      - sequence:
          - choose:
              - condition: {{ condition 2 }}
              - sequence:
                  - service: ...

Oh wow, so I was missing the point then. Are you sure it will really execute the other choose statements if the first one evaluates to false though? I would think all of them would have to evaluate true for this to work, if one evaluated as false, it would break the chain, no?

I probably wasn’t clear when I said AND IF, but what I was really looking for was just multiple IF statements with no dependencies on each other. I guess this is really OR IF… I will change this in my statements above to make this more clear. My bad. It’s really OR IF I want.

That is exactly what my first example shows. Each of the choose statements are independent. If one does not evaluate to true it moves on to the next. If it does evaluate to true it executes the sequence before moving on to the next choose statement.

Hmm, I’ve been using it that way (the example code I showed is from a real automation), and I can only ever get the first condition/sequence pair to fire. This is consistent with what it shows in the docs:

The choose action can be used like an “if” statement. The first conditions/sequence pair is like the “if/then”, and can be used just by itself. Or additional pairs can be added, each of which is like an “elif/then”. And lastly, a default can be added, which would be like the “else.”

The example they show for this is this (notice the lack of nesting, but they still say this is an if/elif/else):

# Example with "if", "elif" and "else"
automation:
  - trigger:
      - platform: state
        entity_id: input_boolean.simulate
        to: 'on'
    mode: restart
    action:
      - choose:
          # IF morning
          - conditions:
              - condition: template
                value_template: "{{ now().hour < 9 }}"
            sequence:
              - service: script.sim_morning
          # ELIF day
          - conditions:
              - condition: template
                value_template: "{{ now().hour < 18 }}"
            sequence:
              - service: light.turn_off
                entity_id: light.living_room
              - service: script.sim_day
        # ELSE night
        default:
          - service: light.turn_off
            entity_id: light.kitchen
          - delay:
              minutes: "{{ range(1, 11)|random }}"
          - service: light.turn_off
            entity_id: all

Look closely. That’s one choose action with multiple conditions (and a default). That gives you if/then/else for each condition in the single choose action.

My example has seperate choose actions each with their own conditions. That gives you a whole bunch of individual if statements. Which is (I think) what you are after.

My code:

action: 
  - choose:
      - conditon: {{ blah 1 }} # do this if true
        sequence:
          - ...
  - choose:
      - conditon: {{ blah 2}} # and then do this if true
        sequence:
          - ...
  - choose:
      - conditon: {{ blah 3 }} # and then do this if true
        sequence:
          - ...
  - choose:
      - conditon: {{ blah n-1 }} # and then do this if true
        sequence:
          - ...
  - choose:
      - conditon: {{ blah n }} # and then do this if true
        sequence:
          - ...

That example:

action: 
  - choose:
      - conditon: {{ blah 1 }} # do this if true then exit the choose
        sequence:
          - ...
      - conditon: {{ blah 2}} # else do this if true then exit the choose
        sequence:
          - ...
      - default: # do this if none of the above then exit the choose.
        sequence:
          - ...

See the difference now?

Only one option in each choose gets executed but I have listed multiple choose statements, so each of them gets evaluated and actioned if true.

2 Likes

As to your example:

IF I see someone inside the gate # this your trigger (and maybe a condition)
THEN:

# first choose block 
-Notify my wife if she is home and if no one has been spotted in front in 10 minutes
AND:

# second choose block
-Notify me on my phone if I am home and no one has been spotted in front in 10 minutes
AND:

# third choose block
-Notify me on my computer if I am home and no one has been spotted in 10 minutes

You only appear to have two choose blocks in your code so have a look at it and try again. I’d write it out but I’m on mobile.

Oh shit, you’re right. Well spotted. Will try it tonight. So as usual, probably just me being thick. Thanks for that!

if you are running HassIO, just install Node-Red, you can do there whatever you like.

You can do 'whatever you like" without the added layer and overhead of node red using yaml and jinja.

2 Likes

Is it possible to do this in the Automations interface? And how would it look? (Sorry my YAML syntax is weak. I like the interface to limit my mistakes to logic errors :crazy_face: )

Honestly I don’t use the UI for writing automations. But according to the release notes yes the choose action is available from the automation UI where you select “Action Type”.

More information is possible what you mean. Can I use it when playing? :thinking: Or am I wrong topic?

Sorry :grimacing: