Input_select.set_options not working with options generated by Jinja

Hi,

I’m using a automation to get new options for a input select:

alias: Sonos-Favoriten Update
trigger:
  - platform: homeassistant
    event: start
action:
  service: input_select.set_options
  data_template:
    entity_id:
      - input_select.sonos_favs
    options: "{{ states.media_player.buro.attributes.source_list|list }}"

“{{ states.media_player.buro.attributes.source_list|list }}” gives me a list:
[‘ANTENNE BAYERN’, ‘hr1’, ‘SWR1 Rheinland-Pfalz’, ‘SWR3 Elchradio’, ‘Top 40’, ‘Zucchero’]

but the card show me all in one line:

If I set the option like this:

  options:
    - ANTENNE BAYERN
    - Top 40
    - hr1
    - SWR1 Rheinland-Pfalz
    - SWR3 Elchradio
    - Zucchero
    - None

and look at the entity state it looks the same way:

Do we have a bug or whats wrong with my config?

Thank you very much, Steffen

What you are trying to do is not possible. So it’s not a bug and nothing’s wrong with your config. Jinja templates only return a single string. Nothing else. Even if you attempt to replicate what looks like a list, the parser will only see it as a string.

The easiest way to do what you want to do would be a python script.

Or

Template each bullet. But your list will always have to be the same size.

OK, do you have a sample for a Phyton Script - I’m not knowledgeable about this …

Thank you, Steffen

Can you I call a very simple Python script at options to convert the string like this:

alias: Sonos-Favoriten Update
trigger:
  - platform: homeassistant
    event: start
action:
  service: input_select.set_options
  data_template:
    entity_id:
      - input_select.sonos_favs
    options: python_script.convert(states.media_player.buro.attributes.source_list)

Thank you.

No, you have to write a python script

And then call it as a service. In the script is where you’d set the list.

Here’s an example python_script that fills an input_select from a group with entities.

group = data.get('group')
input_select = data.get('input_select')

if group is not None and input_select is not None:
    group_entities = hass.states.get(group).attributes['entity_id']
    list = []
    for e in group_entities:
        list.append(e)
    service_data = {'entity_id': input_select,
                    'options': list}
    hass.services.call('input_select', 'set_options', service_data)
else:
    logger.warning('Missing arguments!')

It’s called at HA start with:

      - service: python_script.group2input_select
        data:
          group: 'group.all_switches'
          input_select: 'input_select.all_switches'

The script was from @pnbruckner, if i remember it right.

2 Likes

Thank you very much, I try to modify it and come back here …

Thank you, with your example I can write this:

entity_inputselect = data.get('entity_inputselect ')
entity_optionsstring = data.get('entity_optionsstring')

if  entity_inputselect is not None and entity_optionsstring is not None:

    if '.' in entity_optionsstring:

        # entity_optionsstring is entity
        logger.debug('Type: Entity')

        entityparts = entity_optionsstring.split('.')
        if len(entityparts)>2 and entityparts[2]=='attributes':
            string_elements = hass.states.get(entityparts[0] + '.' + entityparts[1]).attributes[entityparts[3]]
        else:
            string_elements = hass.states.get(entityparts[0] + '.' + entityparts[1]).state

    else:

        # entity_optionsstring is no entity
        logger.debug('Type: String')
        string_elements = entity_optionsstring.split(',')

    logger.debug('string_elements: ')
    logger.debug(str(string_elements))

    option_list = []
    if ',' in str(string_elements):
        for xe in string_elements:
            option_list.append(xe)
    else:
        option_list = string_elements

    logger.debug('option_list: ')
    logger.debug(str(option_list))

    service_data = {'entity_id': entity_inputselect, 'options': option_list}
    hass.services.call('input_select', 'set_options', service_data)

else:

    logger.warning('set_inputselect_optionstring.py: No Data!')

So I can use it for set_options from states, attributes or different strings. Certainly not very good Python but it works and I think for a new Python script writer it is OK? You are welcome to improve …

So now I can online update the input select from my Sonos favorites!

Regards, Steffen

1 Like

Based on what I think your code does, you can optimize it like this:

entity_inputselect = data.get('entity_inputselect ')
entity_optionsstring = data.get('entity_optionsstring')

if  entity_inputselect is not None and entity_optionsstring is not None:

    if '.' in entity_optionsstring:
        # entity_optionsstring is entity
        logger.debug('Type: Entity')

        entityparts = entity_optionsstring.split('.')
        if len(entityparts)>2 and entityparts[2]=='attributes':
            entity_optionsstring = hass.states.get(entityparts[0] + '.' + entityparts[1]).attributes[entityparts[3]]
        else:
            entity_optionsstring = hass.states.get(entityparts[0] + '.' + entityparts[1]).state

    #clean up whitespace, replace '_' with spaces, make them all titles (Example Title)
    option_list = [ e.strip().replace('_',' ').title() for e in entity_optionsstring.split(',') ]

    logger.debug('option_list: ')
    logger.debug(str(option_list))

    service_data = {'entity_id': entity_inputselect, 'options': option_list}
    hass.services.call('input_select', 'set_options', service_data)

