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.