Subtract two time sensors to get duration (in min), then %

Hi all.

Struggling to create a sensor for an automation.

  1. I have two time sensors for my dishwasher (start and finish). I want to subtract “start” from “finish” to get the total duration (in minutes) for the program. Unfortunately this is not delivered by the integration. Attention: the value can also be “unknown” when no program is running.

  2. Then I want to divide the “remaining time” by the created “duration” to get the %-value. I want to use this value for an automation related to WLED (status progress bar).

I’m pretty new to HA and already stuck at the first challenge “calculate the duration if state is not unknown”.
Can you please assist me?

Thank you!

You’re going to need Template Sensors.


Jinja Templating Math Operations

Thanks but I’m still struggling to set it up :frowning: Any more hints?

I’ve found it easier to do this type of thing after you convert the datetime to a unix timestamp

{{ ((states(‘sensor.finish’) | as_timestamp) - (states(‘sensor.start’) | as_timestamp)) | as_datetime }}

1 Like

What have you tried?

Community Guidelines #9: Show your Work

Since this is your first Template sensor, you probably want to start out using the Template Helper which is done completely in the GUI.

Will dig into this. Really appreciate your help.

I use this format under developer tools, template:
{{ (today_at(states('sensor.dishwasher_finish_at')) - as_timedelta(states('sensor.dishwasher_started_at'))).timestamp() }}
It responses a really high number when the program is running. It responds
ValueError: could not convert str to datetime: 'unknown'
if no program is running.

So first at all I want to have a “if else” connection to avoid errors.

That’s the easier part, before we go there we need to know what formats we will be dealing with.

When the dishwasher is running what do the state values of dishwasher_started_at and dishwasher_finish_at look like?

For the “remaining time” sensor, how do you want the state presented? The screen shot posted above notes the unit of measurement is minutes… should that be whole minutes only or fractional minutes?

That is likely because you are using at least one incorrect time manipulation function for the inputs you have or the outputs you want. There are many functions related to time and time math, making it very easy to tie yourself in knots if you don’t have a clear understanding of where you are starting and what your goal is.

1 Like

Thanks will check tomorrow when the dishwasher is running.
Remaining time is a sensor which is provided by the add on and shows the time left. I will also check which format is provided.

In the meantime, this function

{{ ((states(‘sensor.dishwasher_finish_at’) | as_timestamp) - (states(‘sensor.dishwasher_started_at’) | as_timestamp)) | as_datetime }}

leads to
TemplateSyntaxError: unexpected char '‘' at 12

Does this already helps? I was looking in the history.

Bildschirmfoto 2024-03-21 um 09.52.52

If they are both just time strings in HH:MM format, then the remaining percentage can be found with:

{% set start = states('sensor.dishwasher_started_at') %}
{% set finish = states('sensor.dishwasher_finish_at') %}

{% if 'unknown' in [start, finish] %}
{% else %}
  {% set total_min = ( today_at(finish) - today_at(start) ).total_seconds() / 60 %}
  {{ ((states('sensor.dishwasher_remaining_time') | int(0) / total_min) * 100) | int }}
{% endif %}

EDIT: Corrected missing multiplier in final expression

1 Like

Oh wow. Thank you very much but the response is the same time ans the finish time (dishwasher is running). Attached the screenshot of the entities. Maybe the problem is the entity of “remaining time” wich is given in min. But the calculation responses with hh:mm?

Copy/paste format issue, replace with a single quote

1 Like

Now it’s getting suspicious. I am getting the result “0” which means, that “unknown” was detected. It doesn’t make sense because there was no “unknown” state.

That’s my fault… I forgot to multiply the value by 100 for the percentage. I have corrected it in the post above.

For percentage completed, subtract the results from 100.

{% set start = states('sensor.dishwasher_started_at') %}
{% set finish = states('sensor.dishwasher_finish_at') %}

{% if 'unknown' in [start, finish] %}
{% else %}
  {% set total_min = ( today_at(finish) - today_at(start) ).total_seconds() / 60 %}
  {{ 100 - ((states('sensor.dishwasher_remaining_time') | int(0) / total_min) * 100) | int }}
{% endif %}
1 Like

Argh thanks. Unfortunately the program has finished and I can’t test it :slight_smile: But tmrw I will do!

Do I need to specify more in the template helper?
Really appreciate your help.

No, the other configuration variables are optional… If for some reason you wanted to keep long term statistics, you would need to set State class to measurement.

1 Like

Thanks! Will validate tmrw and will drop a message.

It’s working! Great! Thank you very much. Already linked it to WLED (precent) :smiley:

1 Like