WTH isn't there an if-elif-else instead of choose

Continuing the discussion from WTH. Script execution stops after a condition step in script sequence, rather than continue past:

I’m beginning to believe that the choose construct was a mistake. :laughing: :cry: It seems to confuse everyone.

I think this would be better (and now that I’ve had a chance to think about it more, it wouldn’t really be any more difficult to implement than choose was):

- if:
  <conditions>
  then:
  <actions>
- elif:
  <conditions>
  then:
  <actions>
- else:
  <actions>

where <conditions> are one or more conditions:

- if:
  - condition: state
    entity_id: binary_sensor.abc
    state: 'on'
  - condition: template
    value_template: "{{ abc == '123' }}"

and <actions> are one or more actions:

  then:
  - service: script.abc
  - event: xyz

and elif and else are both optional, meaning you could use one, or the other, or both, or neither.

5 Likes

So if no condition is true no action is performed without generating an error?

I raelly liked how elegant this solution this was:

But it would work just as well with if / else.

Why would there be an error? Yes, “if FALSE then X” would mean don’t do X. Why is that unclear in any way?

The elegant solution you linked to (if “if-elif-else” was available as I proposed), would just look like this instead (but would be exactly equivalent):

- id: light_dependency
  alias: Light dependency
  description: "Switch lights to same state"
  trigger:
    platform: state
    entity_id: light.patio
  action:
    - if:
        - condition: template
          value_template: "{{ trigger.to_state.state == 'on' }}"
      then:
        - service: light.turn_on
          entity_id:
            - light.garden
    - elif:
        - condition: template
          value_template: "{{ trigger.to_state.state == 'off' }}"
      then:
        - service: light.turn_off
          entity_id:
            - light.garden

Think jinja. I’ve lost count of the number of times I’ve told people they need an else case to cover all eventualities.

That’s totally different. If you’re using service_template, then the template must provide a service, because you’re basically saying “call a service, but let me figure out which one first.” But an if action is only doing something if the conditions are true. It’s the difference between:

Do X if Y

vs

If X do Y

In the former (which is like a service_template), if X is false then you’ve said do something, but did not provide what to do.

In the latter (which is like an if action), if X is false then you haven’t said to do anything.

1 Like

I’m trying to think this trough. I’m creating a pseudocode choose, adding if, then, else statements as comments. That is easier for me to think about them that way.

- choose:
    - conditions: # If
        <user is Phil>
      sequence: # then
        <Phil's action>
    - conditions: # elseif
        <user is Tom>
      sequence: # then
        <Tom's action>
  default: #else, then
    <Alternate user action>

Yes, a choose action can be used like if-elif-else. In fact, that’s what it really is. But it seems to confuse a lot of people. I’m not sure why, but it does.

The structure isn’t not obvious, the indents seem inconsistent. I think choose is one I will always have to copy reference code to get started. I don’t think I will ever get it right if I try to type it manually. For example it breaks my brain that default is at a different level than the conditions. My brain wants the else to be at the same level as the elseif's.

5 Likes

Maybe my example would look like this?

- if:
    - conditions:
        <user is Phil>
      then:
        <Phil's action>
    - conditions:
        <user is Tom>
      then:
        <Tom's action>
    - else:
        <Alternate user action>

Or the else could look like this?

    - else:
      then:
        <Alternate user action>

Not based on what I’m proposing. It would be:

- if:
    <user is Phil>
  then:
    <Phil's action>
- elif:
    <user is Tom>
  then:
    <Tom's action>
- else:
    <Alternate user action>
4 Likes

So we could omit the - conditions: and just get to a condition. If that’s possible, that would be nice. But either works in my mind.

:heart: this

I try to live by the motto, “It’s never too late” :slight_smile: But I realize that once published and people start using it, it’s super painful to pull it back. So I guess we live with it and just document. Or could if / else be introduced as aliases for conditions to get most of the way there?

IMO, eliminating the duplicated items would be even more “elegant”. I know this isn’t valid yaml, but I’m thinking of something like:

- id: light_dependency
  alias: Light dependency
  description: "Switch lights to same state"
  trigger:
    platform: state
    entity_id: light.patio
  action:
    entity_id:
      - light.garden
    if:
      - condition: template
        value_template: "{{ trigger.to_state.state == 'on' }}"
      - then:
        - service: light.turn_on
      - else:
        - service: light.turn_off

As for why choose confuses people, for me it’s the conditions: part. I only see one mention of it in the documentation: Script Syntax - Home Assistant and it is super simple. It isn’t clear to me from it how multiple conditions would work - are they AND or OR? And how do multiple ELSE’s fit into the example? And separately, despite having programmed in various languages off and on for 40 years, I can’t wrap my head around how the else in the example makes sense given the indention. Course, I’m still not a yaml expert, so that may be part of the problem (for me and others).

Perhaps the “elegant” example could be added to the documentation, and maybe the example in the 0.113 notes (or point to that example) as well. In both cases, a few comments pointing out the parallel to if, elsif, else would go a long, long ways.

Mostly unrelated, but I just noticed it isn’t mentioned on the automations documentation page, only the scripts page.

2 Likes

Follow the link to the conditions page and it explains it there, because it’s the same everywhere multiple conditions are accepted. It can’t be explained over and over again everywhere. That would not be maintainable.

Yep, that’s definitely part of the problem for new users.

It’s definitely on my to-do list to enhance the documentation for the choose action.

It’s on the “script syntax” page, which is used by both the script’s sequence section and the automation’s action section. (An automation is really nothing but a script with trigger/condition tacked on to decide when to automatically run the actions.) I have a PR somewhere in the stages of release that reorganizes the script & automation pages somewhat to make it clearer, but it’s stuck somewhere…

1 Like

And a quick link to the preview.

2 Likes