Kabala
(Cata)
October 8, 2020, 12:35pm
1
Is that correct?
I would like to display the time remaining from several switches.
zone_wir_time_remaining:
friendly_name: 'Zone wir Time Remaining'
value_template: >
{% set update = states('sensor.time') %}
{% if is_state('switch.zone_5', 'on') %}
{% elif is_state('switch.zone_6', 'on') %}
{% elif is_state('switch.zone_7', 'on') %}
{% elif is_state('switch.zone_8', 'on') %}
{% elif is_state('switch.zone_9', 'on') %}
{{ [ (states('input_number.zone_5_run_time')|int - (as_timestamp(now()) - as_timestamp(states.switch.zone_5.last_changed))/60)|round(0) ,0 ] | max }}
{{ [ (states('input_number.zone_6_run_time')|int - (as_timestamp(now()) - as_timestamp(states.switch.zone_6.last_changed))/60)|round(0) ,0 ] | max }}
{{ [ (states('input_number.zone_7_run_time')|int - (as_timestamp(now()) - as_timestamp(states.switch.zone_7.last_changed))/60)|round(0) ,0 ] | max }}
{{ [ (states('input_number.zone_8_run_time')|int - (as_timestamp(now()) - as_timestamp(states.switch.zone_8.last_changed))/60)|round(0) ,0 ] | max }}
{{ [ (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"
123
(Taras)
October 8, 2020, 2:29pm
2
Here are two variations you can experiment with:
zone_wir_time_remaining:
friendly_name: 'Zone wir Time Remaining'
value_template: >
{% set update = states('sensor.time') %}
{% if is_state('switch.zone_5', 'on') and is_state('switch.zone_6', 'on') and is_state('switch.zone_7', 'on') and
is_state('switch.zone_8', 'on') and is_state('switch.zone_9', 'on') %}
{{ [ (states('input_number.zone_5_run_time')|int - (now().timestamp() - states.switch.zone_5.last_changed.timestamp())/60)|round(0), 0 ] | max }},
{{ [ (states('input_number.zone_6_run_time')|int - (now().timestamp() - states.switch.zone_6.last_changed.timestamp())/60)|round(0), 0 ] | max }},
{{ [ (states('input_number.zone_7_run_time')|int - (now().timestamp() - states.switch.zone_7.last_changed.timestamp())/60)|round(0), 0 ] | max }},
{{ [ (states('input_number.zone_8_run_time')|int - (now().timestamp() - states.switch.zone_8.last_changed.timestamp())/60)|round(0), 0 ] | max }},
{{ [ (states('input_number.zone_9_run_time')|int - (now().timestamp() - states.switch.zone_9.last_changed.timestamp())/60)|round(0), 0 ] | max }}
{% else %}
0
{% endif %}
unit_of_measurement: "min"
zone_wir_time_remaining:
friendly_name: 'Zone wir Time Remaining'
value_template: >
{% set update = states('sensor.time') %}
{% if is_state('switch.zone_5', 'on') and is_state('switch.zone_6', 'on') and is_state('switch.zone_7', 'on') and
is_state('switch.zone_8', 'on') and is_state('switch.zone_9', 'on') %}
{% set ns = namespace(x = []) %}
{% for i in range(5, 10) %}
{% set ns.x = ns.x + ( [ (states('input_number.zone_'~i~'_run_time')|int - (now().timestamp() - 'states.switch.zone_'~i~'.last_changed.timestamp()')/60)|round(0), 0 ] | max) %}
{% endfor %}
{{ ns.x | join(',') }}
{% else %}
0
{% endif %}
unit_of_measurement: "min"
Kabala
(Cata)
October 8, 2020, 5:37pm
3
I thank you
what is the difference between the two variants?
123
(Taras)
October 8, 2020, 6:03pm
4
Compare their templates. They use different techniques to produce the same result.
Kabala
(Cata)
October 8, 2020, 6:29pm
5
the second variant does not work.
I switched the switch.zone_9 on for 3 minutes via input_number.zone_9_run_time.
Didn’t show me anything.
Value 0
I try the first varian.
zone_wir_time_remaining:
friendly_name: 'Zone wir Time Remaining'
value_template: >
{% set update = states('sensor.time') %}
{% if is_state('switch.zone_5', 'on') and is_state('switch.zone_6', 'on') and is_state('switch.zone_7', 'on') and
is_state('switch.zone_8', 'on') and is_state('switch.zone_9', 'on') %}
{% set ns = namespace(x = []) %}
{% for i in range(5, 10) %}
{% set ns.x = ns.x + ( [ (states('input_number.zone_'~i~'_run_time')|int - (now().timestamp() - 'states.switch.zone_'~i~'.last_changed.timestamp()')/60)|round(0), 0 ] | max) %}
{% endfor %}
{{ ns.x | join(',') }}
{% else %}
0
{% endif %}
unit_of_measurement: "min"
petro
(Petro)
October 8, 2020, 6:46pm
6
Seems like there’s a language barrier issue here and you actually want to sum all time times together?
petro
(Petro)
October 8, 2020, 6:52pm
7
Yeah, verbleibende zeit means remaining time.
123
(Taras)
October 8, 2020, 6:54pm
8
Here is part of your original code:
{% if is_state('switch.zone_5', 'on') %}
{% elif is_state('switch.zone_6', 'on') %}
{% elif is_state('switch.zone_7', 'on') %}
{% elif is_state('switch.zone_8', 'on') %}
{% elif is_state('switch.zone_9', 'on') %}
It only works if zone_9
is on
and all others are off
. If any of the other zones is on
, the template returns nothing (not even 0
).
You can prove that for yourself by pasting this simple example into the Template Editor:
{% set z1 = 1 %}
{% set z2 = 1 %}
{% set z3 = 1 %}
{% set z4 = 1 %}
{% set z5 = 1 %}
{% if z1 == 1 %}
{% elif z2 == 1 %}
{% elif z3 == 1 %}
{% elif z4 == 1 %}
{% elif z5 == 1 %}
Yes
{% else %}
No
{% endif %}
Notice that the template reports nothing (neither Yes or No).
What I did in my examples was ensure all zones must be on
. Perhaps you want it to work when one or more zones are on
?
123
(Taras)
October 8, 2020, 7:00pm
9
Well hell, then that’s not the way to sum the times …
1 Like
petro
(Petro)
October 8, 2020, 7:01pm
10
I’m thinking he just wants a summation if they are on. @klogg does the same thing with his irrigation system. The template shouldn’t be all too hard
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 ns.values = ns.values + [ states('input_number.zone_'~i~'_run_time')|int ] %}
{% endfor %}
{{ ns.values | sum if ns.values > 0 else 0 }}
unit_of_measurement: "min"
1 Like
123
(Taras)
October 8, 2020, 7:03pm
11
That ought to do it.
EDIT
Hold on, where’s the part that calculates the elapsed time for each zone?
123
(Taras)
October 8, 2020, 7:19pm
12
With the elapsed time calculation for each zone:
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"
Is this what you want? The sum of remaining time for all zones?
Or do you want to see the remaining time for each zone separately?
EDIT
If you want to see remaining time for each zone separately, this will report them as a comma-delimited string:
zone_wir_time_remaining:
value_template: >
{% set update = states('sensor.time') %}
{% set ns = namespace(values=[]) %}
{% for i in range(5, 10) %}
{% set t = [ (states('input_number.zone_'~i~'_run_time')|int -
(now().timestamp() - 'states.switch.zone_'~i~'.last_changed.timestamp()')/60)
| round(0), 0 ] | max if is_state('switch.zone_'~i, 'on') else 0 %}
{% set ns.values = ns.values + [ t ] %}
{% endfor %}
{{ ns.values | join(', ') }}
unit_of_measurement: "min"
For example, if zones 5 and 7 have remaining time and the other zones have none, the result will look something like this:
12, 0, 10, 0, 0
1 Like
Kabala
(Cata)
October 9, 2020, 4:21am
14
Hi
thanks for the great suggestions.
I want the sum of the remaining time for all zones…
123
(Taras)
October 9, 2020, 4:38am
15
Try the first of the two examples in my previous post. It reports the sum of the remaining time for all zones.
Kabala
(Cata)
October 9, 2020, 5:34am
16
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
petro
(Petro)
October 9, 2020, 11:52am
17
paste the template into the template editor and take a screenshot of your screen & results.
123
(Taras)
October 9, 2020, 3:50pm
18
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).
petro
(Petro)
October 9, 2020, 4:26pm
19
seems like PEDMAS needs to add tilda
123
(Taras)
October 9, 2020, 4:33pm
20
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: