Hi all,
I seem to be running into an issue when trying to write some YAML, and admittedly I’m not the best at YAML and I’m a little stuck.
There must be a better way of doing this, and I’m unsure what.
There must be a YAML expert here who can see better than I can?
Here is what I’m trying to do:
{% macro battery_level() %}
{% for entity_id in states.group.battery_status.attributes.entity_id if (
{% if ( states.input_boolean.show_unavailable_batteries.state == true ) %}
not (
is_state_attr(entity_id, 'battery_alert_disabled', true)
or is_state_attr(entity_id, 'restored', true)
)
{% else %}
not is_state_attr(entity_id, 'battery_alert_disabled', true)
{% endif %}
) -%}
{{ state_attr(entity_id, "friendly_name") }} ({{ states(entity_id) }})
{% endfor -%}
{% endmacro %}
I have a {% for this if ( stuff ) %} {% endfor %} statement and I’m trying to insert an {% if %} in there based off an input_boolean.
I keep getting errors like:
Invalid config for [automation]: invalid template (TemplateSyntaxError: unexpected '%') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: unexpected '%') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: unexpected '%') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: unexpected '%') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
I’ve got the code here if you’d like to take a look:
I was originally trying to add it to this PR to fix issues of the package by @NotoriousBDG :
Once you’re inside the template ({%), there’s no need to exit again. Just remove them all from your if/else inside the if.
value_template: &low_battery_check >
{% macro battery_level() %}
{% for entity_id in states.group.battery_status.attributes.entity_id if (
if ( states.input_boolean.show_unavailable_batteries.state == true )
not (
is_state_attr(entity_id, 'battery_alert_disabled', true)
or is_state_attr(entity_id, 'restored', true)
)
else
not is_state_attr(entity_id, 'battery_alert_disabled', 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() | trim != "" }}
Invalid config for [automation]: invalid template (TemplateSyntaxError: expected token ')', got 'not') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: expected token ')', got 'not') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: expected token ')', got 'not') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
I’m not quite understanding all the layers of enumeration here, I admit.
Just read the error again, saw that it needed brackets:
value_template: &low_battery_check >
{% macro battery_level() %}
{% for entity_id in states.group.battery_status.attributes.entity_id if (
if ( states.input_boolean.show_unavailable_batteries.state == true )
{{ not (
is_state_attr(entity_id, 'battery_alert_disabled', true)
or is_state_attr(entity_id, 'restored', true)
) }}
else
{{ not is_state_attr(entity_id, 'battery_alert_disabled', true) }}
fi
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() | trim != "" }}
After adding that, same error as originally:
Invalid config for [automation]: invalid template (TemplateSyntaxError: expected token ')', got '{') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: expected token ')', got '{') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
Invalid config for [automation]: invalid template (TemplateSyntaxError: expected token ')', got '{') for dictionary value @ data['action'][0]['value_template']. Got None. (See ?, line ?).
The key thing I’m trying to achieve with all of this, is to have an switch/boolean that I can enable/disable to include/exclude the entities with a attribute of restored: true.
In this case, I’m using input_boolean.show_unavailable_batteries.
This is so that I can filter out broken/unavailable battery entities by default, but show them if needed.
There is probably a different and better way to do this, and I continue to figure it out.
All the code that has been posted has tons of errors in it.
Evaluating a input boolean against true/false. The true state of these devices is 'on'/'off'
You have an if statement that immediately goes into a not
if ( states.input_boolean.show_unavailable_batteries.state == true )
not (
This is not valid. You’d need an and between them…
From the previous bullet onward, the code is unreadable because it just doesn’t make sense.
states(entity_id) is number number is not a valid test and will always return false. states return strings, so even if it’s a number as a string it will still fail.
I’m sure I could find other things but I decided to stop. Try this out, I think it does what you want… but as I said, it’s hard to read your intentions with all the mistakes.
{%- set show_unavailable = is_states('input_boolean.show_unavailable_batteries', '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) %}
{%- ns.results = ns.results + [ s.name ~ ' ' ~ s.state ] %}
{%- else %}
{%- if s.state.lower() in ['low', 'medium', 'high'] %}
{%- if s.state.lower() == 'low' %}
{%- ns.results = ns.entites + [ s.name ~ ' ' ~ s.state ] %}
{%- endif %}
{%- elif low < s.state | float < high %}
{%- ns.results = ns.entites + [ s.name ~ ' ' ~ s.state ] %}
{%- endif %}
{%- endif %}
{%- endfor %}
{{ ns.results | join(', ') }}
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 ?).