Try the first of the two examples in my previous post. It reports the sum of the remaining time for all zones.
somehow that doesn’t work.
This is a part of my current configuration.
time remaining for each zone work for me.
sum of the remaining time for all zones does not work.
Am I doing something wrong?
switch.zone_9 and input_number.zone_9_run_time ist Hecke
zone_9_time_remaining:
friendly_name: 'Time Remaining'
value_template: >
{% set update = states('sensor.time') %}
{% if is_state('switch.zone_9', 'on') %}
{{ [ (states('input_number.zone_9_run_time')|int - (as_timestamp(now()) - as_timestamp(states.switch.zone_9.last_changed))/60)|round(0) ,0 ] | max }}
{% else %}
0
{% endif %}
unit_of_measurement: "min"
################ SUMME ZEIT ZONE WIR ################
gesamtzeit_wir:
value_template: "{{ states('input_number.zone_5_run_time')|int + states('input_number.zone_6_run_time')|int + states('input_number.zone_7_run_time')|int + states('input_number.zone_8_run_time')|int + states('input_number.zone_9_run_time')|int }}"
friendly_name: 'gesamtzeit'
zone_wir_time_remaining:
value_template: >
{% set update = states('sensor.time') %}
{% set ns = namespace(values=[]) %}
{% for i in range(5, 10) if is_state('switch.zone_'~i, 'on') %}
{% set t = [ (states('input_number.zone_'~i~'_run_time')|int -
(now().timestamp() - 'states.switch.zone_'~i~'.last_changed.timestamp()')/60)
| round(0), 0 ] | max %}
{% set ns.values = ns.values + [ t ] %}
{% endfor %}
{{ ns.values | sum }}
unit_of_measurement: "min
paste the template into the template editor and take a screenshot of your screen & results.
I think I know what prevents this from working.
I created appropriate entities to test the template. Here’s the error message:
TypeError: unsupported operand type(s) for -: ‘float’ and ‘str’
It’s complaining about this subtraction:
now().timestamp() - 'states.switch.zone_'~i~'.last_changed.timestamp()'
Upon evaluation, the first term is a float but the second one is a string.
I’m expecting the second term to be evaluated like this:
- Concatenate the two strings with the variable and then evaluate the resulting expression to get the timestamp (which would be a float).
What’s happening is:
- Concatenate the two strings with the variable and nothing more. The result is a string.
One would need to force evaluation of the resulting string using something like an eval
function but it’s not available:
now().timestamp() - eval('states.switch.zone_'~i~'.last_changed.timestamp()')
I don’t know of a workaround because last_changed
is not an attribute so it cannot be referenced using state_attr()
.
You can see the behavior I’ve described in this screenshot. I’m using input_boolean
instead of switch
but that’s immaterial.
EDIT
It seems to me that the solution is to iterate a generator containing the switch
entities. That would allow for accessing each item’s last_updated
without resorting to string concatenation. I’ll give this a go later (after lunch).
seems like PEDMAS needs to add tilda
I got it to work.
Create a group containing the zone switches:
#group:
sprinkler_zones:
- switch.zone_5
- switch.zone_6
- switch.zone_7
- switch.zone_8
- switch.zone_9
Here’s the revised Template Sensor that uses the group.
zone_wir_time_remaining:
value_template: >
{% set update = states('sensor.time') %}
{% set ns = namespace(values=[]) %}
{% for i in expand('group.sprinkler_zones') | selectattr('state', 'eq', 'on') | list %}
{% set t = [ (states('input_number.'~i.object_id~'_run_time')|int -
(now().timestamp() - i.last_changed.timestamp())/60) | round(0), 0 ] | max %}
{% set ns.values = ns.values + [ t ] %}
{% endfor %}
{{ ns.values | sum }}
unit_of_measurement: "min"
Screenshot showing the sum of the remaining time. Currently, two of the five zones are on
and have been running for a few minutes.
UPDATE: Still correctly showing the decreasing time remaining:
Many Thanks,
I’ll try it in a moment.
Can I do that with the sum of all input_number times?
Also through the switch group?
That’s how it looks for me at the moment.
gesamtzeit_wir:
value_template: "{{ states('input_number.zone_5_run_time')|int + states('input_number.zone_6_run_time')|int + states('input_number.zone_7_run_time')|int + states('input_number.zone_8_run_time')|int + states('input_number.zone_9_run_time')|int }}"
friendly_name: 'gesamtzeit'
Yes, the template would be simpler. This calculates the sum of all input_numbers whose corresponding switch is on
.
zone_wir_time_total:
value_template: >
{% set update = states('sensor.time') %}
{% set ns = namespace(values=[]) %}
{% for i in expand('group.sprinkler_zones') | selectattr('state', 'eq', 'on') | list %}
{% set ns.values = ns.values + [ states('input_number.'~i.object_id~'_run_time')|int ] %}
{% endfor %}
{{ ns.values | sum }}
unit_of_measurement: "min"
EDIT
Correction. Leading (
removed from + [ (states
Hi,
Unfortunately does not work.
gesamtzeit_wir:
value_template: >
{% set update = states('sensor.time') %}
{% set ns = namespace(values=[]) %}
{% for i in expand('group.zone_wir') | selectattr('state', 'eq', 'on') | list %}
{% set ns.values = ns.values + [ (states('input_number.'~i.object_id~'_run_time')|int ] %}
{% endfor %}
{{ ns.values | sum }}
unit_of_measurement: "min"
invalid template (TemplateSyntaxError: unexpected ‘]’, expected ‘)’) for dictionary value @ data[‘template’]. Got ’ gesamtzeit_wir:\n value_template: >\n {% set update = states(‘sensor.time’) %}\n {% set ns = namespace(values=[]) %}\n {% for i in expand(‘group.zone_wir’) | selectattr(‘state’, ‘eq’, ‘on’) | list %}\n {% set ns.values = ns.values + [ (states(‘input_number.’~i.object_id~’_run_time’)|int ] %}\n {% endfor %}\n {{ ns.values | sum }}\n unit_of_measurement: “min”’
That was due to a typo I made. There was an extra (
in the template. I have removed it from the example posted above. I have also tested it and confirmed it works. Make the same correction (or copy-paste the revised example) and try again.
What are the results of your other test? Did the Template Sensor that calculates the remaining time work for you?
somehow that doesn’t work for me.
sum time remaining funktioniert
zone_wir_time_total:
value_template: >
{% set update = states('sensor.time') %}
{% set ns = namespace(values=[]) %}
{% for i in expand('group.zone_wir') | selectattr('state', 'eq', 'on') | list %}
{% set ns.values = ns.values + [ states('input_number.'~i.object_id~'_run_time')|int ] %}
{% endfor %}
{{ ns.values | sum }}
unit_of_measurement: "min"
zone_wir:
name: Zonen wir
entities:
- switch.zone_5
- switch.zone_6
- switch.zone_7
- switch.zone_8
- switch.zone_9
is zone_wir in the group section? Doesn’t look like it based on what you posted.
We have now arrived at a point in this thread where we are discussing the behavior of a second Template Sensor (zone_wir_time_total
) but have not received confirmation the first one works (zone_wir_time_remaining
).
It’s important to learn if the first one works (to confirm the selected calculation technique is correct) before proceeding to analyze the operation of the second one (which is derived from the same technique).
Does “sensor.zone_wir_time_remaining” report correct values? If it does not, then we should return to correcting it before jumping ahead to the second Template Sensor.
NOTE
In your post’s screenshot, all switches are off. The template sums the switches that are on. If you want it to sum all switches, regardless of their state, then the template becomes even simpler:
zone_wir_time_total:
value_template: >
{% set update = states('sensor.time') %}
{% set ns = namespace(values=[]) %}
{% for i in expand('group.sprinkler_zones') | list %}
{% set ns.values = ns.values + [ states('input_number.'~i.object_id~'_run_time')|int ] %}
{% endfor %}
{{ ns.values | sum }}
unit_of_measurement: "min"
Hello,
zone_wir_time_total works very well.
I try that
Sum of all switches, regardless of their status.
I think that was the mistake.
It works now.
thank you very much
how can i change minutes?
For example:
70 min.
in
1h 10min
Replace this line:
{{ ns.values | sum }}
with this:
{% set t = ns.values | sum %}
{{ '{}h {}min'.format(t//60, t%60) }}
Thank you,
You helped me a lot
Hi,
me again.
How can I configure a single switch in this way?
Right now just show me the minutes.
zone_9_time_remaining:
friendly_name: 'Time Remaining'
value_template: >
{% set update = states('sensor.time') %}
{% if is_state('switch.zone_9', 'on') %}
{{ [ (states('input_number.zone_9_run_time')|int - (as_timestamp(now()) - as_timestamp(states.switch.zone_9.last_changed))/60)|round(0) ,0 ] | max }}
{% else %}
0
{% endif %}
unit_of_measurement: "min"
zone_9_time_remaining:
friendly_name: 'Time Remaining'
value_template: >
{% set update = states('sensor.time') %}
{% if is_state('switch.zone_9', 'on') %}
{% set t = [ (states('input_number.zone_9_run_time')|int - (as_timestamp(now()) - as_timestamp(states.switch.zone_9.last_changed))/60)|round(0) ,0 ] | max %}
{% else %}
{% set t = 0 %}
{% endif %}
{{ '{}h {}min'.format(t//60, t%60) }}
unit_of_measurement: "min"
Hei Taras,
you are the best…
Thank you again