Create a dictionary with dynamic structure with templating

I agree.

action:
  - choose:
      - conditions: "{{ is_state(trigger.entity_id, 'Aus') }}"
        sequence:
          - service: light.turn_off
            data:
              entity_id: light.wohnzimmer
              transition: -1
    default:
      - service: hue.hue_activate_scene
        data:
          group_name: Wohnzimmer
          scene_name: '{{ states(trigger.entity_id) }}'

How about loops? You could use templates to generate a list for options.

use repeat for loops. Make a list and store it in a variable, then use repeat.index to grab each item as you move through the repeat. This can also be combined with choose. The current automation engine is excellent and can pretty much do anything in yaml without templates. Templates only compliment them. And if youā€™re good enough, you can take long yaml automations and tighten them up with variable templates.

Show me an example of a template that does that. Remember, weā€™re talking about a template that generates options (like the one I posted above).

Iā€™m so excited. I actually get to answer a question for petro! I stumbled across your comment here looking for something totally different (info on zwave.refresh_values).

The data: parameter of a service call DOES accept a template! I didnā€™t realize it myself until I tried it out helping out a fella on this thread. Maybe this has been added since your comment (this is an old thread after all) but I really donā€™t want to go back through all the release notes to check.

That guy never did report back if it worked for him but I tried it out locally with a test script to call another script in my config and it worked a treat.

Test Script
test_alarm_options:
  alias: 'Test Alarm Options'
  fields:
    zone:
      description: 'Alarm zone.'
    mode:
      description: 'Alarm arm mode.'
    code:
      description: 'Alarm arm code.'
    override:
      description: 'Bypass open sensors.'
  variables:
    zone: "{{ zone|default('') }}"
    mode: "{{ mode|default('') }}"
    code: "{{ code|default('') }}"
    override: "{{ override|default('') }}"
    options: >
      {% set option_dict = namespace(value='') %}
      {% set options = ['zone','mode','code','override'] %}
      {% set values = [zone,mode,code,override] %}
      {% for item in options %}
        {% if values[loop.index0] != '' %}
          {% set option_dict.value = option_dict.value
              ~ '"' ~ item ~ '":"'
              ~ values[loop.index0] ~ '"' ~ ',' %}
        {% endif %}
      {% endfor %}
      {{ '{' ~ option_dict.value[:-1] ~ '}' }}
  sequence:
    - service: script.arm_alarm
      data: '{{ options }}'

image

Iā€™m sure there has to be a more efficient way to do it, but this does work.

I do have a question. Is there an easier way to build the dictonary? I did something very similar here but it feels like there should be an easier way to work with the dictonary than building it as a string. Maybe not since that was the approach @123 used in this thread.

4 Likes

It was added by koying and incorporated into the November 2021 release.

I havenā€™t used it yet but itā€™s an interesting addition to oneā€™s toolkit.

1 Like

Hah, yes. @koying added it a bit ago, been using it for some time. Thanks for the heads up though!

1 Like

I use it to get around validation on yaml, like when you need to put a string representation of an object in a notification message. Normally that would fail with ā€œMessage needs to be a stringā€, but if you template the whole data section, it doesnā€™t validate the data for message.