Time is available in format xm e.g. 17m and today after vacuum was unusually diligent I discovered value was actually in form yh xm e.g. 1h 24m which broke my automation:
- alias: Send Servantess to dock when someone arrives home during repeated cleanup
trigger:
- platform: state
entity_id: group.people
to: 'home'
condition:
condition: and
conditions:
- condition: state
entity_id: vacuum.servantess
state: 'cleaning'
- condition: template
value_template: '{{ states.sensor.vacuum_cleanups_today.state | int > 1 }}'
- condition: template
value_template: '{{ states.sensor.vacuum_cleanups_today.attributes.value | replace("m", "") | int | default(0) > 10 }}'
action:
- service: vacuum.return_to_base
entity_id: vacuum.servantess
What would be the best concise and clean way how to convert states.sensor.vacuum_cleanups_today.attributes.value to minutes for comparing?
I did not find a way to control the format how sensor sets time value so value_template should work for both xm and yh xm patterns.
And building on the previous suggestions, how about:
- condition: template
value_template: >
{% set s = state_attr('sensor.vacuum_cleanups_today', 'value') %}
{% set t = strptime(s, '%Hh %Mm' if 'h' in s else '%Mm') %}
{{ (t.hour * 60 + t.minute) > 10 }}
EDIT: Hmm, just realized, that / should probably be a *, right??? (Updated above accordingly.)
BTW, you don’t need to specify condition: and – that is the default. Also, your second condition would normally be written using the numeric_state condition. So:
condition:
- condition: state
entity_id: vacuum.servantess
state: 'cleaning'
- condition: numeric_state
entity_id: sensor.vacuum_cleanups_today
above: 1
- condition: template
value_template: >
{% set s = state_attr('sensor.vacuum_cleanups_today', 'value') %}
{% set t = strptime(s, '%Hh %Mm' if 'h' in s else '%Mm') %}
{{ (t.hour * 60 + t.minute) > 10 }}
On the other hand, you could do the whole thing in one template condition:
condition:
condition: template
value_template: >
{% set s = state_attr('sensor.vacuum_cleanups_today', 'value') %}
{% set t = strptime(s, '%Hh %Mm' if 'h' in s else '%Mm') %}
{{ is_state('vacuum.servantess', 'cleaning') and
states('sensor.vacuum_cleanups_today')|int > 1 and
(t.hour * 60 + t.minute) > 10 }}
but while this would be logically correct it mathematically wrong and hard to perceive to anyone reading so yours is much better and variations be reused in my other automations.
Don’t listen to that. It’s very old, and given the way things work now (and I suspect the way they did even back then), there are wrong conclusions being drawn.
First and foremost, EVERY entity’s state is a string, even if it looks like a number. (And by “state” I mean as in a State Object’s state field.)
Second, the numeric_state trigger and condition first attempt to convert the entity’s state (string) to a float (i.e., number) before making the comparison to above and/or below. They also handle the case where the state is ‘unknown’ or the state object is None, etc.
In most cases, the numeric_state trigger or condition is the same as something like {{ states('XXX.YYY')|float > above|float }}.
So I polished automation to final state of the art.
- alias: Send Servantess to dock when someone arrives home during repeated cleanup
trigger:
- platform: state
entity_id: group.people
to: 'home'
condition:
- condition: state
entity_id: vacuum.servantess
state: 'cleaning'
- condition: template
value_template: >
{% set s = state_attr('sensor.vacuum_cleanups_today', 'value') %}
{% set t = strptime(s, '%Hh %Mm' if 'h' in s else '%Mm') %}
{{ states('sensor.vacuum_cleanups_today') | int > 1 and (t.hour * 60 + t.minute) > 10 }}
action:
- service: vacuum.return_to_base
entity_id: vacuum.servantess
I intentionally left cleaning state condition separated to return quickly before setting variable and performing calculations.