Minutes into hours and minutes

Ok, I misunderstood. From the name of the second sensor I thought you wanted it to indicate whether or not charging was finished, not when it will finish. So maybe:

sensor:
  - platform: template
    sensors:
      minutes_to_hours:
        value_template: >
          {% set ct = states('sensor.charging_time_left') | int %}
          {% if ct == 0 %}
            Unavailable
          {% elif ct > 60 %}
            {{ ct // 60 }}:{{ '{:0>2d}'.format(ct%60) }} hours
          {% else %}
            {{ ct }} minutes
          {% endif %}
      charge_finish_time:
        value_template: >
          {% if is_state('sensor.charging_time_left','unavailable') %}
            Unavailable
          {% else %}
            {% set ct = states('sensor.charging_time_left') | int %}
            {% if ct == 0 %}
              Done
            {% else %}
              {{ (as_timestamp(now()) + ct * 60) | timestamp_custom("%H:%M") }}
            {% endif %}
          {% endif %}

Here I provide separate indications of unavailable and done. If you want to show the time it finished (i.e., in the past), then you’ll need an input_datetime to record the finish time in and an automation to trigger the recording.

EDIT: Fixed typo as described below.

1 Like

It Works :slight_smile: thanks for helping

2 Likes

Is there a way to extend this template so that if the time is > 24h it will format to “1 day”, “2 days” and so on?

Would be nice for uptime sensors.

Yes.

Modify the template so that it first checks if the total number of minutes exceeds 1440 (total minutes in a day = 24 * 60). If it does, uses integer division to divide the total minutes by 1440 to get the number of days (days = total minutes // 1440). Then continue processing to get the hours and minutes.

This topic and one or two others has been extremely helpful for this newbie to calculate time remaining to charge an EV from basic input paramaters. ie enter a start and target percent, and this calculates required kWh, then current charge rate divided into the required kWh gives a time remaining (decimal hours) and then that gets added to the current time in minutes and seconds to give an end time in local time zone. Lastly when the target kWh is delivered, the wifi circuit breaker turns off terminating the charge at the specified battery level.

Losses through the chargring process and temperature can make some variances, but generatlly I am within 1-2% state of charge of the EV battery over a full charge cycle. I’ve done this because the Renault Zoe can’t terminate the charge at a given battery charge level, so this was my solution :slight_smile:

It was a journey but with the community I have been able to get it working and without needing to bother anyone for assistance. Kudos to all!

1 Like

This sensor seems to be exactly what i need but for some reason it does not work for me…

In my code i replaced ‘sensor.charging_time_left’ with my own value and changed out the ‘Unavailable’ with ‘Unkown’ and placed the whole thing in my config.

But i get the following error message when I check my configuration:

Invalid config for [sensor.template]: invalid template (TemplateSyntaxError: unexpected ')') for dictionary value @ data['sensors']['charge_finish_time']['value_template']. Got '{% if is_state(\'sensor.zoe_charging_remaining_time\',\'Unknown\') %}\n Unknown\n{% else %}\n {% set ct = states(\'sensor.zoe_charging_remaining_time\') | int %}\n {% if ct == 0 %)\n Done\n {% else %}\n {{ (as_timestamp(now()) + ct * 60) | timestamp_custom("%H:%M") }}\n {% endif %}\n{% endif %}\n'. (See ?, line ?).

I cant make much sense of it :pensive:

Hi - post your YAML and we will have a look.

Thanks Zoogara, here it is.

sensor:
  - platform: template
    sensors:
      minutes_to_hours:
        value_template: >
          {% set ct = states('sensor.zoe_charging_remaining_time') | int %}
          {% if ct == 0 %}
            Unknown
          {% elif ct > 60 %}
            {{ ct // 60 }}:{{ '{:0>2d}'.format(ct%60) }} hours
          {% else %}
            {{ ct }} minutes
          {% endif %}
      charge_finish_time:
        value_template: >
          {% if is_state('sensor.zoe_charging_remaining_time','Unknown') %}
            Unknown
          {% else %}
            {% set ct = states('sensor.zoe_charging_remaining_time') | int %}
            {% if ct == 0 %)
              Done
            {% else %}
              {{ (as_timestamp(now()) + ct * 60) | timestamp_custom("%H:%M") }}
            {% endif %}
          {% endif %}
2 Likes

                 Replace this ) with a }
                           |
                           |
                           V
            {% if ct == 0 %)
              Done
            {% else %}
2 Likes

Yep - it’s wrong in the original one as well

1 Like

That was it. It works perfectly now :grin: Thanks for your time!

This discussion is helpful. How would I convert the units of hours (which are actually hours and minutes) into hrs:min?

For example, the sensors suggested here report: “1:22 hours”

However, I would prefer: “1 hr 22 min” or “1:22 hrs:min”

Thanks

Never mind, answer is simple:
{% if ct > 60 %}{{ ct // 60 }}:{{ '{:0>2d}'.format(ct%60) }} hrs:min{% else %}{{ct}} min{% endif %}

It might be useful to know about this thread too, since this one is now covering multiple questions and there’s probably more to come: The EPIC Time Conversion and Manipulation Thread!.

I wanted a format of:

1hr 22min

The following did the trick

      workshop_ups_timeleft_in_hr_min:
        value_template: >
          {% set ct = states('sensor.ups_timeleft') | int %}
          {{ (ct | float // 60) | round(0) }}hr {{ (ct | float % 60) | round(0) }}min    
1 Like

or in a custom button card you can write this:

   label: |
      [[[
        var minutes = states['sensor.appliance_minutes_to_end'].state;
        var hours = Math.floor(minutes / 60);
        var remainingMinutes = minutes % 60;
         return 'End in: ' + hours.toString() + ':' + remainingMinutes.toString().padStart(2, '0');
      ]]]

As long as you understand that the value won’t update live on screen. Only when you refresh the page.

custom button card with that code I’ve posted in previous post is updated live on screen.

Please post in English

Sorry, I had auto translation activated, but porbably already found a solution via KI I would like to share.
I got charge and decharge limits activated at my Zendure setup (20%min , 85%max). Here is my KI solution that need to check tomorrow and might be improved:

sensor:
  - platform: template
    sensors:
      battery_charge_hours:
        value_template: >
          {% set ct = states('sensor.remainInputTime') | int %}
          {% set current_level = states('sensor.electriclevel') | int %}
          {% set charge_limit = 85 %}
          {% set remaining_charge = charge_limit - current_level %}
          {% set adjusted_ct = (ct * remaining_charge) / (100 - current_level) %}
          {% if adjusted_ct == 0 %}
            Unavailable
          {% elif adjusted_ct > 60 %}
            {{ adjusted_ct // 60 }}:{{ '{:0>2d}'.format(adjusted_ct%60) }}
          {% else %}
            {{ adjusted_ct }} minutes
          {% endif %}
      charge_finish_time:
        value_template: >
          {% if is_state('sensor.remainInputTime','unavailable') %}
            Unavailable
          {% else %}
            {% set ct = states('sensor.remainInputTime') | int %}
            {% set current_level = states('sensor.electriclevel') | int %}
            {% set charge_limit = 85 %}
            {% set remaining_charge = charge_limit - current_level %}
            {% set adjusted_ct = (ct * remaining_charge) / (100 - current_level) %}
            {% if adjusted_ct == 0 %}
              Done
            {% else %}
              {{ (as_timestamp(now()) + adjusted_ct * 60) | timestamp_custom("%H:%M") }}
            {% endif %}
          {% endif %}
      battery_remain_hours:
        value_template: >
          {% set ct = states('sensor.remainOutTime') | int %}
          {% set current_level = states('sensor.electriclevel') | int %}
          {% set discharge_limit = 20 %}
          {% set remaining_discharge = current_level - discharge_limit %}
          {% set adjusted_ct = (ct * remaining_discharge) / current_level %}
          {% if adjusted_ct == 0 %}
            Unavailable
          {% elif adjusted_ct > 60 %}
            {{ adjusted_ct // 60 }}:{{ '{:0>2d}'.format(adjusted_ct%60) }}
          {% else %}
            {{ adjusted_ct }} minutes
          {% endif %}
      decharge_finish_time:
        value_template: >
          {% if is_state('sensor.remainOutTime','unavailable') %}
            Unavailable
          {% else %}
            {% set ct = states('sensor.remainOutTime') | int %}
            {% set current_level = states('sensor.electriclevel') | int %}
            {% set discharge_limit = 20 %}
            {% set remaining_discharge = current_level - discharge_limit %}
            {% set adjusted_ct = (ct * remaining_discharge) / current_level %}
            {% if adjusted_ct == 0 %}
              Done
            {% else %}
              {{ (as_timestamp(now()) + adjusted_ct * 60) | timestamp_custom("%H:%M") }}
            {% endif %}
          {% endif %}