How long switch has been on for?

I want to have a sensor for displaying how long my coffee machine has been on for. I have used the following code with the history_stats field:

  - platform: history_stats
    name: Coffee On
    entity_id: switch.coffee
    state: 'on'
    type: time
    start: '{{ now().replace(hour=0, minute=0, second=0) }}'
    end: '{{ now() }}'  

But this just totals up the amount its been on for the entire day. My coffee machines takes a minimum of 20 minutes to warm up, so just want to query how long its been on for at any time. If it’s currently off then the sensor should say ‘off’.

How would I do this?
Thanks

Try the following Template Sensor. You will need to define sensor.time using the Time & Date integration.

  - platform: template
    sensors:
      coffee_time:
        entity_id:
          - sensor.time
          - switch.coffee
        value_template: >
          {% set t = 0 if states('switch.coffee') == 'off' else now().timestamp() - states.switch.coffee.last_changed.timestamp() %}
          {{ t | timestamp_custom('%H:%M', false) }}

The sensor’s template will be evaluated whenever sensor.time changes state (every minute) or switch.coffee changes state (on or off). It simply subtracts the switch’s last_changed from the current time (but only if the switch is currently on, otherwise it simply reports 0). The result is a time value in seconds which is converted so it appears in HH:MM format.


EDIT
Corrected typo in template’s last line.

1 Like

Thank you for this. I have just turned the switch on but get this as the sensor result

01:03, false

Not sure what this means!

Oops! The final line of the template has a typo. I’ll correct the post to prevent misleading other users.

Change this:

          {{ t | timestamp_custom('%H:%M, false') }}

to this:

          {{ t | timestamp_custom('%H:%M', false) }}

Let me know if it works the way you want it to. If not, I’m sure it can be adjusted to meet your requirements.

1 Like

Sorry to revive an old thread but will this work over more than one day? I want to keep a record of how long my heating switch has been on for over the course of a month and then reset at say 1am on the first day of each month but struggling to find a way to do it!

Theoretically, yes, it can work for periods greater than a day. Practically, no, because when you restart Home Assistant, all entities get their last_updated property reset to the current time.

I want to keep a record of how long my heating switch has been on for over the course of a month

The technique shown above would not be the way to do that. You want cumulative time the switch was on over the course of a month. That’s one of the things that the History Statistics sensor can do. It analyzes the historical data in the recorder database. However, by default, it is configured to record a maximum of 10 days worth of data.

If you extend it to a month, the database’s size may become substantial (it records everything and not in the most efficient manner). It was never designed for (efficient) long-term storage. For that purpose, it’s recommended to use alternative storage solutions such as InfluxDB.

Ah ok, I’ve had a brief read of the influxdb page and the recorder page so that makes sense. Influxdb looks a bit above my skill level so I don’t think I’ll be going that route! Looking at the recorder integration though could I limit the amount of things recording to it (basically just thermostats, switches and lights, approx 15 entities) and then extend the length it keeps them to 30 days? Or would this still lead to a massive database size? I’m running HA on a raspberry pi 4, 2gb with a 32gb SD card if that helps?

You can try that strategy and after a week you can estimate how large the database will grow in a month.

Things you should know:

  • When you create a full snapshot, it includes the database, and is stored on your 32Gb SD card. Keep that in mind when estimating how much ‘headroom’ is available on the SD card.
  • I’ve seen reports of database corruption (usually, and unfortunately, when a snapshot is restored). The standard ‘fix’ is to simply delete the database and allow Home Assistant to create a new (empty) one. That’s probably not comforting news given that you want to preserve a month’s worth of data.

My sensor has stopped working in the last few days and now always just reports 00:00. The code I use is as follows:

  - platform: template
    sensors:
      coffee_time:
        friendly_name: 'Coffee time'
        entity_id:
          - sensor.time
          - switch.coffee
        value_template: >
          {% set t = 'off' if states('switch.coffee') == 'off' else now().timestamp() - states.switch.coffee.last_changed.timestamp() %}
          {{ t | timestamp_custom('%H:%M', false) }}

