My man. Thank you!
hello, thanks for sharing this solution. at every restart of Hassio I start an automation that populates my input_select, but unfortunately doing so I lose the current selection, do you know if there is a way to keep the previous setting on reboot?
can you please tell me what this HTTP password? I keep getting the following error.
Login attempt or request with invalid authentication from 127.0.0.1
update: solution is here
Sorry - I only just found your post now, havenāt logged in for a while. Yeah since HA has has long lived tokens, I use them religiously now thatās the way to go
This string helped me a lot - thanks gents. I still canāt get this to work. Goal is to dynamically update input_selectā¦ Gives me a perfectly formatted array in the developer tools template.
rest_command:
populate_input_select_options:
url: "http://192.168.1.100:8123/api/services/input_select/set_options"
method: POST
headers:
x-ha-access: !secret http_password
content-type: application/json
payload: >-
{
"entity_id": "input_select.meat_type"
"options": [
{%- for state in states.variable if state_attr(state.entity_id, 'meat_type')==states['input_select.meat_type'].state -%}
"{{state_attr(state.entity_id, 'meat_cut')}}"
{%- if not loop.last %}, {%-endif-%}
{%- endfor -%}]
}
Help much appreciated. Dave
Itās giving you a string that only looks like an array.
The output of any template is a string.
Hi Dave,
A few suggestions:
1: Paste your rest_command config into the template area with the HASS UI, then paste the resulting payload here or at the jsonlint site to test if itās actually valid json
2: it looks like you are using an HTTP password, try creating long life tokens instead. (The ābearer: ####ā examples from above)
3: call the rest command a few times then check the main log. It should tell you what is going wrong.
Hi everybody,
Im newbie with HA but i like it
I would like too populate an input_select depending of the value of a first input_select.
input_select:
who_cooks:
name: Who cooks today
options:
- Select
- Paulus
- Anne Therese
initial: Select
icon: mdi:panda
living_room_preset:
options:
- Visitors
- Visitors with kids
- Home Alone
automation:
- alias: change select
trigger:
platform: state
entity_id: input_select.who_cooks
action:
service: input_select.set_options
data:
entity_id: input_select.living_room_preset
options: >
{% if trigger.to_state.state == 'Paulus' %}
["Item A", "Item B", "Item C"]
{% elif trigger.to_state.state == 'radio' %}
["19", "20", "21"]
{% endif %}
I understand that template returns string, also i would like use the workaroud.set_options to populate the second input_select.
BUT i need the values are in a list written by me for some temperature value.
If 1st input == āComfortā , the second input populates with temperature number 19, 20, 21ā¦
Like
automation:
- alias: change input_select_Second
trigger:
platform: state
entity_id: input_select.first
action:
service: input_select.set_options
data_template:
entity_id: input_select.second
options: >
{% if trigger.to_state.state == 'Comfort' %}
["20", "20.5", "21", "21.5", "22"]
{% elif trigger.to_state.state == 'Eco' %}
["14", "14.5", "15", "15.5"]
{% endif %}
Can you help me please ?
Thanks
With 0.117 and the new native types for templates, you should be able to use the automation as you have written.
Just make sure you have
homeassistant:
legacy_templates: false
in your configuration.yaml
Thanks @Olen
I know but it is in beta and i dont want to risk modify the other template that i use.
Itās why i would like to do this with the rest_command
Generally beta doesnt like me
The chances of anything breaking are pretty slim, especially if you have just started using ha, and your templates are reasonably standard. And if they do, it is pretty easy to fix.
I have hundreds of automations, scripts and sensors using templates built over several years, and nothing serious broke here.
Not using something that works well and will be default in the next release or so is imho just causing yourself more trouble at a later date.
Hi @Olen
He i cant wait and i do the modification.
It works like a charm yeah !!
But i want testing the rest solution for populating.
What add in configuration for testing the api? Please
Thanks for thƩ job for all admins of ha
I know this thread is old, and my reply doesnāt exactly address the original question, but I have solved a similar problem that someone might find useful.
The use case is: maintain a dropdown in the front end containing a (relatively short) list of movies available for my Kodi media player. The list must be able to be updated dynamically. My solution uses pyscript modules to glue everything together (https://github.com/custom-components/pyscript).
The dropdown is defined as an input_select in yaml, with a static dummy option:
kodi_movies:
name: Kodi Movies
options:
- "Select"
Next is a script to set or update the actual list - the key service is kodi.call_method:
kodi_get_all_movies:
alias: Kodi Get All Movies
sequence:
- condition: state
entity_id: media_player.shield_tv
state: 'off'
- service: input_boolean.turn_off
data:
entity_id: input_boolean.kodi_specific_movie
- service: media_player.turn_on
data:
entity_id: media_player.shield_tv
- delay: 00:00:03
- service: androidtv.adb_command
data:
entity_id: media_player.shield_tv
command: "am start -a android.intent.action.MAIN -c android.intent.category.LEANBACK_LAUNCHER -n 'org.xbmc.kodi/.Splash'"
- delay: 00:00:02
- service: kodi.call_method
data:
entity_id: media_player.kodi
method: VideoLibrary.GetMovies
- delay: 00:00:02
- service: remote.send_command
entity_id: remote.harmony_hub
data:
command: 'Home'
device: NVIDIA Shield TV
- delay: 00:00:02
- service: media_player.turn_off
data:
entity_id: media_player.shield_tv
This drives an automation to process the response, which is a list of 2 dictionaries (ālimitā describes the number of entries, āmoviesā contains all the movies and movie IDs). I am just using the movie title at the moment, then calling Kodi again to get the ID when I play it. I might try to save the IDs at this point, but I think that would get a bit messy:
- alias: Kodi All Movies Result
id: kodi_all_movies_result
trigger:
- platform: event
event_type: kodi_call_method_result
event_data:
result_ok: true
input:
method: VideoLibrary.GetMovies
condition:
- condition: state
entity_id: input_boolean.kodi_specific_movie
state: 'off'
action:
- service: pyscript.populate_all_movies
data:
entity: input_select.kodi_movies
result: "{{ trigger.event.data.result }}"
Finally, here is the pyscript module called by the above automation:
#!/usr/bin/python3
# Populate the given input select from the result of a Kodi all movies query.
import sys
# File I/O is done in a called module - ensure the path includes it. Note that this only needs to be added
# to one file ... pyscript picks it up when loading the files.
if "/config/pyscript_modules" not in sys.path:
sys.path.append("/config/pyscript_modules")
import file_ops
# This runs as a service, and is normally run from an automation.
@service
def populate_all_movies(entity=None, result=None):
log.debug(f"got entity {entity}, result {result}")
# Inputs are required. They are defined as optional so we can just log an error instead of encountering
# an exception.
if entity is None or result is None:
log.error("entity and result are both required, exiting")
# Domain must be input_select.
elif not entity.startswith("input_select."):
log.error("input entity must be domain input_select, exiting")
# All seems well.
else:
# List of all movies
movies = result['movies']
all_movies = []
for movie in movies:
all_movies.append(movie['label'])
all_movies.sort()
log.debug(f"movie list {all_movies}")
# Populate the input select.
input_select.set_options(entity_id=entity, options=all_movies)
# Write the list to a file so we can restore the input select after a restart.
task.executor(file_ops.write_movie_file, all_movies)
Well, I said āfinallyā but not really. Note the last instruction above. When HA restarts, the input_select reverts back to its initial, static, value. So the write_movie_file() above persists the movie list using a native Python module. Note that when pyscript calls native Python, using task.executor(), the native Python module must exist in a different directory, python_modules in my case. At the top of the above file is a bit of code to modify the Python search path to include this directory. This is covered in the pyscript doc, but I struggled with it a bit. Here is the file containing write_movie_file(), as well as read_movie_file(), to be described in a bit:
#!/usr/bin/python3
# This native Python module is called by pyscript modules to perform file operations.
import os
import pickle
# Constants
MOVIE_BACKUP_FILE = "/config/all_movies_backup"
# Write the movie list to a file.
def write_movie_file(all_movies):
with open(MOVIE_BACKUP_FILE, "wb") as outfile:
pickle.dump(all_movies, outfile)
# Read and return the movie list.
def read_movie_file():
with open(MOVIE_BACKUP_FILE, "rb") as infile:
return pickle.load(infile)
To fully restore the input_select we need not only the movie list, but the selected option as well. For my use this is the movie to be shown for my āfeature presentationā mode (work in progress), so I donāt want to lose it over a restart. This requires an input_text (not shown since it just has a name), and an automation to set the text when a movie is selected from the dropdown in the front end:
- alias: Save Feature Movie Name
id: save_feature_movie_name
trigger:
- platform: state
entity_id: input_select.kodi_movies
condition:
- condition: template
value_template: "{{ ( trigger.to_state.state ) != ( 'Select' ) }}"
action:
- service: input_text.set_value
data_template:
entity_id: input_text.current_feature
value: "{{ ( trigger.to_state.state ) }}"
Here is the restart automation to restore the input_select:
- alias: Restore Movie List On Start
id: restore_movie_list_on_start
trigger:
- platform: homeassistant
event: start
action:
- service: pyscript.restore_all_movies
data:
entity: input_select.kodi_movies
- service: input_select.select_option
data:
entity_id: input_select.kodi_movies
option: "{{ states('input_text.current_feature') }}"
And the pyscript module:
#!/usr/bin/python3
# Restore the given input select from the previously saved list of all movies.
import file_ops
# This runs as a service, and is normally run from an automation.
@service
def restore_all_movies(entity=None):
log.debug(f"got entity {entity}")
# Input entity is required. It is defined as optional so we can just log an error instead of encountering
# an exception.
if entity is None:
log.error("entity is required, exiting")
# Domain must be input_select.
elif not entity.startswith("input_select."):
log.error("input entity must be domain input_select, exiting")
# All seems well.
else:
# Read the backup file.
try:
all_movies = task.executor(file_ops.read_movie_file)
except FileNotFoundError:
log.error(f"saved movie file not found, exiting")
sys.exit(f"file not found")
except pickle.UnpicklingError:
log.error(f"saved movie file not usable, exiting")
sys.exit(f"file not usable")
log.debug(f"movie list {all_movies}")
# Populate the input select.
input_select.set_options(entity_id=entity, options=all_movies)
Apologies for the massively long reply
Hey itās always great when someone takes the time to post their solution. There is nearly always something to be learned from the ingenuity of others. Thanks!
I thought I might share the direction I have gone since this threadā¦ so when I need something reflected into HASS based on a scripted payload, I push it straight to HASS from the code.
Here is some old BASH code I really need to convert to Python. The services function allows me to update most things editable. The sensors thing has been really valuable too.
hassApi='https://mypersonal.dns.com/api/'
# where I keep my long lived access tokens
# the directory business is so I can use these functions from within the HASS docker,
# or from my server
if [ -f /config/llat.txt ]; then
source /config/llat.txt
elif [ -f /volume1/docker/hass/llat.txt ]; then
source /volume1/docker/hass/llat.txt
fi
function callHASSservice {
domain=$1
service=$2
json=$3
_service='services/'
serviceurl=$hassApi$_service
url="$serviceurl$domain/$service"
post=$(curl -s -X POST -H "Authorization: Bearer $llat" -H "Content-Type: application/json" -d "$json" $url)
echo $post
}
function callHASSsensor {
# I use a state-on, pause then state-off so that I can more easily control when automations trigger.. probably uneccessary
stateon=$1
json=$2
sensor=$3
stateoff=$4
_sensor='states/sensor.'
status='{"state":"'$stateon'","attributes":'$json'}'
sensorurl=$hassApi$_sensor$sensor
send=$(curl -X POST -s -H "Authorization: Bearer $llat" -H "Content-Type: application/json" -d "$status" $sensorurl)
if [ ! -z $4 ]; then
sleep 3
status='{"state":"'$stateoff'","attributes":'$json'}'
send=$(curl -s -X POST -H "Authorization: Bearer $llat" -H "Content-Type: application/json" -d "$status" $sensorurl)
echo $send
fi
}
This works !!!
action:
- service: input_select.set_options
target:
entity_id: input_select.di_zhi
data:
options: >
{% set zonelist = namespace(numbers=[]) %} {%- for zone in states.zone -%} {%- set zonelist.numbers = zonelist.numbers + [zone.entity_id.replace('zone.','') ] -%} {%- endfor -%} {{zonelist.numbers}}
If you simply want to create a list of each zoneās object_id
(the object_id
in zone.office
is office
) then you can do that, without using a for-loop, like this:
action:
- service: input_select.set_options
target:
entity_id: input_select.di_zhi
data:
options: "{{ states.zone | map(attribute='object_id') | list }}"
I decided to try out the new native types support for templates (beta) feature .
I was able to populate the list of my favorite Sonos stations in an input_select
helper with this code:
service: input_select.set_options
target:
entity_id: input_select.sonos_favorites
data_template:
options: >
[{%- for key, value in state_attr('sensor.sonos_favorites', 'items').items() -%}
"{{ value }}",
{%- endfor %}]
service: input_select.set_options
target:
entity_id: input_select.sonos_favorites
data:
options: >
{{ state_attr('sensor.sonos_favorites', 'items').values() | list }}
@123 Thank you, thank you, thank you! I think this is the best post Iāve found so far on my HA journey?
Iāve been phaffing around with loops, tests and various input helpers to convert a string into a list and to find it can be done by piping into ālistā. My dozen+ lines of template which nearly worked now all in one simple and concise line.
Bloody Perfect!
Iām trying to populate a āselection Bā based on a āselection Aā. From what I understand this should be doable. Iām admittedly autodidact leaving big blanks in my understanding of HA and yaml.
Specifically, Iām trying to on the basis of the initial choice of type of inverter (1 phase ot 3 phase) make a drop down list for choosing between only models related to the type. But no matter what I end up with the complete list. Iāve been around alot reading and testing but must admit I canāt get this to work. Here is the basic code Iām building from, just sĆ„ you get the idea.
input_select:
inverter_1_phases:
name: "Inverter #1 Phases"
options:
- Select
- 1 Phase
- 3 Phase
inverter_1_models:
name: "Inverter #1 Models"
options:
- Select
- SUN2000 2 KTL-L1
- SUN2000 3 KTL-L1
- SUN2000 3.68 KTL-L1
- SUN2000 4 KTL-L1
- SUN2000 4.6 KTL-L1
- SUN2000 5 KTL-L1
- SUN2000 6 KTL-L1
- SUN2000 3 KTL-M1
- SUN2000 4 KTL-M1
- SUN2000 5 KTL-M1
- SUN2000 6 KTL-M1
- SUN2000 8 KTL-M1
- SUN2000 10 KTL-M1
automation:
- alias: "Inverter #1 Model"
trigger:
platform: state
entity_id: input_select.inverter_1_phases
action:
service: input_select.set_options
data:
entity_id: input_select.inverter_1_models
options: >
{% if trigger.to_state.state == '1 Phase' %}
[
"Select",
"SUN2000 2 KTL-L1",
"SUN2000 3 KTL-L1",
"SUN2000 3.68 KTL-L1",
"SUN2000 4 KTL-L1",
"SUN2000 4.6 KTL-L1",
"SUN2000 5 KTL-L1",
"SUN2000 6 KTL-L1"
]
{% elif trigger.to_state.state == '3 Phase' %}
[
"Select",
"SUN2000 3 KTL-M1",
"SUN2000 4 KTL-M1",
"SUN2000 5 KTL-M1",
"SUN2000 6 KTL-M1",
"SUN2000 8 KTL-M1",
"SUN2000 10 KTL-M1"
]
{% else %}
{{ 'Select No of Phases' }}
{% endif %}