{% if ... elif ... else %} with no else - what do you do?

I agree but do you have an alternative for cases where there really isn’t an else but there are further steps in the automation?

The only other way I have come up with is to always call a separate script which performs one function and let that script have the condition. Probably slightly more correct but in my opinion slightly less maintainable. YAML is bad enough without having tiny bits of code all over the place just to deal with a logic problem.

Of course, feel free to disagree :slight_smile:

Agreed. Tonight I have actually been able to remove it from the few templates I was using it in by using either David’s suggestion to put the last option in the else case or petro’s condition suggestion. e.g.

  condition:
  - condition: template # Only if currently running any heat mode
    value_template: "{{ 'Heat' in states.input_select.lounge_ac_mode.state }}"
  action:
    service_template: >
      {% if is_state('input_select.lounge_ac_mode', 'Powerful Heat') %} shell_command.lounge_ac_powerful_heat
      {% elif is_state('input_select.lounge_ac_mode', 'Normal Heat') %} shell_command.lounge_ac_normal_heat
      {% elif is_state('input_select.lounge_ac_mode', 'Silent Heat') %} shell_command.lounge_ac_silent_heat
      {% endif %}

Put the if/else template bit as the last action. After the condition. You can put conditions in the action section.

Show me an example, and I’ll let @petro beat me to the answer :smile:

Ha! You already beat me to my answer though. I’d use a dummy script if it needs to run first in the sequence.

1 Like

@anon43302295 I thought my original example covered it!

But between you and @petro you’ve pretty much answered everything so no need to fight over it :stuck_out_tongue_winking_eye:

However @tom_l wins the prize for being first to point out the obvious trivial and inconsequential,

delay: 00:00:00

I still don’t like that you can’t have an empty else but, hey ho. (EDIT: although it has been adequately explained to me now - Automation - right usage of trigger event data for conditions)
Thanks everyone

If it’s just that, it would be

  - condition: template
    value_template: "{{ (now().month == 1 and now().day == 2) or (now().month == 3 and now().day == 4) }}" 
  - service: script.birthday_greeting

And @tom_l 's would be…

action:
    service: script.turn_on
    data_template:
      entity_id: >-
        {% if states('sensor.aeotec_lounge_light_level') | float > 70 %}
          script.lounge_rd_lights_off
        {% elif 41 > states('sensor.aeotec_lounge_light_level') | float > 30 %}
          script.lounge_rd_lights_25
        {% elif 31 > states('sensor.aeotec_lounge_light_level') | float > 20 %}
          script.lounge_rd_lights_50
        {% else %}
          script.lounge_rd_lights_75
        {% endif %}

Not quite. There’s a gap between 41 and 70 that should not result in the (else) lights_75 case. I just closed it by bringing that first test down to >40.

Condition the gap, so it doesn’t run the action if it is within the gap :wink:

@anon43302295, that is another good solution using a condition but I am interested in if there is a solution when it is not the last action in an automation.

Let’s say for some reason I then wanted to to check if was St. Georges day(!), or something else more useful :slight_smile: and not even date related, or even something that didn’t even need a condition to be met. (A real world example could be a delay until the birthday greeting TTS was finished.)

That’s why I asked for the example code.

Like I don’t know what your birthday greeting script does, or what your St George’s day script would do, but if this is all part of an announcement over tts for example, I would run a ‘say’ script and put the logic for what needs saying and when in that.

Like my announcements script uses the status of a random binary sensor to decide whether or not to add an ‘interesting fact’ to the end of each message, you could easily use the same principle to work out if it’s somebody’s birthday (or saints day!) and just have it built in to the message.

Your TTS script was one of the first really cool things I saw when I joined this forum and I did indeed nick most of it to good effect :slight_smile:

I became slightly disenchanted with the whole TTS in HA thing though due to it not being able to queue messages so getting message clash and also announcements always being in a predefined order does get a bit samey.

This prompted me to come up with a different method which currently might just about be as good as yours (at best) but I think will be more flexible if ever there is a way to queue messages and if I can put the work in to get around the 256 character input text limit. MQTT seems the best option at the moment for that but there is always something more interesting to do with HA than rework existing working features!

Heh, there are ways to queue the messages, just depends how much effort you want to put in. You could use a counter for example, and increment the counter with each message and get the number ‘in the queue’ to wait for the message to be spoken at the start of the script, and use a wait template.

Randomising the order of the sections of speech shouldn’t be too difficult either, the real ball-ache being how much time it takes to refine these things and try to cover every eventuality :slight_smile:

1 Like

please let me join this here, with a related question. I think I got it working, but I am not using the fail safe dummy script yet, and not sure if I even need to.
consider this:

service_template: >
  script.{% if is_state('input_boolean.notify_announcement', 'on') %}announce_presence
         {% elif is_state('input_boolean.notify_presence', 'on') %}notify_presence
         {% endif %}

If the announcement is on, it takes precedence over notify even if that is on. If announcement is off, evaluate if notify is on and if yes, notify.
If none are on, do nothing.
Would I need the ‘else’ here?

