I try to use a template binary sensor to check if the valve state of any climate device which has a valve attribute is bigger than “0”.
The template
{% for item in states.climate if (item.attributes.valve is defined and item.attributes['valve'] | int > 0) %}{{ item.name }}{% endfor %}
shows the correct items, but how can I use the output in a binary sensor? The sensor shows always “off”. My current code for this is:
- platform: template
sensors:
heizung_waermebdarf:
friendly_name: "Heizung Waermebedarf"
value_template: "{% for item in states.climate if (item.attributes.valve is defined and item.attributes['valve'] | int > 0) %}{% endfor %}"
The template is not returning anything, it’s just doing the loop. Try
value_template: "{% for item in states.climate if (item.attributes.valve is defined and item.attributes['valve'] | int > 0) %}True{% endfor %}"
Don’t know if this is the correct syntax, personally I would use more brackets, so it becomes clear where the if begins and ends.
value_template: "{%- for item in states.climate -%}{%- if (item.attributes.valve is defined and item.attributes['valve'] | int > 0) -%}True{%- endif -%}{%- endfor -%}"
I have ideas, but I cannot help implementing in Python or Jinja2.
I another programming language I would use a “return” statement to return a result and escape the loop. Something like this:
for(item in states.climate) {
if(item.attributes.valve is defined and item.attributes['valve'] | int > 0) {
return True
}
}
return False
Or, as an alternative one could use a variable initialized with “False” and a boolean operator.
set result = False
for(item in states.climate) {
result = result or (item.attributes.valve is defined and item.attributes['valve'] | int > 0)
}
return result
But as I said, I don’t know how to implement this for HA.
PS: Just checked the Jinja2 documentation on loops and it it possible to ‘break’ a loop.
So, the following could work:
value_template: "{%- for item in states.climate -%}{%- if (item.attributes.valve is defined and item.attributes['valve'] | int > 0) -%}True{% break %}{%- endif -%}{%- endfor -%}"
Unfortunately its not working, the template designer gaves me an ´Error rendering template: TemplateSyntaxError: Encountered unknown tag ‘break’. Jinja was looking for the following tags: ‘elif’ or ‘else’ or ‘endif’. The innermost block that needs to be closed is ‘if’.´
Quick Q: do you want your template sensor to be on if at least one of the valves is on?
If so why don’t you group them? A group will be on if at least one entity is on.
To my understanding, groups works on sensor’s state, not sensor’s attributes. But by reading the documentation on template binary sensor, I ask myself if you really have too much climate sensors to address them directly (ich nehme mal an, es sind Heizkörperventile).
So, how about:
binary_sensor:
- platform: template
sensors:
heizung_waermebedarf:
value_template: >-
{{
not(
is_state_attr('climate.sensor1','valve',0) and
is_state_attr('climate.sensor2','valve',0) and
is_state_attr('climate.sensor3','valve',0) and
is_state_attr('climate.sensor4','valve',0) and
is_state_attr('climate.sensor5','valve',0)
)
}}
Thanks @m0wlheld, that’s why I wrote “template sensor” I know it means extra work in creating a template sensor for each needed attribute, but that’s a one off and then all you’d need to use is the group in the trigger.
Anyway @nicx, try @m0wlheld 's suggestion above as it might be even easier than mine…
thanks again to both of you @m0wlheld@lolouk44, as already written a group is not working in my case because I am using attributes with a integer and not boolean state.
I will try your last solution @m0wlheld, even if this is a manual maintained solution and I am a fan of automatical solutions But you are right, I have about 10 “Heizkörperventile” and therfor the manual effort is ok for me in this case