Templating with entity_id wildcard

Hi ,

i’ve got an problem with condition templating. I want to get notified if one of my battery-sensors has changed there state. I looked around and found this example, witch sadly not work in my case…

 - alias: Battery
   trigger:
      platform: event
      event_type: state_changed
      event_data:
        domain: sensor
    condition:
      condition: template
      value_template: "{{ trigger.event.data.entity_id.startswith('battery_') }}"
    action:
      service: notify.telegram
      data_template:
        message: "\U0001F50B Battery {{ trigger.to_state.attributes.friendly_name }} has changed to {{ trigger.to_state.state }}"

I always got this error:

ERROR (MainThread) [homeassistant.config] Invalid config for [automation]: extra keys not allowed @ data['condition'][1]['state']. Got None
not a valid value for dictionary value @ data['condition'][1]['condition']. Got None. (See /home/homeassistant/.homeassistant/configuration.yaml, line 629). Please check the docs at https://home-assistant.io/integrations/automation/

Thank you for helping and happy Christmas Eve :wink:

There are many problems here.

  • The indentation of your automation is wrong. (The first line isn’t consistent with the rest of the automation.)
  • The error cannot possibly be for the posted automation since it says there’s an error in the second condition, but this automation only has one condition.
  • In the condition you’re testing if the entity_id begins with 'battery_', but it never will, because given the trigger it will always start with 'sensor.'.
  • The trigger variable does not have a to_state field for an event trigger.

Have you made any progress? Do you still need help? If you still need help can you post your current attempt and any error message that corresponds to it?

Thanks for the answer.

  • I’ve fixed the indenration in my post. This was a copy/paste fault.
  • This is confusing. I’ve comment-in this wrong automations and no error appears.

so… this is “fixed” :sweat_smile:

With the given link i was able to understand witch attributes are available.

I modified my automation and it works :smiling_face_with_three_hearts: Thanks!

  - alias: Battery
    trigger:
      platform: event
      event_type: state_changed
      event_data:
        domain: sensor
    condition:
      condition: template
      value_template: "{{ trigger.event.data.entity_id.startswith('sensor.battery_') and trigger.event.data.old_state.state != 'unknown' }}"
    action:
      service: notify.telegram
      data_template:
        message: "\U0001F50B Battery {{ trigger.event.data.old_state.name }} has changed from {{ trigger.event.data.old_state.state }} to {{ trigger.event.data.new_state.state }}"

I’ve also added

trigger.event.data.old_state.state != 'unknown' 

to the condition to prevent a notification after restarting home assistant. Just in case someone else has struggle with this.

That’s not the correct way to do it. The first state_changed event for all entities will have trigger.event.data.old_state equal to None. In that case trigger.event.data.old_state.state will cause an error (because None does not have an attribute named state.) The correct way is:

trigger.event.data.old_state is not none

Hi, I try to join all changes:

  - alias: Battery
    trigger:
      platform: event
      event_type: state_changed
      event_data:
        domain: sensor
    condition:
      condition: template
      value_template: "{{ trigger.event.data.entity_id.startswith('sensor.battery_') and trigger.event.data.old_state is not none }}"
    action:
      service: notify.telegram
      data_template:
        message: "\U0001F50B Battery {{ trigger.event.data.old_state.name }} has changed from {{ trigger.event.data.old_state.state }} to {{ trigger.event.data.new_state.state }}"

This is the correctly way?

Looks ok to me. Is it working like you want?

Not entirely off topic so wonder something like this is possible for a binary_sensor?

value_template: "{{ state('sensor.*battery*') < 15 }}"

You say “for a binary_sensor”, but then your example shows 'sensor.', so which is it???

Anyway, here’s a hint:

{% set domain, object_id = trigger.event.data.entity_id.split('.', 1) %}
{{ domain == 'sensor' and 'battery' in object_id }}

Sorry about the inconsistency, its for a binary_sensor.
I don’t understand the code and how to I test the state for an value?

What I am trying to do, is to have one binary sensor changing to “ON” if one of many sensors with battery level goes under 15%.
This way if one of my sensors with battery level goes under 15%. I can have one alert firing when the binary sensor changes to “on”.

value_template: >-
  {% set domain, object_id = trigger.event.data.entity_id.split('.', 1) %}
  {{ domain == 'sensor' and 'battery' in object_id }}
  ??{{ object_id.*battery*') < 15 }}??

So you’re saying you have some entities in the sensor domain that each have an attribute whose name contains the word “battery”, and you want to create a binary_sensor whose state should be 'on' if any of those attributes have a value less than 15? Is that it?

Yes, some entities in the sensor domain which have “battery_level” in the sensor name, or as an attribute. Whit value less than 15.

Wait, this gets more complicated each time you clarify. I’m still unclear exactly what you’re looking for.

So some sensor entities have an entity ID that is like "sensor.*battery_level*" (i.e., they have "battery_level" in their object IDs), and their states indicate battery levels. And some other sensor entities have an attribute named "battery_level", or have "battery_level" in the name of one of their attributes, and they also indicate battery levels. And you want a new binary_sensor that is on if any of those states or attributes indicate a level below 15. Is that it?

I would be a happy camper if the "sensor.*battery_level*" would work (forget about the attribute functionality).

1 Like
value_template: >
  {% set ns = namespace(count=0) %}
  {% for state in states.sensor if 'battery_level' in state.entity_id and 
                                   state.state|float(100) < 15 %}
    {% set ns.count = ns.count + 1 %}
  {% endfor %}
  {{ ns.count > 0 }}

I specified a default value of 100 for the float filter so that values that cannot be interpreted as a number (e.g., 'unavailable' or 'unknown') don’t cause the template to result in true. But, if you do want those to turn the binary sensor on, then just change “float(100)” to “float”.

1 Like

Outstanding. Thanks!

This is strange. Using your code in the Developer Tool-Template, it works fine, geting “True”.

This code gets state value “off” (no errors in the log):

  - platform: template
    sensors:
      battery_low_alert:
        friendly_name: 'Battery low alert'
        device_class: battery
        value_template: >-
          {% set ns = namespace(count=0) %}
          {% for state in states.sensor if 'battery_level' in state.entity_id and 
                                   state.state|float(100) < 15 %}
            {% set ns.count = ns.count + 1 %}
          {% endfor %}
          {{ ns.count > 0 }}

No, it’s not strange. It’s expected. You’re probably getting a warning about it not being able to detect any entity IDs. You need to make the sensor update, since it won’t on its own. Either add something like

entity_id: sensor.time

Or set up an automation to update it periodically. That’s the problem with using a template like this for a sensor.

1 Like

Could you please double check if this actually does anything in your setup (like removing it and checking if the behaviour has changed)?
Im trying to do something similar to your automation, but found out that domain property of event_data is not documented and doesnt work for me.

Hello, i found this post because i’m in the same case, but using this code don’t give a number, only true or false.
Can someone help to solve this ?

remove the > 0.