Template to calculate percentage based on runtime of device

I am automating a dehumidifier using the generic_hygrostat platform using a z-wave plug and separate humidity sensor. I already have a binary template sensor that tells me when it is running based on the plug’s power draw, and an automation that tells me to empty the water bin when the generic_hygrostat triggers turns on the plug, but no power draw is detected for several minutes (indicating the dehumidifier paused for a full bin). What I’d like to do is calculate a rough percentage of the water bin based on the dehumidifier’s runtime in order to anticipate when I need to empty, i.e., to get notifications when the bin is 75% full. I have a rough idea of how long the dehumidifier runs before the bin fills up. I imagine the first step would be to create a template sensor that calcuates the total amount of runtime between emptying and filling the water bin. Then, I would divide the hours-run by the estimated total runtime to arrive at a percentage. I’m looking for some help in creating the necessary template sensors. Thank you.

You need to make a template sensor that determines when it starts to draw. And a template sensor that determines the duration. And a template sensor that calculates the percentage. You can skip the second one if needed, but why not have that info.

template:
- trigger:
  - platform: state
    entity: binary_sensor.your_binar_sensor
    to: 'on'
  sensor:
  - name: Dehumidifier Start
    unique_id: dehumidifer_start
    device_class: timestamp
    state: "{{ now() }}"

- sensor:
  - name: Dehumidifier Duration
    unique_id: dehumidifier_duration
    device_class: duration
    unit_of_measurement: s
    state: "{{ (now() - states('sensor.dehumidifer_start') | as_datetime).total_seconds() }}"
    availability: "{{ 'sensor.dehumidifer_start' | has_value }}"

  - name: Dehumidifier Percent
    unique_id: dehumidifier_percent
    device_class: percent
    state: >
      {% set hours_for_100_percent = 10 %}
      {{ min((states('sensor.dehumidifer_percent') | float / (hours_for_100_percent * 60 * 60)) * 100, 100) }}
    availability: "{{ states('sensor.dehumidifer_percent') | is_number }}"

Just fill in binary_sensor.your_binar_sensor with your binary sensor and fill in hours_for_100_percent = 10 with the number of hours it takes to get to 100%.

1 Like

Thanks, this looks great. I will test it once I get home and empty the humidifier to start fresh.

Looking at your code, I’m wondering if there is also a way to extrapolate the exact time it takes for the dehumidifier to fill from start to finish. As I said, I have a rough idea of how long it takes to fill, but it would be nice to get an exact number based on one full cycle. Thanks again for your help.

Sorry, I actually hadn’t considered something: the dehumidifier doesn’t run continuously, but rather starts and stops throughout the day based on the relative humidity. It may run for an hour and then stop for two hours before the humidity rises enough to trigger the generic_hygrostat. It seems like the Dehumidifier Duration sensor will only calculate the number of seconds from the last time the dehumidifier turned on and will return to zero when it reaches its setpoint. Is there any way to include that in the calculation?

I figured it out with the use of an extra input_boolean and a history-stats sensor. I created an input_boolean that turns on when my dehumidifier-full automation triggers, and off when I empty the tank and power begins to draw again. Then I created a history-stats sensor and modified the above code as follows:

template:
- trigger:
  - platform: state
    entity_id: input_boolean.dehumidifier_full
    to: 'off'
    from: 'on'
  sensor:
  - name: Dehumidifier Start
    unique_id: dehumidifier_start
    device_class: timestamp
    state: "{{ now() }}"

- sensor:    
  - platform: history_stats
    name: Dehumidifier Runtime Since Empty
    entity_id: binary_sensor.dehumidifier_running
    state: "on"
    type: time
    start: "{{ states('sensor.dehumidifier_start') }}"
    end: "{{ now() }}"
  - name: Dehumidifier Duration
    unique_id: dehumidifier_duration
    device_class: duration
    state: "{{ states('sensor.dehumidifier_runtime_since_empty') | float * 60 * 60}}"
    availability: "{{ 'sensor.dehumidifier_start' | has_value }}"
  - name: Dehumidifier Percent
    unique_id: dehumidifier_percent
    device_class: moisture
    state: >
      {% set hours_for_100_percent = 30 %}
      {{ min((states('sensor.dehumidifier_duration') | float / (hours_for_100_percent * 60 * 60)) * 100, 100) | round(default=0) }}
    availability: "{{ states('sensor.dehumidifier_duration') | is_number }}"

That yaml is invalid in HA, are you sure you’re using that? Or is the history stats entity in a separate sensor section?

Yeah it’s in a separate sensor section, I moved it in my post for reading ease but should have known it would be invalid. I’ll edit the post to correct later, thanks for catching it