How to calculate duration a binary sensor is currently in the on state

I have an binary_status entity that is monitoring the status of a sump pump. The pump is controlled externally by a float, but I have an ESP_Home entity that has a binary status that tells me when it is actively running. Normally the pump runs for no longer than 10 minutes. I want to know when the pump has been running for longer than 10 minutes.

How can I calculate the duration of the pump has been running? Ideally I would like to display the current running time of the pump on a card so I can visually see how long it has been running without having to look at the binary_sensor history graph.

I’m doing something similar to this: Tracking Sump Pump (Idle + Run with details) - Configuration - Home Assistant Community (home-assistant.io), but I don’t want the full day. I just want the current running duration.

Here’s my config. For the start time, I think I just need the last time the state transitioned to on.

  - platform: history_stats
    name: "Pump Run time"
    entity_id: binary_sensor.esp_pump_ejector_pump_status
    state: "on"
    type: time
    start: "{{ now().replace(hour=0, minute=0, second=0) }}"
    end: "{{ now() }}"

A way to solve it is to use a trigger with a for clause.

Look here for the state trigger with an example of using the for

configuration.yaml

template:
  - sensor:
      - name: "Last Pump Run Time"
        icon: "mdi:clock-end"
        state: >
          {% if is_state('binary_sensor.esp_pump_ejector_pump_status', 'on') %}
            {{ now() - states.binary_sensor.esp_pump_ejector_pump_status.last_changed }}
          {% else %}
            this.state
          {% endif %}

This will update every minute, so that’s your precision.

That is awesome. When the pump isn’t running the value ends up literally being: this.state.
Is there a way to keep it actually at the last run time.

Oops. Should be:

{{ this.state }}

Thanks that works perfectly.

1 Like

In the above solution, the result type is string - if you want to return number (e.g. minutes so you can plot it in graph), you need to convert it:

- name: "Heating duration"
  unique_id: solary_ohrev_doba_id
  device_class: duration
  unit_of_measurement: min
  state_class: total_increasing
  state: >
    {% if is_state('binary_sensor.solary_ohrev', 'on') %}
      {{ (as_timestamp(now()) - as_timestamp(states.binary_sensor.solary_ohrev.last_changed))/60 }}
    {% else %}
      {{ this.state }}
    {% endif %}