I know this seems crazy, but I’ve been spending hours on this without success.
I’m looking for a way to look for the string “batt” in an http api-sensor state and then fire a trigger based on that.
Here’s what I think is probably the closest to correct, but still doesn’t work:
- alias: Device battery low
trigger:
platform: state
entity_id: group.raw_sensors
condition:
- condition: template
value_template: >
{{'batt' in trigger.to_state.state}}
I think this one above doesn’t work because the group is acting more like a binary sensor and going “on” or “off” instead of a variable with the state of the sensor.
I also tried something like this:
- alias: Device battery low
trigger:
platform: template
value_template: >
{% set found = 0 %}
{% for state in states.sensor %}
{% if 'batt' in state.state %}
{% set found = 1 %}
{% endif %}
{% endfor %}
{{ found == 1 }}
but it doesn’t seem to be getting into the trigger.
I have a 433Mhz battery powered temperature/humidity sensor, the battery level is being put in the device attributes. I created a virtual sensor for it: sensors.yaml
alias: 022 - Cresta slaapkamer low battery
trigger:
- platform: state
entity_id: sensor.tx320_sk_battery
from: 'Vol'
to: 'Leeg'
action:
- service: notify.telegram_f
data:
title: Batterijmelding -
message: Batterij van de Cresta TX320 in de slaapkamer begint leeg te raken!
customization.yaml
`sensor.tx320_sk_battery:`
` hidden: true`
Excuse my Dutch, vol = full, leeg = empty.
The batterylevel attribute is 9 when battery is full and 0 (or not 9) when (almost) empty.
I think that is also the way to go for you, extract the value from the sensor with some [Jinja](http://jinja.pocoo.org/docs/dev/templates/) magic and put the batterylevel in a virtual sensor, which you can then use in automation rules.
Thank you for the reply - I am able to use a virtual sensor to get the battery info out but if I have many many of them that is what I am trying to do without listed each one in a separate automation. Is there a way to add them all to one automation?
Maybe you should look into the for function in jinja. I can’t check right now but maybe you could just iterate over all sensors of this group. I don’t know if you can get all sensors of a group but if so you could iterate over them.
Sorry, but do you have any more info on how to access groups? I’ve been looking in the docs and the code and can’t find a reference. Any way to iterate or get access to group entities?
Sure. Just take a look at the groups in your developer console under “states” there you can see that each group has an attribute named “entity_id” You should be able to iterate over that or you could iterate over all states and just check if they are in that field of the group.
In Jinja the for loop looks like this:
action:
- service: notify.janis_handy_telegram
data_template:
title: "[ALERT][Homeassistant] "
message: >-
{%- for state in states.sensor if state.entity_id == trigger.entity_id -%}
{{ state.attributes.friendly_name }} is down.
{%- endfor -%}
Thanks for the additional info. I also found a loose reference that the entity_ids are in the group attributes, so here’s what I have come up with so far:
{%- for state in states.group if state.entity_id == 'group.raw_sensors' %}
{% for sstate in states.sensor if sstate.entity_id in state.attributes.entity_id %}
{{ 'batt' in sstate.state }}
{% endfor %}
{%- endfor -%}
I do wish there was a more direct way of accessing the group by name without iterating over all of them. If anyone knows of a way, please let me know.
Now, I should be able to come up with a template trigger based on this at some point. I’ll need to spend just a bit more time figuring out what a trigger would look like - I think it needs to return ‘true’ or ‘false’ based on the loops above, but I’m still unclear how template triggers work, am I correct that the template get executed for EVERY component state change?
Yes you are correct. That is also why you should really only use template triggers as a last resort. You should at least build a if block around your core template which check the “trigger.entity_id” for your group.Also you could use the states function like “states.group.raw_sensors” This way you would not have to iterate over the groups.
Cheers
PS: Yes the template trigger has to return true or false
So after much trial and error, this is what I settled on, quite different than what I had originally:
trigger:
platform: template
value_template: >
{% for sstate in states.sensor if sstate.entity_id in states.group.raw_sensors.attributes.entity_id and 'batt' in sstate.state %}
{% if loop.first %}
{{true}}
{% endif %}
{% else %}
{{false}}
{% endfor %}
If you see anything wierd with this, please let me know. Thanks for all your help.
Maybe try somethin like this to get to only trigger on state changes from the group:
trigger:
platform: template
value_template: >
{% for sstate in states.sensor if sstate.entity_id in states.group.raw_sensors.attributes.entity_id and 'batt' in sstate.state and trigger.entity_id in states.group.raw_sensors.attributes.entity_id %}
{% if loop.first %}
{{true}}
{% endif %}
{% else %}
{{false}}
{% endfor %}
I’m a bit new to jinja templates, but I’m learning and this post was extremely helpful for me as I’m trying to do something similar. I have a group of battery sensors (12 actually) and the thought of creating 12 different automations to alert on a low battery made me cringe.
I was able to use the template console in the developer tools to get me close, but I think I have a misunderstanding of how the automation triggers work.
Using your example I was able to piece together the following automation (I used 70 as a test because I have a couple of devices lower than 70%):
batteries:
name: Battery Levels
entities:
- sensor.living_room_4in1_battery
- sensor.master_bed_4in1_battery
- sensor.office_4in1_battery
- sensor.front_door_battery
- sensor.garage_back_door_battery
- sensor.garage_laundry_door_battery
- sensor.kitchen_glassdoor_battery
- sensor.master_bed_door_battery
- sensor.master_bed_glassdoor_battery
- sensor.nw_garage_door_battery
- sensor.se_garage_door_battery
- sensor.maibox_battery
# ---------------------------------- #
- alias: Low Battery Notification
trigger:
- platform: template
value_template: >
{% for state in states.sensor
if trigger.entity_id in states.group.batteries.attributes.entity_id
and state.entity_id in states.group.batteries.attributes.entity_id
and state.state | int < 70 %}
{% if loop.first %}
{{true}}
{% endif %}
{% else %}
{{false}}
{% endfor %}
action:
- service: notify.all
data_template:
message: >
{{ trigger.from_state.attributes.friendly_name }} needs new batteries.
I’m not sure if the message data_template is correct or not, but I would at least figure I would see the automation get triggered in the logs if that was the problem. Is there a way to somehow test for trigger.entity_id in the template developer tools?
Reviving a old thread, I just tested this out and it seems to work okay at least with the first device it finds (it would be great to get notifications for all devices that are found below the threshold, but I can live with this). I’d like to post what I have to keep me honest and to make sure I’m not doing something stupid. Any other suggestions are greatly appreciated.
# Send a notification if a zwave device battery is low
- alias: Low Battery Notification
hide_entity: True
trigger:
- platform: template
value_template: >
{% for zwave in states.zwave if zwave.attributes.battery_level %}
{%- if zwave.attributes.battery_level | int < 70 -%}
{{true}}
{%- endif -%}
{%- endfor -%}
action:
- service: notify.pushover
data_template:
data:
sound: spacealarm
priority: 1
message: >
{{ trigger.to_state.attributes.friendly_name }} needs new batteries.