Trouble with data_template if/else

Hi,

I’m trying to get an automation working, where a specific script should be turned on depending on which binary sensor triggered the automation.
For some reason I can’t get the automation to fire any other than the first script in my data_template action.

  action:
  - data_template:
      entity_id: '{%if "trigger.to_state.entity_id","binary_sensor.stue_altandoer_sensor"%}script.1586436129877{%elif "trigger.to_state.entity_id","binary_sensor.spisestue_altandoer_sensor"%}script.1586436129878{%elif "trigger.to_state.entity_id","binary_sensor.sovevaerelse_altandoer_sensor"%}script.1586436129879{%elif "trigger.to_state.entity_id","binary_sensor.kontor_altandoer_sensor"%}script.1586436129880{%endif%}'
    service: script.turn_on

Any idea why?

  action:
    service _template: >
      {% if trigger.to_state.entity_id == binary_sensor.stue_altandoer_sensor %} script.1586436129877
      {% elif trigger.to_state.entity_id ==  binary_sensor.spisestue_altandoer_sensor %} script.1586436129878 

Etc

You got a bunch of issues.

  1. Your if and else if statements are doing nothing for you. It will hit the first if statement every time and script.1586436129877 will always be executed. This is because the way you wrote the if statement.
    {% if "trigger.to_state.entity_id", "binary_sensor.stue_altandoer_sensor" %}
    Will always be True because you’re saying if this string is not empty, and then you provide it 2 non-empty strings.

  2. You’re not actually checking the trigger object. You have the correct name for it, but then you place quotes around it, turning it into a string. "trigger.to_state.entity_id" is a string trigger.to_state.entity_id is the trigger object. Notice the lack of quotes?

  3. You need to verify that the entity_id equals the sensor you care about. This is done with a double equal sign. ==

  4. You writing this in a way that is extremely hard to read and debug. Do yourself a favor and use multiline templating. This is indicated with a > after the field in question.

  5. You don’t have a fallback plan. I.e. an else statement. What happens if your entity_id doesn’t match anything? This is typically controlled by your trigger, but we can’t see it. It would be best to have a fallback.

In the end you’ll have this:

      entity_id: >
        {% if trigger.to_state.entity_id == "binary_sensor.stue_altandoer_sensor" %}
          script.1586436129877
        {% elif trigger.to_state.entity_id == "binary_sensor.spisestue_altandoer_sensor" %}
          script.1586436129878
        {% elif trigger.to_state.entity_id == "binary_sensor.sovevaerelse_altandoer_sensor" %}
          script.1586436129879
        {% elif trigger.to_state.entity_id == "binary_sensor.kontor_altandoer_sensor" %}
          script.1586436129880
        {% else %}
          script.fallback_or_whatever
        {% endif %}

Also, if you really want to make this expandable with little to no overhead when adding a new binary sensor, you can use a dictionary to get the job done.

      entity_id: >
        {% set sensors = {
          'binary_sensor.stue_altandoer_sensor': 'script.1586436129877',
          'binary_sensor.spisestue_altandoer_sensor': 'script.1586436129878',
          'binary_sensor.sovevaerelse_altandoer_sensor': 'script.1586436129879',
          'binary_sensor.kontor_altandoer_sensor': 'script.1586436129880',
        } %}
        {% if trigger.to_state.entity_id in sensors %}
          {{ sensors[trigger.to_state.entity_id] }}
        {% else %}
          script.fallback_or_whatever
        {% endif %}

Then all you need to do when you get a new script and binary sensor is add to the sensors dictionary.

          'binary_sensor.something_new': 'script.something_new',
2 Likes

Now that is a comprehensive set of rules to live and test by !
:+1:

Thank you so much for the answers, especially @petro for the very extensive one! Learning new stuff every day.
I’m quite new to code, so this community really is a big help, even thou I still have trouble wrapping my head around a lot of it.

The reason for not having a fallback in this automation was that I specify exactly the possible entity_id’s, so nothing else than the ones listed, should be a possibility.

I’ve changed format like you recommended. The automation works now, but I still get a few errors:

Notify dør åben i 20 min: Error executing script. Invalid data for call_service at pos 1: extra keys not allowed @ data['data']
Notify dør åben i 20 min: Error executing script. Invalid data for call_service at pos 1: not a valid value for dictionary value @ data['entity_id']
Notify event sluk varme: Error executing script. Invalid data for call_service at pos 1: not a valid value for dictionary value @ data['entity_id']

Here is the complete set of automations. Basically it’s supposed to notify me or my wife, if a door or window has been open for more than 20 minutes, then give us the option to either turn off the heating in the specific room (1. action in the notification) or leave it alone (2. action).
So the first automation fires a script for one of the four rooms, which then handles sending the notification, if specific criteria are met.
The second automation handles the selected action of the notification.
My problem at the moment is that I can’t seem to understand, how to make it act on the event of the notification. This has worked before, but only for one room. Should the formatting be different in this case?

