Automation template generates correct output but fails with dict error

I have this automation set up to notify me about which plane is overhead. The template to generate the ‘message’ part, which is a concatenation of elements from the trigger, works perfectly. The ‘data’ part I would like to be dependant on some properties and that template logic seems to work fine (generate YAML) as well, but the action fails and the traceback mentions a dict error. I know it has to do with syntax but as far as I can see it should work. Indentation seems correct as well (which is why the |- is in the template). What am I overlooking or doing wrong here?

alias: Notify airplane
description: ""
triggers:
  - event_type: flightradar24_entry
    trigger: event
conditions:
  - condition: state
    entity_id: input_boolean.automation
    state: "on"
actions:
  - action: notify.lametric
    data:
      message: >-
        Flight{% if trigger.event.data.callsign is not in [none, '', 'Blocked']
        %} {{ trigger.event.data.callsign }}{% endif %}{% if
        trigger.event.data.aircraft_model is not in [none, ''] %} of type {{
        trigger.event.data.aircraft_model }}{% endif %}{% if
        trigger.event.data.airport_origin_city is not in [none, ''] %} from {{
        trigger.event.data.airport_origin_city }} {% if
        trigger.event.data.airport_origin_country_code is not in [none, '']
        %}({{trigger.event.data.airport_origin_country_code }}){% endif %}{%
        endif %}{% if trigger.event.data.airport_destination_city is not in
        [none, ''] %} to {{ trigger.event.data.airport_destination_city }}{%
        if trigger.event.data.airport_destination_country_code is not in [none,
        ''] %} ({{ trigger.event.data.airport_destination_country_code }}){%
        endif %}{% endif %} passes{% if trigger.event.data.altitude is not
        in [none, ''] %} at {{ trigger.event.data.altitude | multiply(0.3048) |
        round(0)}}m height{% endif %}.
      data: |-
        {% if trigger.event.data.altitude | multiply(0.3048) < 5000 %}sound: 'notification3'{% endif %}
        icon: '49029'
        cycles: 2
        priority: {% if trigger.event.airport_destination_code_iata == 'XXX' or
        trigger.event.airport_destination_code_iata == 'YYY' %}'critical'{% else
        %}'info'{% endif %}
mode: single

The traceback looks like this:

params:
  domain: notify
  service: lametric
  service_data:
    message: >-
      Flight TEST123 of type Airbus A330-941 from Somewhere (AB) to Overthere (CD) passes at 5829m height.
    data: |-
      icon: '49029'
      cycles: 2
      priority: 'info'
  target: {}
running_script: false

yet also reports “expected dict for dictionary value @ data[‘data’]”

You can’t template the structure of yaml like this. The YAML parser treats everything after the |- like a string even though it looks to your human eyes exactly like what a dictionary looks like. Instead you’ll have to have an if block in the automation based on the altitude where the if and the else both have the notify action (one with the sound key under data and one without).

That explains it and it confirms a suspicion I already had.

Your solution goes against my desire to DRY but I’ll try and mess around with macro’s to get around that.

Thanks for your insight!

You can use variables for the message and the priority at least to not have to repeat those templates.

You should be able to template the value for data, you just have to have your template return a dictionary instead of a dictionary-shaped string.

{% set base_list = [("icon", "49029"), ("cycles", 2) ] %}
{% set sound_list = [("sound", "notification3")] if trigger.event.data.altitude | multiply(0.3048) < 5000 else [] %}
{% set pri = "critical" if trigger.event.data.airport_destination_code_iata in ["XXX", "YYY"] else "info" %}
{% set pri_list = [("priority", pri)] %}
{{ dict(base_list + sound_list + pri_list) }}
1 Like

Hi 6hfe8z6vaaitjb,

I was going to suggest to put that in a variable for other reasons as well.

That’s indeed what I did, result is this - works perfectly so thanks again:

alias: Notify airplane (LaMetric)
description: ""
triggers:
  - event_type: flightradar24_entry
    trigger: event
conditions:
  - condition: state
    entity_id: input_boolean.automation
    state: "on"
actions:
  - variables:
      message: >-
        Flight{% if trigger.event.data.callsign is not in [none, '', 'Blocked']
        %} {{ trigger.event.data.callsign }}{% endif %}{% if
        trigger.event.data.aircraft_model is not in [none, ''] %} of type {{
        trigger.event.data.aircraft_model }}{% endif %}{% if
        trigger.event.data.airport_origin_city is not in [none, ''] %} from {{
        trigger.event.data.airport_origin_city }} {% if
        trigger.event.data.airport_origin_country_code is not in [none, '']
        %}({{trigger.event.data.airport_origin_country_code }}){% endif %}{%
        endif %}{% if trigger.event.data.airport_destination_city is not in
        [none, ''] %} to {{ trigger.event.data.airport_destination_city }}{%
        if trigger.event.data.airport_destination_country_code is not in [none,
        ''] %} ({{ trigger.event.data.airport_destination_country_code }}){%
        endif %}{% endif %} passes{% if trigger.event.data.altitude is not
        in [none, ''] %} at {{ trigger.event.data.altitude | multiply(0.3048) |
        round(0)}}m{% endif %}.
  - choose:
      - conditions:
          - condition: template
            value_template: |-
              {{
                true if trigger.event.data.airport_destination_code_iata == 'XXX' or
                trigger.event.data.airport_destination_code_iata == 'YYY'
                else false
              }}
        sequence:
          - action: notify.lametric
            data:
              message: "{{ message }}"
              data:
                sound: notification3
                cycles: 2
                icon: "49029"
                priority: info
      - conditions:
          - condition: template
            value_template: |-
              {{ 
                true if trigger.event.data.altitude | multiply(0.3048) < 5000
                else false
              }}
        sequence:
          - action: notify.lametric
            data:
              message: "{{ message }}"
              data:
                cycles: 2
                icon: "49029"
                priority: critical
    default:
      - action: notify.lametric
        data:
          message: "{{ message }}"
          data:
            cycles: 2
            icon: "49029"
            priority: info
mode: single

I did not know about this as being ‘the jinja way’ for it. That’s very handy for future reference - thanks!