Returning a list from a template

I’m trying to figure out how to get a template to produce a list that can be consumed as a list by a service call. Specific case right now is to enumerate a list of scenes, and send that list to an input_select as a list of available options

Currently, this is what I have:

  - service: input_select.set_options
    data_template:
      entity_id: "input_select.hasp_plate01_page1button4scene"
      options: "[{% for item in states.scene %}'{{ item.entity_id }}'{% if not loop.last %}, {% endif %}{% endfor %}]"

That template renders as ["scene.daylight", "scene.lights_off", "scene.lights_on", "scene.night"] which, if pasted into the service call, works like expected. However, I’m pretty sure it’s just rendering as a long string and I think I need it to somehow be returning a list.

Is this possible?

One data point - this approach worked w/ group.set back when that was a thing.

A template always produces a single string. As far as I know, what you want to do is not possible.

You can create a list like this:
options: ["some template code", "some template code", "some template code"]

but as far as I know you can’t use this with a loop.

If that’s the case, it means there is no way to accomplish this unless you know the number of elements in the list ahead of time.

Yep, looks like this is the case.

Any insight as to why that worked w/ group.set? Is this due to some special handling of entity_id such that it will be handled as a list?

And if so - is there any documentation on where one can parse a template as a list, and where I can’t?

Yes

No, there isn’t.

Entity_id is the only place this happens, and it only happens on specific services. All other fields are treated as single strings.

1 Like

You could use a python script.

For group.set, the content validator is using cv.entity_ids

https://github.com/home-assistant/core/blob/7c79adad8f7e047a578ac1db4fa180029d4abb56/homeassistant/components/group/init.py#L311

http://dev-docs.home-assistant.io/en/master/api/helpers.html#homeassistant.helpers.config_validation.entity_ids

This is specifically handling a string list.

1 Like

Yep, which options does not use because it’s not expecting entity_id’s.

Roger that, thanks for the quick response!

If it weren’t for inconsistency, there’d be no consistency at all…

I don’t remember all details and not sure if it is applicable in your case but some used from_json and to_json to pass a lists (or dict?) between automations.

This would only work for going between state objects -> templates. Won’t really work for a service call unfortunately.

FWIW, even if there were a way to write that template, your example contains a syntax error that would prevent the end-result from being interpreted as a list.

      options: "[{% for item in states.scene %}'{{ item.entity_id }}'{% if not loop.last %}, {% endif %}{% endfor %}]"

You’ve wrapped the whole thing in double-quotes, thereby guaranteeing it will be interpreted as a string.

It should look like this:

      options: ["{% for item in states.scene %}'{{ item.entity_id }}'{% if not loop.last %}, {% endif %}{% endfor %}"]

To be clear, that still won’t work (because of the reasons already given) but at least that’s the proper syntax.

For example, this works (but doesn’t meet your requirement of being dynamically generated).

        options: ["{{(states.scene|list)[0].entity_id}}", "{{(states.scene|list)[1].entity_id}}"]
2 Likes

looks like it it won’t.

@luma I think you need to look at your task from a different angle. Don’t know all the details, but a python script can easily fill in an input_select with whatever you want, just decide on when and with what.

Agreed, that appears to be the only option here. Thanks for your help!

1 Like