else:

    logger.warning('set_inputselect_optionstring.py: No Data!')

Hi Petro,

thank you. Can you explain a littel your command? This part you change I’m want to look if it is a list (if ‘,’ in …) than make a list-element and if not only give the string to the option_list.

Regards, Steffen

it seems like you had some redundancy, unless I miss understood what’s happening there.

Your first if statement checks to see if it’s an entity string. Your else, splits the list up based on commas.

Then later, you check for a comma inside your string elements. At this point, string elements will be a ‘string’ (coming from state), any object (coming from attributes), or a list of strings (comming from else statement). My assumption is that ‘any object (coming from attributes)’ was also going to always be a string.

If that’s not the case, can you please explain what you plan on providing with attributes or from the state of an entity_id?

Your original code doesn’t cover all bases, and neither does mine. It can be made 100% error proof, but i’d need to know what you expect to get from state attributes or the state.

Hi Petro,

thank you learning me a littel Python and working with Hass.io. I have made some optimization:

I want to make a list element and set it as the option list of the input_select. So I want to make it a little bit generic and working for this examples:

# Set online input_select option_list from entity state, attribute or string

# Must be entity of the input_select like 'input_select.sonos_favs'
entity_inputselect = data.get('entity_inputselect')

# A entity or string to make a list from
# entity attribute: media_player.buro.attributes.source_list
# entity state: media_player.buro
# String with a comma list: 'On,Off'
# String only: 'Pause'
entity_optionsstring = data.get('entity_optionsstring')

So after checking the Parameters I check if it is a entity. If it is a get the state or the attribute and save the string to ‘string_elements’. Now after that I split the string an make a list:

if  entity_inputselect is not None and entity_optionsstring is not None:

    option_list = []
    if '.' in entity_optionsstring:

        # entity_optionsstring is entity
        logger.debug('Type: Entity')

        entityparts = entity_optionsstring.split('.')
        if len(entityparts)>2 and entityparts[2]=='attributes':
            string_elements = hass.states.get(entityparts[0] + '.' + entityparts[1]).attributes[entityparts[3]]
        else:
            string_elements = hass.states.get(entityparts[0] + '.' + entityparts[1]).state

        if ',' in str(string_elements):
            for xe in string_elements:
                option_list.append(xe)
        else:
            option_list = string_elements

If it is no entity, it must be a string and I split the list. If the list have no comma:

    else:

        # entity_optionsstring is no entity
        logger.debug('Type: String')
        option_list = entity_optionsstring.split(',')

    logger.debug('option_list: ' + str(option_list))

    service_data = {'entity_id': entity_inputselect, 'options': option_list}
    hass.services.call('input_select', 'set_options', service_data)

else:

    logger.warning('set_inputselect_optionstring.py: No Data!')

Regards, Steffen

# Set online input_select option_list from entity state, attribute or string

# Must be entity of the input_select like 'input_select.sonos_favs'
entity_inputselect = data.get('entity_id')[0]

# A entity or string to make a list from
# entity attribute: media_player.buro.source_list
# entity state: media_player.buro
# String with a comma list: 'On,Off'
# String only: 'Pause'
entity_optionsstring = data.get('data_source')

if entity_inputselect is None and entity_optionsstring is None:
    logger.warning('No data!')
    exit()

current_selection = hass.states.get(entity_inputselect).state
option_list = ['None']

if '.' not in entity_optionsstring:
    option_list = entity_optionsstring.split(',')
else:
    entityparts = entity_optionsstring.split('.')
    if len(entityparts) > 2:
        string_elements = hass.states.get(entityparts[0] + '.' + entityparts[1]).attributes[entityparts[2]]
    else:
        string_elements = hass.states.get(entityparts[0] + '.' + entityparts[1]).state

    if ',' in str(string_elements):
        for xe in string_elements:
            option_list.append(xe)
    else:
        option_list.extend(string_elements)


service_data = {'entity_id': entity_inputselect, 'options': option_list}
hass.services.call('input_select', 'set_options', service_data)

if current_selection in option_list:
    service_data = {'entity_id': entity_inputselect, 'option': current_selection}
    hass.services.call('input_select', 'select_option', service_data)


Usage:

data:
  data_source: sensor.audio.file_list
entity_id: input_select.alarm_sound
service: python_script.input_select_set_options

P.S.

  • Newly created input_select must contain “None” as single item
1 Like