I have the following trigger condition that makes a list of any sensors with low battery level (set at 98% for testing) and if there are any items in the list returns the trigger condition as true.
{% set min_battery_level = 98 -%}
{% set ns = namespace(found=false, entities = []) -%}
{% for entity_id in states.group.doors.attributes.entity_id -%}
{% set name = state_attr(entity_id, 'friendly_name') | string -%}
{% set battery = state_attr(entity_id, 'battery_level') | replace("%","") | int -%}
{% if (battery) < min_battery_level -%}
{% set ns.found = true -%}
{% set ns.entities = ns.entities + [name+' ('+battery|string+'%)'] -%}
{% endif -%}
{% endfor -%}
{{ ns.found }}
What I want to then do is use the output list in a notification message triggered in the automation’s action:
You have to make the template twice. What do you plan on doing with the entities? Just a message? If so, just use the exact same template again inside the message. Also, here’s a streamlined version
{%- set min_battery_level = 98 %}
{%- set ns = namespace(entities = []) %}
{%- for state in expand('group.doors') %}
{%- set battery = state.attributes.battery_level | replace("%","") | int %}
{%- if battery < min_battery_level %}
{%- set ns.entities = ns.entities + [ '%s (%i\%)'%(state.name, battery) ] %}
{%- endif %}
{%- endfor %}
{{ ns.entities | count > 0 }}
Then in your message:
{%- set min_battery_level = 98 %}
{%- set ns = namespace(entities = []) %}
{%- for state in expand('group.doors') %}
{%- set battery = state.attributes.battery_level | replace("%","") | int %}
{%- if battery < min_battery_level %}
{%- set ns.entities = ns.entities + [ '%s (%i\%)'%(state.name, battery) ] %}
{%- endif %}
{%- endfor %}
{{ ns.entities | join(', ') }}
Couple of things,
You don’t need the ns.found. You can use the list that you build.
You should use expand(). It returns state objects. Then you don’t need to make extra state grabbing calls for attributes.
I made some changes to the format line '%s (%i%)'%(state.name, battery). You could have left it but you should just change from + to ~ to ensure string types. name ~ ' (' ~ battery ~ '%)'
So helpful! Thank you. Lots to learn from in this answer.
The following line: {%- set ns.entities = ns.entities + [ '%s (%i%)'%(state.name, battery) ] %}
Seems to give the following error: TypeError: not enough arguments for format string
Currently playing with it to see if I can fix myself.
Also, just to note that the message template needs to begin with: message: >
Followed by the template on the next lines AND the closing %} needs to have a dash before it, like this: -%}
Just for fun, I wanted to see (using 0.118.0) if a variable can be used in both a Template Trigger and in the action. Answer: No.
## This doesn't work.
## The variable `inputs` fails to trigger the automation.
- alias: var tester
variables:
inputs: >
{{ expand('group.input_booleans')
| selectattr('state', 'eq', 'on')
| map(attribute='name') | list }}
trigger:
platform: template
value_template: "{{ inputs | count > 0 }}"
action:
service: persistent_notification.create
data:
title: "{{ now().timestamp()|timestamp_local() }}"
message: "{{ inputs | join(', ') }}"
Although no error messages are reported, the Template Trigger fails to trigger. However, if triggered manually, the action does correctly report the names of the enabled input_booleans. In other words, the variable inputs contains a valid list and {{ inputs | join(', ') }} works. However, not when used in the Template Trigger {{ inputs | count > 0 }}.
My guess is the variable isn’t defined yet when the Template Trigger is created. Too bad because it would be a tidy way of handling the OP’s request.