API to flatten lists in templates / HA flavor of jinja?

Trying to figure out the API to flatten a list of lists but starting to think it’s not available.
Something like flatMap or flat_map or flatten as a filter but none of those seem to work…

Show an example of what you want to go from and to and I am sure someone here will come up with something.

Good point, it’s an XY problem situation for sure.

What I REALLY want to do is get a list of al entities that do NOT have an area assigned.

I have this as part of a template sensor which is triggered once a day to check for anything that needs an area assignment (it’s a binary sensor which then pops up in the ‘warnings’ area of my dashboards and will have an attribute with the list of problematic entities ideally).

Very roughly (and incorrectly, I always have to brute force syntax in HA using the Developer Tools because there is no real static type system so you kinda gotta play with it until it works), this is the approach

{# All entities with areas. In practice, this returns a nested list, one list for each area. #}
{% set entities_with_areas = areas()|map('area_entities')|list %}

{# Now, for every single entity, check if it's in the list. It's quadratic but whatever (esp since I do not rederive the area entities each time). #}
{# Let me know if you can think of a more efficient way to do this. #}
{# Obviously, the below syntax doesn't work, probably for all sorts of reasons in addition to entites_with_areas being a list of lists. #}
{{ states|rejectattr('entity_id', 'in', entities_with_areas)|list }}
1 Like

So, entites don’t really have areas. Devices do. You would need to get a list of devices without an area then get the list of entites for those devices.

I found this in my saved test templates. I am not sure what it was all about. LOL. but, it does show a list of attributes for each device in each area. See if it can get you in the right direction.

The # in the attr list is for ones I didn’t really want to see after I got somethingerrother.

{%- for area in areas() | sort %}
{{ area_name(area) }}
  {%- for device in area_devices(area) %}
    name: {{ device_attr(device, 'name') }}
    {%- for attr in [
      ] %}
      {%- if attr[0] != '#' %}
      {{ attr }}: {{ device_attr(device, attr) }}
      {%- endif -%}
    {%- endfor -%}
  {%- endfor -%}
{%- endfor -%}

Thank you. While that might be technically true, you can get that from the following API.
area_entities(SOME_AREA) so I’m a bit confused about the code above.
In fact, you can definitely override areas per entity, so the underlying data must definitely be at the entity level. I’m very certain about that.

I think this will just unnecessarily complicated the code.

Otherwise, you are giving me the idea I can just two nested loops but I want to avoid rederiving everything multiple times though it probably doesn’t matter much if it only runs once a day.

LOL. I am sure it can be done better. Again, it is not in my production. But, in my testing I was looking for something. Clearly, I was not looking for entities.

It does not seem more complicated than you are looking for. It seems you just need to change

for device in area_devices(area)


for entity not in area_entities(area)

Certainly clean it up and please come back and post your final code so others can get it too.

It’s not just changing that API, it will require also mapping from device to entity which I don’t want to deal with TBH.

The final solution I have is this, perhaps not ideal but works well for me.

{% set entities_with_area = namespace(data=[])%}
{% for area in areas() %}
{% set entities_with_area.data = entities_with_area.data + area_entities(area) %}
{% endfor %}
{{ states|rejectattr('entity_id', 'in', entities_with_area.data)|map(attribute="entity_id")|list }}