Automation - right usage of trigger event data for conditions

I have some issues with the right definition of conditions, I tried several variants, but I get different configuration check errors.

My next question is:
If I define a service_template with multiple conditions and no condition will match: Will the automation automatically stopp or is it “dirty” to not provide a service?
What is the best way to break the automation at this point when nothing matches?
Calling a dummy script would work but is not a fine solution.

- alias: 'Cube Action all in one'
  id: cube_action_all_in_one
  hide_entity: false
  #initial_state: false
  trigger:
    # multiple trigger
    # Whenever one of the triggers fires, your rule is executed.
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_12345678901234
        #cube Dachgeschoss
        #action_type: tap_twice
    - platform: event
      event_type: cube_action
      event_data:
        entity_id: binary_sensor.cube_12345678901299
        #cube Wohnzimmer 2
        action_type: tap_twice
  ##################################################
  ### required: a condition that 
  ### action_type is in a set of actions:
  #flip90
  #flip180
  #move
  #tap_twice
  #shake_air
  #rotate (degrees as action_value)
  ##swing?
  ##free_fall?
  #################################################
  # condition: or
  # conditions:
    # - condition: template
      # value_template: "{{ trigger.event.data.action_type == 'tap_twice' }}"
      # # value_template: >-
         # # {% if trigger.event.data.action_type == "tap_twice" %}
           # # {{true}}
         # # {% endif %}
         
    # # # - condition: template
      # # # value_template: "{{ trigger.event.data.new_state.attributes['action_type'] == 'move' }}"
    # # # - condition: template
      # # # value_template: "{{ trigger.event.data.new_state.attributes['action_type'] == 'move' }}"
    # # # - condition: template
      # # # value_template: "{{ trigger.event.data.attributes['action_type'] == 'move' }}"
     # # # - condition: template
      # # # value_template: "{{ trigger.event.data.attributes['action_type'] == 'move' }}"
  action:
  - service_template: >
          {% if trigger.event.data.action_type == "tap_twice" %}
            script.cube_tap_twice
          {% elif trigger.event.data.action_type == "flip90" %}
            script.light_color_temp
          {# % else % #}
            {# how to say, stopp and do nothing?, calling a dummy script would work, but is not fine #}
            {# or will a missing elso automatically break the automation? #}
            {#script.dummy_do_nothing #}
          {% endif %}
  ###### only one service works also fine:
  #- service: script.cube_tap_twice
    data_template:
      entity_id: >-
          {% if trigger.event.data.entity_id == "binary_sensor.cube_12345678901234" %}
            {{ "light.dachgeschoss_decke" }}
          {% elif trigger.event.data.entity_id == "binary_sensor.cube_12345678901299" %}
            {{ "light.wohnzimmer_stehlampe" }}
          {% else %}
            {# should not happen #}
            {{ "light.germo_schreibtisch" }}
          {% endif %}

I’ve wondered the same thing. I ran into this over a year back and ended up using a dummy script (script.do_nothing). It’s worked well and I haven’t looked back.

Unfortunately I do not remember if I had any issues without calling a dummy service or if I initially created a dummy service and just never cared try without it because it worked ok.

1 Like

Yes, you can create and call a “dummy” script if you don’t want to do something for that particular step under some particular set of conditions.

But if you also don’t want to do later steps as well, then insert a condition step before that step. If the condition evaluates to false, the remaining steps of the automation actions will not be executed.

This is interesting.

I have at least one script that runs with an if … else and nothing in the else. In one of them the if evaluates true only twice a year and I have not had any problems (that I know of!).

:slight_smile:

I guess I’d need to look at your script, but if you call service_template, and the template evaluates to nothing, that will definitely (er, I think) cause an error.

Here is an example, I think I found three others

 - service_template: >
     {% if (now().month == 1 and now().day == 2) or
           (now().month == 3 and now().day == 4)  %}
        script.birthday_greeting
      {% else %}
      {% endif %}

Maybe it is causing an error?
I’ll try and check my logs again next time one of these scripts run. I think it is always the last step in the process
which may be ‘hiding’ the error.

I’m pretty sure this will cause an error if the expression evaluates to false. And, BTW, in general, the {% else %} is unnecessary in this type of statement (i.e., nothing in the else.)

Since i was curious on a definitive answer, i threw the following test code into my dev env:

script:
  test:
    sequence:
      - service_template: >
          {% if 1 == 0 %}
            notify.telegram
          {% endif %}
        data:
          message: 'test'

When executing this script, it errors out with the following:

ERROR (MainThread) [homeassistant.helpers.service] Template rendered invalid service: 

I also tested with the empty “else” clause and it returned the same error. However, once i added ‘notify.telegram’ to the “else” clause it executed without error (as expected).

So to summarize, you have to use a “dummy” script or it will throw the “Template rendered invalid service” error in your logs.

OK, i will use a dummy-Script. But even without that I did not get errors in the log, even if the cube fires other action types which are not covered by my action_type-to-script logic. it looks like the assigned script is empty in this case and this doesn’t cause a logged error. Strange, but also fine.

This was only an additional minor point of my issue.
My main question is: how I should write the condition to use the trigger action_type. What is wrong in my thinkings and tests, some of them are still in the comments?

You’re right (not that I doubted you :slight_smile:) I checked my logs this morning and indeed my script has been ERROR’ing every day but as I said being the last step in the process it hasn’t actually mattered so passed under my radar.

It seems strange to me, I had it indoctrinated into me that ifthenelseend constructs must always deal with every possible case, including unexpected possibilities, and to do that an empty else, whilst not great was the bare minimum. Every language I have ever used allows an empty else. I believe IBM Asssembler even had a ‘no operation’ instruction for that very reason but that was 30 years ago so I may be wrong.

Is it because we are using a templates rather than a native ‘language’?

.

my else was not empty but there was no else at all. That’s why I think a service was not assigned and hassio can handle this and will not call any script at all. anyway this is a little bit “dirty”.
But I am still very new with yaml, and all these things. My main business are databases where I use T-SQL and MDX for analytical databases :slight_smile:

I think you’re confusing the if statement construction with the result of the if statement. In this case the issue is using service_template with a template that returns nothing in some cases. The nothing is the problem, not how you got there. As I said above, if you don’t have anything in an else clause, then there’s not point to having the else clause – either way you get nothing. But in this case – i.e., service_template – you do always need the if statement to generate a valid service to call, even if it’s a – wait for it … – a NOP! Which, for a service_template, can be a “dummy” script (i.e., a script that exists, but that does nothing.)

1 Like

As has been discussed, using service_template with a template that doesn’t evaluate to a valid service (such as a script name) will cause an error. I don’t know why you’re not seeing them. Maybe you have set your logging level to critical???

Anyway, given your originally posted automation, I think the best choice would be to simply have an else that invokes a so-called dummy script. You could use a condition step, but then you would pretty much have to duplicate most of the template from your service_template step anyway, which would tend to be error prone trying to keep them both in sync.

I tried to avoid some not required overhead, but you are right, the advantage to call an “do-nothing-script” would be to have the logic only in one place.