Add/Remove an Option in input_select with an Action

Hello,

what is the simplest/shortest “one-liner” to remove or add an option (e.g. the string ‘red’) in an input_select from inside an Action of an Automation?

I tried obvious list functions like append('red'), but they are considered “unsafe” code by hass and are not allowed …

Thank you for your input and help,

Fred

There isn’t one. The service input_select.set_options requires a list of all options.

    action:
      - service: input_select.set_options
        data:
          entity_id: input_select.who_cooks
          options: ["Item A", "Item B", "Item C"]

Thanks for your reply. Of course, I have no problem supplying this “new” list, in my case that would be an “updated” list with one option (e.g. ‘red’) added or removed from the original list … how can this be done in a simple fashion?

It can not be done in a “simple fashion”.

Exactly how would one do it in an Action of an Automation? Thank you for your input, even if its not “simple”. At least it would be a start?
On a second thought: How did the devs intend this to be done?

For the past week, I have been experimenting with findings and solutions from elsewhere on the Internet to this issue. My goal is also to affect individual options in an input_select entity. There actually is a solution, but I wouldn’t call it easy. I am still working to refine my code. Here are the steps I have taken so far. I am reviving this post because it was one of the top search results for my terms.

First, create a long-lived access token from the user interface at URL https://your.ha.url/profile. Copy the token that is generated and edit your secrets.yaml file to include a line like below. Be sure to leave the 'Bearer ’ part, including one space.

apirequesttoken: 'Bearer YoUrReAlLyLoNgToKeN'

Also in your secrets.yaml file, you can include a line like below to keep your API URL (including your external IP or URL) away from easy visibility since your configuration file won’t include it directly. I recommend using your local host’s IP address since Home Assistant itself will be the only service using this URL in this use case.

url_inputsetoptions: 'https://your.ha.url/api/services/input_select/set_options'

Edit your configuration.yaml file to include two segments of code like below. Both will need to go under rest_command:.These will need to be adjusted to suit your use case. They are simplified for legibility.

(Add an option to an input_select element)

  add_input_select_option:
    url: !secret url_inputsetoptions
    verify_ssl: false
    method: POST
    headers:
      content-type: application/json
      authorization: !secret apirequesttoken
    content_type: application/json
    payload: >-
      {
        "entity_id": "input_select.entity_you_want_to_change",
        "options": [
      {% set ns = namespace(this_option = (however_you_want_to_retrieve_the_option_to_add) %}
      {% set ns.existing_count = state_attr('input_select.entity_you_want_to_change','options') | count %}
      {%- for existing in state_attr('input_select.entity_you_want_to_change','options') -%}
        {%- if existing != "some_default_empty_list_value" and existing != ns.this_option -%}
          "{{ existing }}"{% if not loop.last %}, {% endif %}
        {% endif %}
        {%- if existing == "some_default_empty_list_value" or existing == ns.this_option -%}
          {% set ns.existing_count = ns.existing_count - 1 %}
        {% endif %}
        {% if loop.last %}
          {%- if ns.existing_count > 0 -%}
            , "{{ ns.this_option }}"]
          {%- else -%}
            "{{ ns.this_option }}"]
          {% endif %}
        {% endif %}
      {%- endfor -%}
      }

