One of the features currently missing in Home assistant is support for dynamic lists. For example, if you had a number of video files from a security camera which are stored in a directory and the videos are changing every day, how would you be able to show this in Home Assistant. The solution below is a little involved, but does work very well and can be adapted for your needs.

First, we need to create an ‘input select’ in the configuration.yaml file. We will only give it one static option at this point, which will just let us know if the list has been updated or not. When the list has been correctly updated this option will disappear from the list.
input_select: security_video_playlist: name: Security Video playlist options: - 'List not defined - run rest update command' icon: mdi:video
Next, we need to create a sensor. This will store the filenames of the video files as attributes within a sensor. The sensor takes its information from a JSON formatted file within the same directory as the security videos. The folder is best placed in the homeassistant configuration/www directory as this directory is an already accessable resource in Home Assistant.
sensor: platform: rest name: Security video playlist json_attributes: - path - files resource: https://XXXX.com/local/timelapse_recordings/json.txt value_template: "{{ value_json.path}}"
To create the JSON formatted list of the directory contents I used this python script, which I found somewhere online and re-purposed to create a JSON list in the format I needed. You would need to create a cron job to run this script every 5 minutes, so that it maintains an up to date list of the directory contents. I have attached the python script and an example of the output it generates.
#!/usr/bin/env python import os import errno def path_hierarchy(path): hierarchy = { 'type': 'folder', 'name': os.path.basename(path), 'path': path, } try: hierarchy['files'] = [ path_hierarchy(os.path.join(path, contents)) for contents in os.listdir(path) ] except OSError as e: if e.errno != errno.ENOTDIR: raise hierarchy['type'] = 'file' return hierarchy if __name__ == '__main__': import json import sys try: directory = sys.argv[1] except IndexError: directory = "." print(json.dumps(path_hierarchy(directory), indent=2, sort_keys=True))
We now have a method of creating a directory list, a sensor which will read the list and an ‘input select’ to hold the list options. But, we now need to tell Home Assistant to feed the sensor data into the ‘input select’. This is quite a complex statement which we need to insert into the configuration.yaml file. I will show the statement and then break down what it does.
rest_command: populate_input_select_security_video_playlist: url: "https://XXXXXXX.com/api/services/input_select/set_options" method: POST headers: content-type: application/json x-ha-access: {your secure API key} content_type: application/json payload: >- { "entity_id": "input_select.security_video_playlist", "options": [ {%- set files = states.sensor.security_video_playlist.attributes.files -%} {%- for item in files -%} "{{ item.name }}"{% if not loop.last %}, {% endif %} {%- endfor %}] }
The above rest command instructs Home Assistant to set the options for an input select, by reading the contents of the sensor. In the payload statement, we instruct Home Assistant to iterate through each JSON object under ‘files’ attribute and pull out the object called ‘name’. Each ‘name’, (which is a filename) will then be fed to the ‘input select’ as an option.
Finally, we need to create a simple automation to run the rest command often, so that the ‘input select’ is constantly updated (say every 5 minutes).
automation: alias: Populate input select for media players and update playlists initial_state: True trigger: - platform: homeassistant event: start - platform: time_pattern minutes: '/5' action: - delay: seconds: 30 - service: rest_command.populate_input_select_security_video_playlist
I said it was a little convoluted, but if you absolutely do need a dynamic list of elements in your Home Assistant, this is one method I have found. As a way of finishing off, you might like to know how I play my security files in home assistant. I direct the chosen file to a local chromecast stick. So now I can play a video file to any chromecast in the house. The automation below shows how I achived this.
automation: - alias: Play security video (last 24hrs) initial_state: True trigger: - platform: state entity_id: input_boolean.play_security_video to: 'on' action: - service_template: > {% if is_state('input_select.video_capable_players', 'off') %} media_player.turn_on {% else %} script.noop {% endif %} data_template: entity_id: '{{ states.input_select.default_tts_media_player.state }}' - service: media_player.play_media data_template: entity_id: '{{ states.input_select.video_capable_players.state }}' media_content_id: 'https://XXXXXXX.com/local/timelapse_recordings/{{ states.input_select.security_video_playlist.state }}' media_content_type: video - service: input_boolean.turn_off data: entity_id: input_boolean.play_security_video
And the final view in Home Assistant looks like this.