If I just use the value_template section in Developer Tools it works fine. Can anyone spot why the sensor.coffee_time is not being set?

Thanks

I assume you are using version 0.115.X. If you check the log (Configuration > Logs) you will probably find one or messages informing you that entity_id has been deprecated (and should be removed).

As a result, whatever entities you have listed in entity_id are now ignored. That means your Template Sensor is only updated whenever one of the identifiable entities within the template changes state. In other words, the template is no longer refreshed every minute, according to sensor.time, but only when switch.coffee changes state.

To correct it, simply add this line to the template:

          {% set x = states('sensor.time') %}

For more information:

2 Likes

It’s work!
Thanks!

Hi, Thank you for the code which works so far. However, I amended the sensor to show seconds

(timestamp_custom('%H:%M:%S', false)

but the sensor is not updated any seconds. So, it shows the seconds but they will change only every 30 seconds or so.

Is there a way to have the sensor updated every second?

I don’t think so, not with that technique.

You could have an automation run every second with /1 and count up on a counter helper when the sensor/device is on.
Then have a sensor that converts the counter to h:m:s value.

I had a simpler requirement: I just wanted to send a notification that showed how long the washer or dryer ran before completing. A little pointless, yes… :laughing:

I created a Date and/or time helper named “Dryer Started”, and then a “Laundry Duration Tracker” automation:

alias: Dryer Duration Tracker
mode: single
trigger:
  - platform: state
    id: dryer
    entity_id:
      - binary_sensor.dryer_is_drying
    to: 'on'
action:
    - service: input_datetime.set_datetime
      target:
        entity_id: input_datetime.dryer_started
      data:
        datetime: '{{ now() }}'

And the automation that sends the notification:

alias: Dryer done
mode: single
trigger:
  - platform: state
    entity_id:
      - binary_sensor.dryer_is_drying
    from: 'on'
    to: 'off'
condition: []
action:
  - service: notify.ios
    data:
      title: Dryer is done
      message: >-
        Ran for {{ state_attr("input_datetime.dryer_started", "timestamp") | as_datetime | relative_time }}

This is a bit simplified (I update the helper for both the washer and dryer in the same automation).

The important bit of the duration is in the message above, which renders to something like “Ran for 33 minutes”.

2 Likes

@blalor, thanks so much for posting this. You say it is a little pointless, but I have a real-life example of why it isn’t pointless with a problem I have been scouring a solution to: We have four 20+ year olds living in our home. My gas bill has doubled over time, and I suspect the ‘tankless’ hot water heater (that to a 20 y/o means “FREE HOT WATER FOREVER!” I’m going to adapt your solution above to a use case to track the duration that a Zigbee switch my H/W heater is plugged into exceeds 10W (it is 2.5W ‘asleep’ and 60W running).

When the switch exceeds 10w, start tracking, and when the switch senses a drop back below 10W the water heater is off and the tracker can record the time elapsed and send me a notification with a timestamp - then I can catch the offending hot water hog! Why not just listen for the water? Those young guys shower much later than when this old geezer goes to bed!

1 Like

Glad it was useful! Gotta admit, tho, I do love me a HOT shower. :wink:

1 Like

i know this is an older topic but just got this working… when i turn on my coffee machine the timer works great. Soon as I turn off the coffee machine, the timer says unavailable. any ideas?

Yeah mine does that, never worked out how to fix it or make it ‘off’.

Maybe this will help?

1 Like

that worked perfectly, thanks a lot for that! this is what i used…

  - platform: template
    sensors:
      coffee_counter:
        friendly_name: "Coffee On Duration"
        value_template: >-
          {% if (states('sensor.coffee_time')) == "unavailable" %}
            Off
          {% else %}
            {{states('sensor.coffee_time')}}
          {% endif %}
1 Like