YAML config nested {% if %} statements - help? battery_alert.yaml [given up]

it should just replace the macro. I’m not sure if the output format is correct though. As I said, I had trouble understanding the overall goal. There’s alot of fluff in there that’s not needed. What does the original code look like?

You can access my PR here and here is a raw of the file in question.

My understanding of the goal/intention of much of the package is it’s essentially iterating over all the entity_ids, checks if they have a battery_level attribute, and creates new monitored dynamic entities for them.
They get added to a new group, also defined in the package, and sends out notifications when configurable thresholds are reached for battery levels of the new monitored entities.

I’ve been messing about with this for over a year, and I try to keep it updated, but it was written by someone who had a deeper understanding of this than me (And most of the people using it).

Unfortunately, I’m getting these errors when replacing your code into the package:

Invalid config for [automation]: invalid template (TemplateSyntaxError: Encountered unknown tag 'ns'. Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. The innermost block that needs to be closed is 'if'.) for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: Encountered unknown tag 'ns'. Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. The innermost block that needs to be closed is 'if'.) for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: Encountered unknown tag 'ns'. Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. The innermost block that needs to be closed is 'if'.) for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).

I’m still looking.

code works and passes validation on my end. How did you place it into the file?

I’ll make a branch, and post here in a sec.

I believe the source of this Byzantine wonder is this post:

I recall skimming through its code and wondering if its complexity was due to the possibility that monitoring battery status is far more difficult than I ever imagined. However I lost interest before I was convinced this elaborate mechanism is truly required to simply report “Battery, Aziz!” :man_shrugging:

Added the changes to this branch here:

Interestingly, in my ‘Developer Tools’ -> ‘Template’, I also cannot get it to work:

Wow, I didn’t think that it was still this popular.

It’s just a typo. The code refers to ns.entities when it ought to be using ns.results.

Seems to be ns.entites

FWIW, there are other solutions posted in this forum that can report low battery level with far less complexity. If you are interested, just search for ‘battery level’.

Either way, it’s referring to an undefined variable. It should be ns.results.

You’re right, I can’t deny that there are better and certainly easier ways of doing this.

I’m just trying to get this to work.

Can you elaborate on the ns.results?
When I correct both entries to ns.results I get the same error.

Sorry, I have no interest in continuing to breathe life into this thing. It appears even its author has lost interest in maintaining it.

I would suggest starting fresh or enhancing one of the other battery level solutions. Good luck!

Alright, I just wanted to know what you meant.

Thanks anyway.

just change all ns.entities to ns.results…

Maybe I don’t understand…

Can you advise?

{%- set show_unavailable = false %}
{%- set high = 30 %}
{%- set low = 0 %}
{%- set ns = namespace(results=[]) %}
{%- for s in expand('group.battery_status') %}
  {%- if s.state in ['unknown', 'unavailable'] and show_unavailable and not (s.attributes.battery_alert_disabled or s.attributes.restored) %}
    {%- set ns.results = ns.results + [  s.name ~ ' ' ~ s.state ] %}
  {%- else %}
    {%- if s.state.lower() in ['low', 'medium', 'high'] %}
      {%- if s.state.lower() == 'low' %}
        {%- set ns.results = ns.results + [ s.name ~ ' ' ~ s.state ] %}
      {%- endif %}
    {%- elif low <  s.state | float < high %}
      {%- set ns.results = ns.results + [ s.name ~ ' ' ~ s.state ] %}
    {%- endif %}
  {%- endif %}
{%- endfor %}
{{ ns.results | join(', ') }}
2 Likes

I just plopped your code into my dev tools template editor and got my expected result which agrees with my working installation of battery_alert:


but I am not sure what is going on in this thread.

@dbrunt yeah sorry man, I’m not entirely sure either, but slow progress is still progress.

@petro Thanks for that update, I’ve been messing around with it, and refined it a little to work:

{%- set show_unavailable = ( states.input_boolean.show_unavailable_batteries.state == 'on' ) %}
{%- set high = states('input_number.battery_alert_threshold_max') | float %}
{%- set low = states('input_number.battery_alert_threshold_min') | float %}
{%- set ns = namespace(results=[]) %}
{%- for s in expand('group.battery_status') %}
  {%- if s.state in ['unknown', 'unavailable'] and show_unavailable and not (s.attributes.battery_alert_disabled or s.attributes.restored) %}
    {%- set ns.results = ns.results + [  s.name ~ ':' ~ s.state ] %}
  {%- else %}
    {%- if s.state.lower() in ['low', 'medium', 'high'] %}
      {%- if s.state.lower() == 'low' %}
        {%- set ns.results = ns.results + [ s.name ~ ':' ~ s.state ] %}
      {%- endif %}
    {%- elif low <  s.state | float < high %}
{{ s.name }} ({{ s.state }})
    {%- endif %}
  {%- endif %}
{%- endfor %}

But I seem to have run into a different issue, and after some messing around I can’t seem to understand why.
The code above works in the template editor, and I can see side-by-side with the old version:

{% macro battery_level() %}
{% for entity_id in states.group.battery_status.attributes.entity_id if (
  not (
        is_state_attr(entity_id, 'battery_alert_disabled', true)
        or is_state_attr(entity_id, 'restored', true)
      )
  and states(entity_id) is not none
  and (
    (
      (
        states(entity_id) is number
        or states(entity_id) | length == states(entity_id)| int | string | length
        or states(entity_id) | length == states(entity_id)| float | string | length
      )
      and states(entity_id) | int < states.input_number.battery_alert_threshold_max.state | int
      and states(entity_id) | int > states.input_number.battery_alert_threshold_min.state | int
    )
    or states(entity_id) | lower == 'low'
    or states(entity_id) | lower == 'unknown'
    or states(entity_id) | lower == 'unavailable'
  )
) -%}
  {{ state_attr(entity_id, "friendly_name") }} ({{ states(entity_id) }})
{% endfor -%}
{% endmacro %}
{{ battery_level() }}

The trouble is, I cannot get it to fire as a persistent notification when I run automation.battery_persistent_notification.
I can see the event and automation trigger, and if I enter a static string, or the old code, the notification shows up.

Is this a type error or something that’s just not showing up?

Any idea why this would be?