action:
  - service_template: >
      script.{% if is_state('input_boolean.notify_announcement', 'on') %}announce_presence
             {% elif is_state('input_boolean.notify_presence', 'on') %}notify_presence
             {% else %}dummy
             {% endif %}

or would this be better:

action:
  - condition: template
    value_template: >
      {{ is_state('input_boolean.notify_announcement', 'on') or 
         is_state('input_boolean.notify_presence', 'on') }}
  - service_template: >
      script.{% if is_state('input_boolean.notify_announcement', 'on') %}announce_presence
             {% elif is_state('input_boolean.notify_presence', 'on') %}notify_presence
             #{% else %}dummy
             {% endif %}

bottom one would be better, but you wouldn’t even need the elif. Because your or statement in the value_template would filter it down to those 2 options. Just keep in mind, with your current logic, if both are on, only 1 will fire (announce_presence).

1 Like

you mean like this:

action:
  - condition: template
    value_template: >
      {{ is_state('input_boolean.notify_announcement', 'on') or 
         is_state('input_boolean.notify_presence', 'on') }}
  - service_template: >
      script.{% if is_state('input_boolean.notify_announcement', 'on') %}announce_presence
             {% else %}notify_presence
             {% endif %}

clean!

Yep, it’s always going to be one or the other.

thx again, like it asasap :wink:

hello,i have this 5 automations,someone could tell me how simplify them in 1 or a sensor or something,thanks

- id: 'Tiempo Riego 15C'
  alias: Tiempo Riego 15C
  initial_state: true
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (states.input_datetime.riego_tardes.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: template
    value_template: "{{ states.sensor.temperatura_exterior.state | int <= 20 }}"
  action:
  - data:
      entity_id: input_number.riego_zona_2
      value: 15
    service: input_number.set_value   
  - data:
      entity_id: input_number.riego_zona_1
      value: 15
    service: input_number.set_value 
  - data:
      entity_id: input_number.riego_zona_3
      value: 15
    service: input_number.set_value 
- id: 'Tiempo Riego 20C'
  alias: Tiempo Riego 20C
  initial_state: true  
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (states.input_datetime.riego_tardes.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: template
    value_template: "{{ states.sensor.temperatura_exterior.state | int > 20 }}"    
  action:
  - data:
      entity_id: input_number.riego_zona_2
      value: 25
    service: input_number.set_value   
  - data:
      entity_id: input_number.riego_zona_1
      value: 25
    service: input_number.set_value 
  - data:
      entity_id: input_number.riego_zona_3
      value: 25
    service: input_number.set_value 
- id: 'Tiempo Riego 25C'
  alias: Tiempo Riego 25C
  initial_state: true  
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (states.input_datetime.riego_tardes.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: template
    value_template: "{{ states.sensor.temperatura_exterior.state | int >= 25 }}"    
  action:
  - data:
      entity_id: input_number.riego_zona_2
      value: 30
    service: input_number.set_value   
  - data:
      entity_id: input_number.riego_zona_1
      value: 30
    service: input_number.set_value 
  - data:
      entity_id: input_number.riego_zona_3
      value: 30
    service: input_number.set_value 
- id: 'Tiempo Riego 30C'
  alias: Tiempo Riego 30C
  initial_state: true  
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (states.input_datetime.riego_tardes.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: template
    value_template: "{{ states.sensor.temperatura_exterior.state | int >= 30 }}"  
  action:
  - data:
      entity_id: input_number.riego_zona_2
      value: 35
    service: input_number.set_value   
  - data:
      entity_id: input_number.riego_zona_1
      value: 35
    service: input_number.set_value 
  - data:
      entity_id: input_number.riego_zona_3
      value: 35
    service: input_number.set_value     
- id: 'Tiempo Riego 35C'
  alias: Tiempo Riego 35C
  initial_state: true  
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (states.input_datetime.riego_tardes.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"    
  condition:
  - condition: template
    value_template: "{{ states.sensor.temperatura_exterior.state | int >= 35 }}"  
  action:
  - data:
      entity_id: input_number.riego_zona_2
      value: 40
    service: input_number.set_value   
  - data:
      entity_id: input_number.riego_zona_1
      value: 40
    service: input_number.set_value 
  - data:
      entity_id: input_number.riego_zona_3
      value: 40
    service: input_number.set_value

i tried this one,but only executed the first 2,some idea,thanks

- id: 'prueba'
  alias: prueba
  initial_state: true
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (states.input_datetime.riego_tardes.attributes.timestamp | int | timestamp_custom('%H:%M', False)) }}"
  condition: []
  action:    
  - data: {}
    entity_id: input_number.riego_zona_2
    data_template:
      value: >
        {% if states.sensor.temperatura_exterior.state | int <= 20 %} 15
        {% elif states.sensor.temperatura_exterior.state | int > 20 %} 25
        {% elif states.sensor.temperatura_exterior.state | int >= 25 %} 30
        {% elif states.sensor.temperatura_exterior.state | int >= 30 %} 35
        {% elif states.sensor.temperatura_exterior.state | int >= 35 %} 40
        {% endif %}
    service: input_number.set_value