Templating custom filters

Thats a good start but unfortunately it targets just the list or the string. What I want is to filter sort the whole list of templatestates based on attribute so that the final results hold all the attributes of the templatestates

What?

You’re going to have to explain a lot better what you want to do, with some example data.

well this is list

[
<template TemplateState(<state input_number.spotify_playback_volume_bathroom_speaker=5.0; initial=None, editable=True, min=0.0, max=100.0, step=5.0, mode=slider, unit_of_measurement=%, friendly_name=Spotify Playback Volume - Bathroom Speaker @ 2023-11-29T10:56:45.390229+01:00>)>,

<template TemplateState(<state input_number.spotify_playback_volume_bedroom_clock=10.0; initial=None, editable=True, min=0.0, max=100.0, step=5.0, mode=slider, unit_of_measurement=%, friendly_name=Spotify Playback Volume - Bedroom Clock @ 2023-11-29T11:16:39.865984+01:00>)>,

<template TemplateState(<state input_number.spotify_playback_volume_living_room_clock=20.0; initial=None, editable=True, min=0.0, max=100.0, step=5.0, mode=slider, unit_of_measurement=%, friendly_name=Spotify Playback Volume - Living Room Clock @ 2023-11-29T11:16:43.477724+01:00>)>,

<template TemplateState(<state input_number.spotify_playback_volume_kitchen_clock=15.0; initial=None, editable=True, min=0.0, max=100.0, step=5.0, mode=slider, unit_of_measurement=%, friendly_name=Spotify Playback Volume - Kitchen Clock @ 2023-11-29T11:16:41.696763+01:00>)>,

<template TemplateState(<state input_number.spotify_playback_volume_office_room_clock=25.0; initial=None, editable=True, min=0.0, max=100.0, step=5.0, mode=slider, unit_of_measurement=%, friendly_name=Spotify Playback Volume - Office Room Clock @ 2023-11-29T11:16:46.284887+01:00>)>
]

here you can see that the list is filled with different TemplateStates. Now I wish to filter out only the TemplateState which has the maximum value in its state.

{{ states.input_number | selectattr('entity_id','search', 'spotify_playback_volume_') | selectattr('state', '>', '0.00') | max(attribute='state') }}

having this filter gives out the following output:

<template TemplateState(<state input_number.spotify_playback_volume_bathroom_speaker=5.0; initial=None, editable=True, min=0.0, max=100.0, step=5.0, mode=slider, unit_of_measurement=%, friendly_name=Spotify Playback Volume - Bathroom Speaker @ 2023-11-29T10:56:45.390229+01:00>)>

which is wrong as you can see the max state value is not in the input_number.spotify_playback_volume_bathroom_speaker but input_number.spotify_playback_volume_office_room_clock

Your problem is that states are strings (as you know), and “5” is greater than “25” alphanumerically.

This might do it: find the maximum state value (having converted to float, then find the first entity that has that state:

{% set max_vol = states.input_number
                 | selectattr('entity_id','search', 'spotify_playback_volume_')
                 | map(attribute='state')
                 | map('float', default=0)
                 | list | max %}
{{ states.input_number
                 | selectattr('entity_id','search', 'spotify_playback_volume_')
                 | selectattr('state','eq',max_vol|round(1)|string)
                 | list | first }}
1 Like

Thanks a lot. I was wondering if is possible to do it in a single query instead of 2 queries?

You can make use of namespace, that’s about it.

{% set ns = namespace(item=None) %}
{% for e in states.input_number | selectattr('entity_id','search', 'spotify_playback_volume_') %}
  {% set s = e.state | float(None) %}
  {% if s is not none and (ns.item is none or (ns.item is not none and s > ns.item)) %}
    {% set ns.item = e.entity_id %}
  {% endif %}
{% endfor %}
{{ ns.item }}

This is a single iteration using a generator. It’ll be the most optimized you can get in regards to speed.

1 Like

Thanks both… my issues are solved by using your code. I ended up using the version from @Troon