Templating and YAML woes

Hi,

I’m trying to put a script together but something is wrong in my formatting that I can’t find. this is the error:

“Failed to perform the action script/vestaboard_message_with_options. expected a dictionary @ data[‘vbml’][‘components’][0]”

I can’t figure out why the components block isn’t showing as a dictionary. I know it has something to do with my templating, but I don’t know why.

Thanks

sequence:
  - variables:
      alert_color: |-
        {% set mappings = {
          'none':'{0}',
          'red':'{63}',
          'blue':'{67}',
          'green':'{66}',
          'yellow':'{65}',
          'orange':'{64}',
          'violet':'{68}',
          'white':'{69}'
        } %} "{{ mappings.get(alert, '{63}') }}"
    enabled: true
  - action: vestaboard.message
    metadata: {}
    data:
      device_id:
        - id1231231
      vbml:
        props:
          text: "{{ words }}"
          alert_color: "{{ alert_color }}"
          date: "{{ as_timestamp(now())|timestamp_custom('%d') }}"
          month: "{{ as_timestamp(now())|timestamp_custom('%b') }}"
          hours: "{{ as_timestamp(now())|timestamp_custom('%H') }}"
          day: "{{ as_timestamp(now())|timestamp_custom('%A') }}"
          minutes: "{{ as_timestamp(now())|timestamp_custom('%M') }}"
          temp: "{{ state_attr('weather.openweather','temperature') | int}}"
          temp_color: >-
            {% if state_attr('weather.openweather','temperature') | float <= 32
            %}
              {69}
            {% elif state_attr('weather.openweather','temperature') | float <=
            55 %}
              {67}
            {% elif state_attr('weather.openweather','temperature') | float <=
            75 %}
              {66}
            {% elif state_attr('weather.openweather','temperature') | float <=
            90 %}
              {65}
            {% else %}
              {63}
            {% endif %}
        components: |-
          {% if alert != 'none' %}
            - style:
                justify: center
                align: center
                width: 22
                height: 5
              template: "{{ alert_color * 22 }}"
            - style:
                justify: center
                align: center
                width: 1
                height: "{{ '3' if status_bar else '4' }}"
              template: "{{ (alert_color * 3) if status_bar else (alert_color * 4) }}"
          {% endif %}
          - style:
              justify: center
              align: center
              width: "{{ '20' if alert != 'none' else '22' }}"
              height: >-
                {% if alert != 'none' and status_bar %}
                  3
                {% elif status_bar %}
                  5
                {% elif alert != 'none' %}
                  4
                {% else %}
                  6
                {% endif %}
            template: "{{ '{{text}}' }}"
          {% if alert != 'none' %}
            - style:
                justify: center
                align: center
                width: 1
                height: "{{ '3' if status_bar else '4' }}"
              template: "{{ (alert_color * 3) if status_bar else (alert_color * 4) }}"
            - style:
                justify: center
                align: center
                width: 22
                height: 5
              template: "{{ alert_color * 22 }}"
          {% endif %}
          {% if status_bar %}
            - style:
                justify: left
                align: center
                width: 5
                height: 1
              template: "{{ '{{date}}{{month}}' }}"
            - style:
                justify: center
                align: center
                width: 12
                height: 1        
              template: "{{ '{{day}}' }}"
            - style:
                justify: right
                align: center
                width: 5
                height: 1        
              template: "{{ '{{temp}}{62}{{temp_color}}' }}"  
          {% endif %}
fields:
  words:
    selector:
      text: null
    description: The text to display on the Vestaboard
    required: true
  status_bar:
    selector:
      boolean: {}
    description: Show the Date, Day, and temp status bar at the bottom
    default: false
  alert:
    selector:
      select:
        options:
          - none
          - red
          - blue
          - green
          - yellow
          - orange
          - violet
          - white
    default: none
alias: Vestaboard - Message with Options
description: >-
  Lets to send a basic message, with the option to add an alert frame, and a
  status bar.

You cannot interlace YAML into Jinja like you are doing. You need to rewrite the whole components: section. You can try changing the interlaced YAML parts to JSON, but that is always much more error-prone than doing it in pure Jinja. I’d recommend the latter.

Thank you for the help.

When changing it to JSON, is there a guide for that? Or a good example? Ideally one with Jinja interspersed so I can build the conditional parts of the JSON

Thanks Again

I think my issue at this point is indenting? I was under the impression that indenting did not matter with JSON, but apparently that is incorrect.

If someone could help me by giving the proper format for this, I think I can put it together from here.

I’ve simplified this greatly so there are only a few things to look at. If I change 1 == 1 to 1 ==2, then it works and I get no error.

But with 1 == 1 (thus attempting to add in the extra JSON block, I get “Failed to perform the action script/vestaboard_message_with_options. expected a dictionary @ data[‘vbml’][‘components’][0]”

    components: |-
      {
        "style": {
          "justify": "center",
          "align": "center",
          "width": "{{ '20' if alert != 'none' else '22' }}",
          "height": "{% if alert != 'none' and status_bar %}3{% elif status_bar %}5{% elif alert != 'none' %}4{% else %}6{% endif %}"
        },
        "template": "{{ '{{text}}' }}"
        {%- if 1 == 1 -%}
          },
          {
            "style": {
              "justify": "left",
              "align": "center",
              "width": 5,
              "height": 1
            },
            "template": "{{  '{{date}}{{month}}' }}"
          {%- endif -%}    
      }

Don’t mind the extra curly brackets, that’s a function of the Vestaboard formatting and has already been checked to make sure it’s not causing the error.

Thanks

Indenting shouldn’t matter in JSON, but HA can be picky when reinterpreting the output from a template… Most often it is easier to construct the whole dict/list as a variable in Jinja, and then at the very end letting Jinja output the dict/list.

In this particular case though your code isn’t outputting one dict, it would be outputting two dicts separated by a comma. The output of your last template above would result in something like this:

{"style": {...}, "template": "{{text}}"}, {"style:" {...}, "template": "{{date}}{{month}}"}