I have a sensor template set up for the OctoPrint component:
sensor:
- platform: template
sensors:
hevo_3d_printer_time_elapsed_friendly:
value_template: >-
{%- set time = states('sensor.hevo_3d_printer_time_elapsed') | int -%}
{%- set seconds = (time % 60) | int -%}
{%- set minutes = ((time % 3600) / 60) | int -%}
{%- set hours = ((time % 86400) / 3600) | int -%}
{{ hours }}:{{ minutes }}:{{ seconds }}
And it converts the sensor from seconds into Hours, Minutes and Seconds.
But I’d really like it to pad with leading zeros like a real timer.
So instead of:
1:5:7
It would be:
01:05:07
And when it was already 2 digits, there would be no zero padding:
01:45:23
I’ve been Googling for a few hours, but all I can find deals with date formats like now() and not a number that is just seconds.
Yeah, it also depends on the component whether the leading zeros are needed. Sometimes, it doesn’t need them sometimes it does. Sort of a pain. Whenever you need to format strings (or do anything complicated in templates), google ‘jinja2 xxx’ replacing xxx with whatever you want to do.
Its number of seconds since the OctoPrint starting printing.
I think timestamp_custom is expecting an Epoch time. I tried it and the results were all funky.
Thanks.
Ok. I must have done something stupid the first time I tried timestamp_custom.
It works just fine with the elapsed and remaining seconds from the OctoPrint component.
Thank everyone!
Ok, last update…maybe.
Ran into a problem where the elapsed time could be longer than 24 hours.
If I use the timestamp_custom function, then I need to include a day part (%j). But that starts on 1, not 0.
So an elapsed time = 0 is formatted as:
001:00:00:00
So I guess I’ll go back to petro’s solution for now and add a ‘set days’ to the value_template, or just use {03} for the hours format so I can handle up to 999 hours.
Thank again everyone!
%j would be the day of the year so yes it’ll never be 0, plus it would only go up to 365.
I’ve not found a formatting for days so you may indeed need to go back to your formula. Ah well at least I tried…
Sorry to awake an old thread, but just found it searching for a similar solution.
I believe a combination of “timestamp_custom” and “days” is the best of both worlds.
You probably dont need to zero-pad the number of days, and don’t need to worry about zero-padding the hours and minutes.
So this is what I ended up with:
{% set days = (seconds / 86400) | int %}
{% if days > 1 %}
{% set time_to_full = days ~ " days, " ~ seconds | timestamp_custom("%H:%M", false) %}
{% elif days > 0 %}
{% set time_to_full = days ~ " day, " ~ seconds | timestamp_custom("%H:%M", false) %}
{% else %}
{% set time_to_full = seconds | timestamp_custom("%H:%M", false) %}
{% endif %}
I ‘used’ this in a last changed sensor but it got hinky if it went beyond a year (it wraps round) (the sensor is not that old, I just believe in testing thoroughly)
I finally went with : -
{% set dif = as_timestamp(now()) - as_timestamp(states('input_datetime.id_heat_last_off')) %}
{% set ds = (dif // (24*60*60)) | int %}
{% set sdif = dif | timestamp_custom('%H:%M', false) %}
{{ ds ~ ' days ' ~ sdif }}
This shows how long ago it happened.
Typical output : 7 days 03:59
No doubt it could be spruced up a bit.
From memory %j defaults to 1 if it just happened, so you have to deduct one or something, can’t remember
That is right. “%j” starts at 1 as also mentioned earlier in the thread, so you would need something like "timestamp_custom("%j") | int - 1" which I think is less readable than what you and I are doing.
{% set days = (seconds / 86400) | int %}
{% if days > 1 %}
{% set time_to_full = days ~ " days, " ~ seconds | timestamp_custom("%H:%M", false) %}
{% elif days > 0 %}
{% set time_to_full = days ~ " day, " ~ seconds | timestamp_custom("%H:%M", false) %}
{% else %}
{% set time_to_full = seconds | timestamp_custom("%H:%M", false) %}
{% endif %}
which could be simplified to this without the concatenation
{% set days = (seconds / 86400) | int %}
{% if days > 1 %}
{% set time_to_full = seconds | timestamp_custom("%j days %H:%M", false) %}
{% elif days > 0 %}
{% set time_to_full = seconds | timestamp_custom("%j day %H:%M", false) %}
{% else %}
{% set time_to_full = seconds | timestamp_custom("%H:%M", false) %}
{% endif %}
And if you’re feeling saucy…
{% set days = (seconds / 86400) | int %}
{% set plural = 'days' if days > 1 else 'day' %}
{% set fmat = '%j {} %H:%M'.format(plural) if days > 0 else "%H:%M" %}
{% set time_to_full = seconds | timestamp_custom(fmat, false) %}
petro, putting all three in the templating tool, thus : -
{% set seconds = 24 * 60 * 60 %}
{% set days = (seconds / 86400) | int %}
{% if days > 1 %}
{% set time_to_full = days ~ " days, " ~ seconds | timestamp_custom("%H:%M", false) %}
{% elif days > 0 %}
{% set time_to_full = days ~ " day, " ~ seconds | timestamp_custom("%H:%M", false) %}
{% else %}
{% set time_to_full = seconds | timestamp_custom("%H:%M", false) %}
{% endif %}
{{ time_to_full }}
{% set days = (seconds / 86400) | int %}
{% if days > 1 %}
{% set time_to_full = seconds | timestamp_custom("%j days %H:%M", false) %}
{% elif days > 0 %}
{% set time_to_full = seconds | timestamp_custom("%j day %H:%M", false) %}
{% else %}
{% set time_to_full = seconds | timestamp_custom("%H:%M", false) %}
{% endif %}
{{ time_to_full }}
{% set days = (seconds / 86400) | int %}
{% set plural = 'days' if days > 1 else 'day' %}
{% set fmat = '%j {} %H:%M'.format(plural) if days > 0 else "%H:%M" %}
{% set time_to_full = seconds | timestamp_custom(fmat, false) %}
{{ time_to_full }}
Produces : -
1 day, 00:00
002 day 00:00
002 day 00:00
So I don’t think we are quite there yet. All three just use (to test) the 1 day (86400 seconds)
The best I can come up with is : -
{% set days = (secs / (24 * 60 * 60)) / int %}
{% set plural = ' days ' if days > 1 else ' day ' %}
{% set hrmn = secs | timestamp_custom('%H:%M', false) %}
{{ days ~ plural ~ hrmn if days > 0 else hrmn }}
1 day 00:00
Edit: I changed the above back to using int when ‘some’ of my sensors started displaying (say) : -
1.0 day 00:00
No, the point is “We Tried”
Always “butt in” if you have a different perspective
@Olen , @lolouk44
I used the // rather than int and(see post above) expanded the hrs-mins-secs (just to make it obvious and easier to read)
I know we are guilding the lilly here but any input welcome
Olen, not everyone wants the comma but it’s easy to put back in