It’s a pita to add them, looked into it. Wasn’t easy at the time and moved on
Home Assistant now supports match
and search
. The first one is like"startswith" and the second is like “contains”.
You must have missed my post where I said match
serves the purpose of startswith
. Here’s the relevant section from Home Assistant’s documentation for Templating - Regular Expressions
- Test
string is match(find, ignorecase=False)
will match the find expression at the beginning of the string using regex. - Test
string is search(find, ignorecase=True)
will match the find expression anywhere in the string using regex.
Here’s an example of match
and search
in action:
from the looks of it, they still can’t be used for the original intent which is something that filters a list based on contains or startswith. I haven’t played with the tests much, but they don’t appear to help much.
EDIT: They can’t be used in selectattr, rejectattr, select, or reject. Making them 100% useless IMO.
EDIT2: Nope, they can!
{% set items = ['abc', 'bcd', 'cde'] %}
{{ items | select("search", 'b') | list }}
returns
[
"abc",
"bcd"
]
another example
{{ states.sensor | selectattr('entity_id', 'search', 'humidity') | map(attribute='entity_id') | list }}
returns
[
"sensor.bonus_server_room_humidity",
"sensor.garage_humidity",
"sensor.kitchen_humidity",
"sensor.master_bathroom_average_humidity",
"sensor.master_bathroom_filtered_humidity",
"sensor.master_bathroom_filtered_humidity_statistics",
"sensor.master_bathroom_humidity",
"sensor.master_bedroom_humidity",
"sensor.ms_humidity"
]
So these basically do what I wanted to do in this post:
EDIT3:
We’ll need to add more examples in the docs because the provided example is piss poor.
Yep, I had suggested its use in this post to match either “The Batchelor” or “The Batchelorette”.
state_attr('sensor.sonarr_upcoming_media', 'data')
| selectattr('title', 'match', 'The Bachelor') | list | length > 0
Initially I had the same concern because the example in the documentation isn’t quite the way I would normally use a filter.
EDIT
I agree the documentation’s example falls short of showing how useful match
and search
can be.
Well, I don’t see a need for namespace anymore… Outside organizing data before presenting it.
just wait til marius finds this, that’s going to be a lot of refactoring
haha, I am silently following along… trying to fix a library bump first now…
please keep at it!
The flip side is one can now fill the object_id
to the brim with metadata and then easily search for it. That invites the creation of gawdawfully long names. I still prefer using custom attributes for that purpose (and they appear, neatly, in the States view) but to each their own.
sensor.rear_porch_west_temperature_battery_CR123_zigbee_etc
I’ve just found this (thankfully) and I have come up with something that feels a bit clunky, especially as petro says.
I’m trying to highlight unavailable entities (yes, that old chestnut). I have a group of entities to ignore but I also want to be able to ignore based on a pattern. e.g. the mobile app creates loads of sensors that I currently don’t use.
I came up with adding entities to the ignore group with a (dummy) domain of ‘pattern’, e.g.
- sensor.sensor_to_ignore
- pattern.prusa
- pattern.mobile_app
and then using the new(ish) search
as petro showed above to create a dynamic ‘child’ ignore group
So, is there a better way to do this especially in light of the fact that I use a namespace?
(And also, states | selsectattr
always seems a bit hefty to me too).
EDIT: there is a also a problem with this if the ignored entities group contains an entity that doesn’t exist. e.g. I currently have no esp32_cam02
so I am getting
..., switch.esp32_cam01, , camera.esp32_cam03, ...
which is obviously causing an error when populating the group. I’m working on it but any assistance greatly received
action:
- service: group.set
data:
object_id: unavailable_entities_children
entities: >
{% set ns = namespace(child_entities = '') %}
{% set ignored = state_attr('group.unavailable_entities_ignored', 'entity_id') | list %}
{%- for item in ignored %}
{% if item.split('.')[0] == 'pattern' %}
{%- set child_pattern = item.split('.')[1] %}
{%- set ns.child_entities = ns.child_entities ~ states | selectattr('entity_id', 'search', child_pattern) | map(attribute='entity_id') | join(', ') %}
{%- if not loop.last %}
{%- set ns.child_entities = ns.child_entities ~ ', ' %}
{%- endif %}
{% endif %}
{% endfor %}
{{ ns.child_entities }}
Thanks, this thread helped to solve my issue where the new button
entities showed up in my unavailable/unknown list of entities (intended to debug system issues, which means it’s not useful to see buttons).
template:
- trigger:
- platform: time_pattern
minutes: "*"
sensor:
- name: Unavailable Entities
icon: mdi:help-circle-outline
state: "{{ states | selectattr('state', 'in',['unavailable', 'unknown', 'none']) | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | reject('match', 'button') | list | length }}"
unit_of_measurement: entities
state_class: measurement
attributes:
# buttons don't have state – we don't care about buttons here
unavailable: "{{ states | selectattr('state', 'in', ['unavailable']) | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | reject('match', 'button') | list }}"
unknown: "{{ states | selectattr('state', 'in', ['unknown']) | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | reject('match', 'button') | list }}"
none: "{{ states | selectattr('state', 'in', ['none']) | map(attribute='entity_id') | reject('==', 'sensor.unavailable_entities') | reject('match', 'button') | list }}"
Related posts:
|rejectattr('domain','eq','button')
Even better — thanks!
Please tell me, is it possible or there is a function or filter that, the first time a match is found, simply returns the value true, and does not produce a complete list.
Generators are light weight. They don’t return the selected object unless you use it. If you use | first | default(False)
it will return the value or false.
Thank you very much, could you give me an example?
that is the example… You haven’t stated what you’re doing so I can’t give any more example.
Well, for example
{% set items = ['abc', 'bcd', 'cde'] %}
{{ items | select("search", 'b') | list }}
{% set items = ['abc', 'bcd', 'cde'] %}
{{ items | select("search", 'b') | first | default(False)}}