As far as I know there’s no Jinja2 filter that can perform a dictionary lookup. If it existed it would look something like this:
{%- set windows = states.binary_sensor
| selectattr('attributes.device_class','eq','window')
| selectattr('state','eq','on')
| map(attribute='entity_id')
| map(lookup(_map)) | list %}
Even if this lookup
filter existed, you would probably still need to use a for-loop. That’s because of your requirement to insert an i
, instead of a comma, before the last name. If you are willing to eliminate the i
before the last name, you can use the join(',')
filter which can convert a list like this:
[' u Mikołaja', ' w garażu', ' u Adasia']
to this:
u Mikołaja, w garażu, u Adasia
However, a new challenge is created because you are now required to create that list of names which requires a for-loop! So no matter which way we approach this problem, it’s difficult to resolve without a for-loop.
Purely as an academic exercise, here’s a different way to produce the ‘open windows’ message. It’s no better than the one you have and only serves to demonstrate an alternate approach.
{%- set _map = {'binary_sensor.door_window_sensor_158d0001c0a321':' u Mikołaja', 'binary_sensor.door_window_sensor_158d0001ef349c':' w sypialni', 'binary_sensor.door_window_sensor_158d0002048827':' w kuchni', 'binary_sensor.door_window_sensor_158d000232c85a':' w garażu', 'binary_sensor.door_window_sensor_158d0003ef0912':' w górnej łazience', 'binary_sensor.door_window_sensor_158d0002049acc':' w salonie drugie', 'binary_sensor.door_window_sensor_158d0002049ae9':' w salonie pierwsze', 'binary_sensor.door_window_sensor_158d00025370e5':' u Adasia'} %}
{%- set windows = states.binary_sensor | selectattr('attributes.device_class','eq','window')
| selectattr('state','eq','on') | map(attribute='entity_id') | list %}
{% set ns = namespace(names = []) %}
{% for w in windows if w in _map.keys() %}
{% set ns.names = ns.names + [_map[w]] %}
{% endfor %}
{% set open = ns.names | length %}
{% if open == 0 %}
Wszystkie okna są zamknięte
{%- else %}
Okn{{'a' if open > 1 else 'o'}}{{ ns.names | join(',') }} {{'są' if open > 1 else 'jest'}} otwarte
{%- endif %}
NOTE
This would be much easier to achieve if the binary_sensor’s friendly_name
contained the information to display in the ‘open windows’ message. The challenge here is that the names are contained in a dictionary and, if the goal is to avoid using a for-loop, would require a filter to perform a lookup (i.e. mapping).