Using templates in a select selector script field

I’m trying to create a select field in a script that is populated by a list of items stored in a sensor. Is there a way to do that?

I haven’t been able to find any documentation or posts about using templates in a select selector script field, so it’s mostly a guessing game. I’ve tried a few different options for enumerating the labels and values for the favorites in the list, but it’s unclear what the select selector supports (if anything). My latest attempt used a for loop:

sonos_favorite:
  selector:
    select: |
      {% for media_id, name in state_attr("sensor.sonos_favorites", "items").items() %}
      - label: {{ name }}
        value: {{ media_id }}
      {% endfor %}
  name: Favorites
  description: Select a Sonos favorite (overrides content type)

Unfortunately it throws an error when trying to save the script saying that it expected a dictionary. I’m not sure how to format a dictionary with the correct select fields. Does anyone have any advice?

In cases where you need to supply a dictionary, you cannot use templates to generate the yaml structure. I did have luck one time using a template to pass json data to an element that required a dictionary, but I’m not sure if that would work here.

However, are your favorites changing so much that this really needs to be dynamic? You could plug this template into the developer tools template page, and paste the results into to the selector. You’ll have to do it again if you add or remove favorites, but probably not a thing that happens that often?

I’ve got some scripts I use to store and retrieve JSON data from a text input field that might be what you’re looking for: homeassistant_tidbits/scripts at main · posicat/homeassistant_tidbits · GitHub

Technically that solution would work (and I’ve implemented it in the interim), but ideally I’d like to avoid the hassle updating the script whenever a new favorite is added. While it might be infrequent, it’s something I’d need to remember and introduces the possibility of confusion.

Thanks for sharing! I took a quick look and it appears the scenario might be different. But maybe there’s something that could point me in the right direction? I’ll keep exploring…

Based on the lack of image tags in the Selector docs and a couple quick experiments it doesn’t look like templates are supported there.

If it was possible, you would use a namespace to output an actual list like:

sonos_favorite:
  selector:
    select:
      options: |
        {% set ns = namespace( x=[] ) %}
        {% for media_id, name in state_attr("sensor.sonos_favorites", "items").items() %}
        {% set ns.x = ns.x + [{'label': name, 'value': media_id}] %}
        {% endfor %}
        {{ ns.x }}
  name: Favorites
  description: Select a Sonos favorite (overrides content type)

Does the state of the sensor always match one of the keys from the items attribute?

Bummer. That’s what I’d kind of figured too. Support for templates in a script field would be incredibly useful.

The Sonos Favorites sensor is a bit weird. The state always shows the total number of favorites. The list of favorites can be accessed using the sensor’s items attribute, and the value can be used to initiate playback using another service call.

It’s a bit of a hack, but… What if you set up a Template Select that pulls it’s Options from that attribute? Then you could use a State selector in the script that pulls from the Template Select.

Brilliant! I’d never used template selects before, but I found one of your other posts with some examples that really helped. That, plus the conveniently-timed release of UI support for creating template select entities. I was able to get it to show up properly in the script and return the correct media_id based on the friendly name of the playlist.

For those reading this later, here’s what I did:

  1. Create a template select entity and an input_text helper to save the most recent selection:

State template:

{{ states('input_text.sonos_favorites_last_selected') }}

Available options:

{{ state_attr("sensor.sonos_favorites", "items").values() | list }}

Action on select:

action: input_text.set_value
metadata: {}
data:
  value: "{{ option }}"
target:
  entity_id: input_text.sonos_favorites_last_selected
  1. Add this template select as a field in the script:
favorite:
  selector:
    state:
      entity_id: select.sonos_favorites
  name: Favorites
  description: Select a Sonos favorite (if multiple are selected one is chosen at random)
  required: false
  1. Once we have the name of the favorite, we have to look up the media_id in the favorites sensor that matches that name:
variables:
  final_content_id: |
    {% for media_id, name in state_attr("sensor.sonos_favorites", "items").items() %}
      {% if name == favorite %}
        {{ media_id }}
      {% endif %}
    {% endfor %}
alias: Finalize content type and content ID

The only downside is that I don’t see a way to make the template select entity multi-select. My original implementation with a hard-coded selector lets users multi-select favorites. @Didgeridrew do you know if that’s possible with a template select entity? I didn’t see a way to do it.

Nothing built in… there has been a proposal for multiselect open for a while, but AFAIK it’s still in the discussion phase.

You can use a trigger-based template sensor to store a history of selections.

See also: https://community.home-assistant.io/t/trigger-based-template-sensor-to-store-global-variables/735474 for a more expansive option using custom events.

Ah darn. The multiselect option for the select script field is very nice. I’d love to have that option for template select entities too.

At least I have a solution for now for dynamically populating the field if I want. I’ll have to think about whether it’s better to keep it dynamic or have multiselect support.

Thanks for all of your help!