Uptime No Longer Working

Since the latest update and the depreciation of “unit_of_measurement” I seem to be being stupid and cannot get uptime to work.

I would like a simple counter for uptime to display on top of a picture elements card, ideally having days and hours but would also like to be able to have others if needed so another I would use would be days, hours and minutes

Anyone have these and able to share working code tested on latest home assistant?

If you only want to display it in the front end this still works you just have to adjust your configuration to use only the options in the docs.

sensor:
  - platform: uptime
    name: Time Online

If you want something that displays properly everywhere in the UI…

sensor:
- platform: uptime

- platform: template
  sensors:
    homeassistant_uptime:
      friendly_name:  HomeAssistant Uptime
      value_template: >
        {# use now() to update every minute #}
        {% set t = now() %}
        {{ relative_time(strptime(states('sensor.uptime'), '%Y-%m-%dT%H:%M:%S.%f%z')) }}
      availability_template: >
        {{ strptime(states('sensor.uptime'), '%Y-%m-%dT%H:%M:%S.%f%z') is not string }}

It will display:

5 minutes

if its been up for 5 minutes.

1 Like

or

{{relative_time(states.sensor.uptime.last_changed)}}

?
(though neither of these auto-update in the template editor anymore since 2020.X, relative_time() doesn’t trigger an update, which feels like a bug, and I have reported it as that…)

I have one that uses now, but I can’t copy and paste it from my phone :see_no_evil:

I should be at a laptop in the next couple of hours, I’ll post it then.

this works alright if you want a ‘phrase’:

      ha_uptime_phrase:
        friendly_name: Ha uptime phrase
        value_template: >-
          {% set up_time = as_timestamp(now())-as_timestamp(states('sensor.uptime')) %}
          {% set seconds = up_time|int %}
          {% set minutes = (up_time // 60)|int %}
          {% set hours = minutes // 60 %}
          {% set days = hours // 24 %}
          {% set weeks = days // 7 %}

          {% set seconds = seconds % 60 %}
          {% set minutes = minutes % 60 %}
          {% set hours =  hours % 24 %}
          {% set days = days % 7 %}

          {% macro phrase(value,name) %}
            {%- set value = value %}
            {%- set end = 's' if value > 1 else '' %}
            {{- '{} {}{}'.format(value,name,end) if value|int > 0 else '' }}
          {%- endmacro %}

          {% set text = [phrase(weeks,'week'),phrase(days,'day'),phrase(hours,'hr'),
                         phrase(minutes,'min'),phrase(seconds,'sec')]
                         |select('!=','')|list|join(', ') %}
          {% set last_comma = text.rfind(',') %}
          {% if last_comma != -1 %}
            {% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}
          {% endif %}

          {{text}}

That might probably will work, it depends on if last_updated is always a datetime object

relative time already does that. all you’d have to add is ‘ago’ after the template:

{{ relative_time(states.sensor.uptime.last_changed) }} ago

But you’d REALLY need to implement the availability_template to ensure it’s ‘unavailable’ when the calculation fails (So that it doesn’t read unavailable ago)

yeah, I only posted the snippet for the longer template you posted, not as a full replacement.

About the

what do you mean by that? relative_time() only mentions the biggest of the available units?

relative_time converts datetime object to its human-friendly “age” string. The age can be in second, minute, hour, day, month or year (but only the biggest unit is considered, e.g., if it’s 2 days and 3 hours, “2 days” will be returned).

so if you need the phrase, relative_time() isnt of much help

If you’re referring to a phrase as 10 hours, 3 minutes, then yes, relative_time does not do that. It would only return 10 hours.

yeah, thought that was was the OP liked to see

my phrase template (which was heavily copied from a couple of fellows here, not taking any credit) also drops in weeks and seconds :wink:

pretty sure I built it for you a few years back :wink:

haha, probably!

you had a big hand in this too, but it mysteriously stopped calculating passed and remaining days correctly…

FYI, here’s a streamlined version

          {%- set up_time = as_timestamp(now())-as_timestamp(states('sensor.uptime')) %}

          {%- macro phrase(name, divisor, mod=None) %}
            {%- set value = ((up_time // divisor) % (mod if mod else divisor)) | int %}
            {%- set end = 's' if value > 1 else '' %}
            {{- '{} {}{}'.format(value, name, end) if value | int > 0 else '' }}
          {%- endmacro %}
          
          {%- set values = [ 
                     phrase('week', 60*60*24*7), 
                     phrase('day', 60*60*24, 7), 
                     phrase('hour', 60*60, 24),
                     phrase('min', 60), 
                     phrase('sec', 1, 60) 
                 ] | select('!=','') | list %}
                        
          {{ values[:-1] | join(', ') ~ ' and ' ~ values[-1] if values | length > 1 else values | first }}

For other languages or variations to this template, see here:

7 Likes

nice!!
and it works equally well with the last_boot sensor.
magic.

It’ll work with any time difference in seconds.

I have not updated yet, but use uptime in many of my automations as a condition to keep them from running during restart. To be honest I added these conditions years ago, and it’s just worked so I have not looked for better ways to do it. I dont care much about displaying the uptime, just want to keep automations from triggering during the first X minutes after a restart.

What is the recommended way to do that these days? Most of my automations with an uptime trigger are set to 1-2 minutes, and a few are set longer for devices that take a little longer to report status sometimes.

So I have a “HA not restarted recently sensor” which was based off minutes of uptime… I just want to show the minutes similar to this:

but without the word minutes… removing “relative_time” just breaks the whole thing and I’m lost with all these time formatting things.

This sensor is used as a condition to keep automations from triggering after a restart…

- platform: template
  sensors:
    home_assistant_not_restarted_recently:
      value_template: "{{ states('sensor.ha_process_uptime_sensor')| float > 6 }}"

And with the old uptime sensor the state was just a numeric value… I’m not sure if it’d be easier to redo the whole restarted recently sensor, or just make another sensor that provides just the numeric number of minutes like it was before.

{{ ( as_timestamp(now()) - as_timestamp(states('sensor.uptime'))) // 60 }}

EDIT: Had math reversed.

1 Like

My automations used to be:

    - condition: numeric_state
      entity_id: sensor.uptime
      above: .1

and is now:

    - condition: template
      value_template: "{{ (((as_timestamp(now()) - as_timestamp(states('sensor.uptime'))) % 3600) / 60) | int > 5 }}"

This new condition is set for 5 minutes.

1 Like