If I have an automation with a binary sensor and its state goes from ‘on’ to ‘off’, how can I find out how long it was ‘on’?
Could you give an example perhaps?
The examples on the History Stats sensor are all for given time periods, e.g. last hour/day/week/whatever.
I guess what jms3000 would like (and myself as well), is
- sensor went from on to off
- How long was the sensor in the ‘on’ state before this transition
Exactly. The sensor goes on and off during the day, few hours on, few hours off. For every state change I need to know: how long was the interval. So there is a state trigger, and in the action-template I need the duration of the last interval. Is it possible to glue a timestamp attribute to the binary sensor?
set_attribute( binary_sensor.xxx, last_change, as_timestamp(now()))
That property already exists.
{{ states.binary_sensor.xxx.last_changed }}
It is a property of the state object, not an attribute. Notice the word attributes is missing between xxx and last_changed.
When I use last-changed, it gives me the amount of time between now and the state transition.
This is not the same as how long the sensor was in a given state?
last_changed gives the time that the last state change occured where something in the state changed. last_updated gives the time that the last update occured.
If you have a state object that has alot of attributes and one of the attributes updated, that will affect last_changed. If you have a binary_sensor with only the main state, it will pretty much give you the value you are looking for.
So the solution is {{ as_timestamp(now()) - as_timestamp(states.binary_sensor.xxx.last_changed) }} ?
If you guys really want it to only occur on the main state, you’d need to get inventive.
You can use the custom variables component or a input_text or input_number. Make an automation that stores the current time.
- alias: store value
trigger:
platform: state
entity_id: binary_sensor.xxx
condition:
condition: template
value_template: >
{{ trigger.from_state is defined and trigger.to_state is defined
and trigger.from_state.state != trigger.to_state.state
and trigger.to_state.state in ['on', 'off'] }}
action:
service: input_text.set_value
data_template:
entity_id: input_text.xxx
value: "{{ as_timestamp(now()) }}"
Then make a sensor that tells you the current time it’s been in that state.
sensor:
- platform: time_date
display_options:
- 'time'
- platform: template
sensors:
xxx_time_difference:
entity_id: sensor.time
value_template: >
{%- set time = as_timestamp(now()) - states('input_text.xxx') | float %}
{%- set minutes = ((time % 3600) // 60) %}
{%- set minutes = '{}min'.format(minutes) if minutes > 0 else '' %}
{%- set hours = ((time % 86400) // 3600) %}
{%- set hours = '{}hr '.format(hours) if hours > 0 else '' %}
{%- set days = (time // 86400) %}
{%- set days = '{}d '.format(days) if days > 0 else '' %}
{{ 'Less than 1 min' if time < 60 else days + hours + minutes }}
That could be the simplest solution if there aren’t any other state changes.
This is my solution. To automations, one for the sensor for going on, one for going off. The on-automations checks the time of the last off-automation and vice versa.
- alias: auto_on
trigger:
- entity_id: binary_sensor.lumi_lumi_sensor_wleak_aq1_1_1280
platform: state
to: 'on'
action:
- service: input_number.set_value
data_template:
entity_id: input_number.num1
value: >-
{{ as_timestamp(now()) - as_timestamp(states.automation.auto_off.attributes.last_triggered) }}
- alias: auto_off
trigger:
- entity_id: binary_sensor.lumi_lumi_sensor_wleak_aq1_1_1280
platform: state
to: 'off'
action:
- service: input_number.set_value
data_template:
entity_id: input_number.num1
value: >-
{{ as_timestamp(now()) - as_timestamp(states.automation.auto_on.attributes.last_triggered) }}