You’re welcome to omit the iterable. Doesn’t matter to me, if you think it’s redundant, then remove it. I personally would rather be safe then sorry.
device: >
{% if lights.device_id is defined and lights.device_id is iterable %}
{% set devices = [ lights.device_id ] if lights.device_id is string else lights.device_id %}
{{ devices | map('device_entities') | sum(start=[]) }}
{% else %}
[]
{% endif %}
area: >
{% if lights.area_id is defined and lights.area_id is iterable %}
{% set devices = [ lights.area_id ] if lights.area_id is string else lights.area_id %}
{{ devices | map('area_entities') | sum(start=[]) }}
{% else %}
[]
{% endif %}
you could probably simplify this to a single field to handle all 3. Allow you to avoid your iterable that you don’t like for some reason.
entities: >
{%- set ns = namespace(ret=[]) %}
{%- for key in ['device_id', 'area_id', 'entity_id'] %}
{%- set items = lights.get(key, []) %}
{%- if items %}
{%- set items = [ items ] if items is string else items %}
{%- set filt = key.split('_') | first %}
{%- set items = items if filt == 'entity' else items | map(filt ~ '_entities') | sum(start=[]) %}
{%- set ns.ret = ns.ret + [ items ] %}
{%- endif %}
{%- endfor %}
{{ ns.ret | sum(start=[]) }}