Dynamic state access for dynamic script fields

I want to run a script select_maintenance_task to select an “asset” option in an input_select. It looks something like this obviously. My question relates to parameterising the option.

...
sequence:
        - service: input_select.select_option
          target:
            entity_id: input_select.maintenance_asset
          data:
            option: "selected option"
...

The script is called via a call service from a card tap action as below.

...
tap_action:
      action: call-service
      service: script.select_maintenance_task
      data:
        ...     

The card doesn’t know the “asset” in question so it can’t simply pass that as a variable which the script could then use (passing-variables-to-scripts).

It just knows it is either task 0, task 1 or task 2. It gets its label by looking that index up in the attributes of an entity called maintenance_tasks which has attributes like below.

This way I can add several cards, each with a different index and their label dynamically generated. The attributes of maintenance_tasks change, so this is all necessary.

task_0_asset: Outdoor Blinds
task_1_asset: Food Fridge
task_2_asset: Washing Machine

I need to pass the “asset” to the script. I experimented with using templates for the data in the service call of the card tap_action but understand you cannot use templates here.

eg: this doesn't work
...
tap_action:
      action: call-service
      service: script.select_maintenance_task
      data:
        asset: {{ state_attr('var.maintenance_tasks', 'task_0_asset') }}
...

I’ve then looked at simply passing the index and getting the script to find the asset via lookup from the state attributes of maintenance_tasks.

eg: this part works obviously
...
tap_action:
      action: call-service
      service: script.select_maintenance_task
      data:
        index: 0
...

…but then I hit snags in the script trying to lookup the attribute value. Below I show two failed attempts.

script:
    select_maintenance_task:
      ...
      fields:
        index:
          description: '0-based index of UI element corresponding to the upcoming task.'
          example: 0
      sequence:
        - service: input_select.select_option
          target:
            entity_id: input_select.maintenance_assets
          data:
        **this doesn't work...**
            option: |
              {% set attribute = 'task_' + {{ index }} + '_asset' %}
              {{ state_attr('var.maintenance_tasks', attribute) }}"
        **nor this...**
            option: |
              {% set attribute = 'task_' + {{ index }} + '_asset' %}
              {{ state_attr('var.maintenance_tasks', attribute) }}"
        **or this...**
            option: "{{ state_attr('var.maintenance_tasks', 'task_{{ index }}_tasl' ) }}"
...

Is there any way I can achieve this dynamic access of state?

Dumb question. Correct answer is:

option: "{{ state_attr('var.maintenance_tasks', 'task_'+index+'_asset' ) }}"

As you have discovered, you can’t nest templates and that’s why all three versions in your first post failed.

Be advised that you can concatenate strings using + or ~. The plus operator is also used to compute the sum of numbers so it can sometimes produce an unexpected result when the intention is for concatenation. That’s why the tilde operator exists and serves no other purpose than concatenation.

option: "{{ state_attr('var.maintenance_tasks', 'task_' ~ index ~ '_asset') }}"

Another way to achieve the same result is to use a script variable.

      sequence:
        - variables:
            idx: 'task_{{ index }}_asset'
        - service: input_select.select_option
          target:
            entity_id: input_select.maintenance_assets
          data:
            option: "{{ state_attr('var.maintenance_tasks', idx) }}"

Thanks, both are great suggestions.

I wasn’t aware of the ~. Saves using index|string.

It’s working as I have it in my second post but I’ll also try the variables based approach for interest.