(Remove an option from an input_select element)

  remove_input_select_option:
    url: !secret url_inputsetoptions
    verify_ssl: false
    method: POST
    headers:
      content-type: application/json
      authorization: !secret apirequesttoken
    content_type: application/json
    payload: >-
      {
        "entity_id": "input_select.entity_you_want_to_change",
        "options": [
      {% set ns = namespace(this_option = (however_you_want_to_retrieve_the_option_to_remove) %}
      {% set ns.existing_count = state_attr('input_select.entity_you_want_to_change','options') | count %}
      {%- for existing in state_attr('input_select.entity_you_want_to_change','options') -%}
        {%- if existing != ns.this_option -%}
          "{{ existing }}"{% if not loop.last %}, {% endif %}
        {%- else -%}
          {% set ns.existing_count = ns.existing_count - 1 %}
        {% endif %}
      {%- endfor -%}
      {% if ns.existing_count == 0 %}
        "some_default_empty_list_value"
      {% endif %}]
      }

Now, after a restart, in an automation or wherever required, you can call the RESTful command service that corresponds to the addition and removal commands created above. It will be up to you how to store and/or pass the option’s value to the command. I personally am gathering it from an attribute on a sensor, so my RESTful commands include that instead of however_you_want_to_retrieve_the_option_to_remove, for example.

I hope this is helpful to fellow users.

Note: This code is modified from my current code and is not tested, so it may require you to review for typos or simple bugs.

Hello, I was trying to get this done as well, I’ve come up with another option using scripts.
If you run the following script with 2 inputs, the first is the entity to add / remove, the second is the input_select . If the entity is already in the input_select, it will remove it, otherwise it will add it.
I hope it’s helpful

alias: Add Or Remove Option From Input Select
sequence:
  - variables:
      option_to_add: "{{ option_to_add }}"
      is_to_add_to: "{{ is_to_add_to }}"
      group_list: >
        {% if not states(option_to_add) in state_attr(is_to_add_to, "options")
        %} {% set ns = namespace( members = []) %} 
          {% for entity_id in state_attr(is_to_add_to, "options") | list %} 
            {% set ns.members = ns.members + [entity_id] %} 
          {% endfor %} 
          {% set ns.members = ns.members + [states(option_to_add)] %}
                {{ ns.members }}
        {% else %} {% set ns = namespace( members = []) %} 
          {% for entity_id in state_attr(is_to_add_to, "options") | list %} 
            {% if not states(option_to_add) == entity_id %}
              {% set ns.members = ns.members + [entity_id] %} 
            {% endif %}
          {% endfor %} 
                {{ ns.members }}
        {% endif %}
  - service: input_select.set_options
    metadata: {}
    data:
      options: "{{ group_list }}"
    target:
      entity_id: "{{ is_to_add_to }}"
mode: single
1 Like

Thanks man! This was exactly what I was lokking for! I couldn’t get the variables to work but instead used helpers (I’m pretty new to HA…)

Here’s my modified snippet:

alias: ma_addArtistToRandomizer
sequence:
  - service: input_text.set_value
    data_template:
      entity_id: input_text.ma_kok_mediaplayerartist
      value: "{{ states.media_player.kok_2.attributes.media_artist}}"
  - variables:
      group_list: >
        {% if not states('input_text.ma_kok_mediaplayerartist') in
        state_attr("input_select.ma_kok_artister" , "options") %} {% set ns =
        namespace( members = []) %} 
          {% for entity_id in state_attr("input_select.ma_kok_artister" , "options") | list %} 
            {% set ns.members = ns.members + [entity_id] %} 
          {% endfor %} 
          {% set ns.members = ns.members + [states('input_text.ma_kok_mediaplayerartist')] %}
                {{ ns.members }}
        {% else %} {% set ns = namespace( members = []) %} 
          {% for entity_id in state_attr("input_select.ma_kok_artister" , "options") | list %} 
            {% if not states('input_text.ma_kok_mediaplayerartist') == entity_id %}
              {% set ns.members = ns.members + [entity_id] %} 
            {% endif %}
          {% endfor %} 
                {{ ns.members }}
        {% endif %}
  - service: input_select.set_options
    metadata: {}
    data:
      options: "{{ group_list }}"
    target:
      entity_id: input_select.ma_kok_artister
mode: restart

I use it to put an Artist playing in a media player to add to a list that I can then randomly call to play. A separate favourite randomizer kind of.

You can simplify this by doing

to add an entry

{{ state_attr('input_select.test', 'options') + ['Person C']}}

to remove an entry.

{{ state_attr('input_select.test', 'options') | reject('match', 'Person A') | list }}

So,

alias: ma_addArtistToRandomizer
service: input_select.set_options
  metadata: {}
  data:
    options: "{{ state_attr('input_select.ma_kok_artister', 'options') + [state_attr('media_player.kok_2','media_artist')]}}" 
  target:
    entity_id: input_select.ma_kok_artister
mode: restart
1 Like

Thank you! This works great! A lot easier on the eyes. I was afraid it would keep adding multiple same items but it doesn’t.

If you want to ensure you cant add the same artist twice, do this so service doesn’t fail.

alias: ma_addArtistToRandomizer
service: input_select.set_options
  metadata: {}
  data:
    options: "{{ state_attr('input_select.ma_kok_artister', 'options') + [state_attr('media_player.kok_2','media_artist')] if state_attr('media_player.kok_2','media_artist') not in state_attr('input_select.ma_kok_artister', 'options') else []}}" 
  target:
    entity_id: input_select.ma_kok_artister
mode: restart
1 Like

Thanks looks great!

However I had to do a hard reboot yesterday evening due to another issue I ran in to and that resetted the input_select to initial. All values added via input_select.set_options dissapeared :sob: Seems it doesn’t store those values the same way as those you type in via settings.

I think of using a file sensor instead but so far I’m to stupid to even create a file, will do some searching on the matter.

Yes, looking at the code, does not seem to store options that are added by a service. This seems a little odd. May do a PR that changes this.

Dont give up hope yet! :grin:

1 Like

Haha thanks! You really made my day being so helpful! Can I somehov add my support to the ticket? Didn’t find any like button or similar.