Hey folks!
I have a script that has a field like this:
target:
name: Target
required: true
selector:
target:
entity:
domain: media_player
The UI allows people to select zero or more media player entities, devices, areas and labels, and as a result the target dictionary will contain keys like device_id, area_id, label_id and entity_id, each of which will have either a string value (if only one of those items was selected) or a list value (if multiple of those items was selected).
So this already presents the interesting challenge of having to detect if the values are strings or lists, but on top of that, since what I ultimately need is a list of the appropriate entity IDs, I have to process the devices/areas/labels to turn them into entity IDs.
I have some code which does this all, but when I look at it, I can't help but suspect I have missed some magic helper that could do all of this for me:
- variables:
expanded_targets: >
{# Create the namespace object we'll use to store all our working data #}
{% set data = namespace(expanded_targets=[]) %}
{# Declare two helper macros #}
{% macro m_listifyIfNot(someValue, returns) %}
{% if someValue is list %}
{% do returns(someValue) %}
{% else %}
{% do returns([someValue]) %}
{% endif %}
{% endmacro %}
{% macro m_noop(someValue, returns) %}
{% do returns(someValue) %}
{% endmacro %}
{# Declare our helper macros as functions, so they can return values #}
{% set f_listifyIfNot = m_listifyIfNot | as_function %}
{% set f_noop = m_noop | as_function %}
{# Iterate our input dictionary #}
{% for value in target %}
{# Store a function pointer we'll use to turn the input value into a list of entities #}
{% if value == "device_id" %}
{% set f_getEntities = device_entities %}
{% elif value == "area_id" %}
{% set f_getEntities = area_entities %}
{% elif value == "label_id" %}
{% set f_getEntities = label_entities %}
{% elif value == "entity_id" %}
{% set f_getEntities = f_noop %}
{% else %}
{# This should never be hit #}
{% set f_getEntities = none %}
{% endif %}
{# Ensure the input value is a list. It will be a string if only one value is supplied #}
{% set listifiedValues = f_listifyIfNot(target[value]) %}
{# Iterate the input list and use our function pointer to expand it to a list of entities, and filter out anything that isn't a media_player #}
{% for entry in listifiedValues %}
{% set data.expanded_targets = data.expanded_targets + expand(f_getEntities(entry)) | map(attribute="entity_id") | select("match", "media_player") | list %}
{% endfor %}
{% endfor %}
{# Output our working data, limited to unique entities, into the script variable #}
{{ data.expanded_targets | unique | list }}
Is there such a thing?