- id: '1586125446593'
  alias: Notify dør åben i 20 min
  description: ''
  trigger:
  - entity_id: binary_sensor.spisestue_altandoer_sensor
    for: 00:20:00
    platform: state
    to: 'on'
  - entity_id: binary_sensor.stue_altandoer_sensor
    for: 00:20:00
    platform: state
    to: 'on'
  - entity_id: binary_sensor.kontor_altandoer_sensor
    for: 00:20:00
    platform: state
    to: 'on'
  - entity_id: binary_sensor.sovevaerelse_altandoer_sensor
    for: 00:20:00
    platform: state
    to: 'on'
  condition:
  - condition: template
    value_template: '{{ (state_attr(''weather.hjem'',''temperature'')) < 20 }}'
  action:
  - data_template:
      entity_id: >
        {% if trigger.to_state.entity_id == "binary_sensor.stue_altandoer_sensor" %}
          script.1586436129877
        {% elif trigger.to_state.entity_id == "binary_sensor.spisestue_altandoer_sensor" %}
          script.1586436129878
        {% elif trigger.to_state.entity_id == "binary_sensor.sovevaerelse_altandoer_sensor" %}
          script.1586436129879
        {% elif trigger.to_state.entity_id == "binary_sensor.kontor_altandoer_sensor" %}
          script.1586436129880
        {% endif %}
    service: script.turn_on
- id: '1586173156892'
  alias: Notify event sluk varme
  description: ''
  trigger:
  - event_data:
      action: tado_sluk_stue
    event_type: mobile_app_notification_action
    platform: event
  - event_data:
      action: tado_sluk_spisestue
    event_type: mobile_app_notification_action
    platform: event
  - event_data:
      action: tado_sluk_sovevaerelse
    event_type: mobile_app_notification_action
    platform: event
  - event_data:
      action: tado_sluk_kontor
    event_type: mobile_app_notification_action
    platform: event
  condition: []
  action:
  - data_template:
      entity_id: >
        {% if trigger.event.data == "action: tado_sluk_stue" %}
          climate.stue
        {% elif trigger.event.data == "action: tado_sluk_spisestue" %}
          climate.spisestue
        {% elif trigger.event.data == "action: tado_sluk_sovevaerelse" %}
          climate.sovevaerelse
        {% elif trigger.event.data == "action: tado_sluk_kontor" %}
          climate.kontor
        {% endif %}
    service: climate.turn_off
  - data_template:
      data:
        tag: >
          {% if trigger.event.data == "action: tado_sluk_stue" %}
            tado_stue
          {% elif trigger.event.data == "action: tado_sluk_spisestue" %}
            tado_spisestue
          {% elif trigger.event.data == "action: tado_sluk_sovevaerelse" %}
            tado_sovevaerelse
          {% elif trigger.event.data == "action: tado_sluk_kontor" %}
            tado_kontor
          {% endif %}
      message: clear_notification
    service: notify.cassar

Why did HA after my last update format the code like this??? I certainly didn’t do it.

  action:
  - data_template:
      entity_id: "{% if trigger.to_state.entity_id == \"binary_sensor.stue_altandoer_sensor\"\
        \ %}\n  script.1586436129877\n{% elif trigger.to_state.entity_id == \"binary_sensor.spisestue_altandoer_sensor\"\
        \ %}\n  script.1586436129878\n{% elif trigger.to_state.entity_id == \"binary_sensor.sovevaerelse_altandoer_sensor\"\
        \ %}\n  script.1586436129879\n{% elif trigger.to_state.entity_id == \"binary_sensor.kontor_altandoer_sensor\"\
        \ %}\n  script.1586436129880\n{% endif %}\n"
    service: script.turn_on

This usually happens when you open the automation in GUI editor and save it

2 Likes

The Automation Editor is well known for not only having limitations, it stores its data in YAML format that is perfectly legal but with compromised legibility. The primary complaint is that it sorts key names alphabetically thereby stripping it of its original logical order. Other complaints are its handling of quotation marks and newlines.

Whatever you do, never use it to edit and save an automation you had created manually. Not only will it reformat it (the way I’ve described and he way you’ve experienced), it will remove comments you had included (because the Automation Editor doesn’t support comments).

FWIW, I have my automations organized like this:

automation: !include automations.yaml
automation manual: !include_dir_merge_list automations/
  • Automations created by the Automation Editor are stored in automations.yaml
  • Automations I create with a text editor are stored in multiple files within the automations directory.

This helps to prevent one from using the Automation Editor to accidentally edit and save a manually created automation.

Thank you for you description.
This sounds like a very good idea! Just to be sure to understand it correctly, you have an individual xyz.yaml for each manually created automation in the automations/ folder?

Another method is "don’t list your automations with " - id: " just with " - alias: " and the editor should steer clear of them
Edit: DON’T do this. See : -

1 Like

Another method is "don’t list your automations with " - id: " just with " - alias: " and the editor should steer clear of them

So you would still be able to edit in the UI then, or when would it steer clear?

The ui will list all automations but simply won’t allow you to edit ones ‘without’ an id
It’s quick and dirty but Taras’s suggestion is ‘more’ flexible as you get the best of both worlds.

True but if manually-created automations are stored in automations.yaml that’s the file used by Automation Editor to store its automations. When it saves its automations, it strips all comments found in the file and sorts options alphabetically. I learned this, as they say, the ‘hard way’.

I could if I wanted to but I don’t. Each file contains several automations, all related to a specific purpose. For example, ‘pool.yaml’ contains all automations that control the pool pump and lights.

Oh S41T !!!, I’ll go back and edit those posts ! :flushed:

I posted my newfound knowledge (which I could have gained, with less frustration, by simply reading the documentation) in this topic: School of hard Knocks: the Automation Editor. A classic case of “RTFM”.