Uptime in days hours and minutes

For minutes I think that should be

      value_template: >
        {{ (as_timestamp(now()) - as_timestamp(states('sensor.ha_uptime_moment'))) / 60 }}
2 Likes

Yes. 3600 is for hours

finally how can I get the data templated? can someone paste the sensor code?
thanks

Can you psot what your sensor configuration looks like. I am a complete puttz when it comes to coding but I am trying to understand. I appreciate your assistance very much.
Thankyou

Below is the contents of my uptime_sensor.yaml. It’s included in the configuration.yaml.

- platform: uptime
  name: Uptime

- platform: template
  sensors:
    ha_uptime:
      friendly_name: "Home Assistant uptime"
      value_template: >-
        {% set up_time =  as_timestamp(now()) - as_timestamp(states('sensor.uptime')) %}

        {% if up_time == 0 %}
          Just restarted...
        {% else %}
          {% set minutes = (up_time // 60) | int %}
          {% set hours = (minutes // 60) %}
          {% set days = (hours // 24) %}
          {% set weeks = (days // 7) %}

          {% 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') ] | select('!=','') | list | join(', ') %}
          {% set last_comma = text.rfind(',') %}
          {% if last_comma != -1 %}
            {% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}
          {% endif %}

        {{ text }}

        {% endif %}
4 Likes

if you’re interested here is a streamlined version of that. Makes it easy to add or remove any unwanted values:

2 Likes

Great work to get the uptime working again but as for the Automations this code is difficult to work with, at least for me. I need numeric states or at least integers but this is a string attribute.

This is what I’ve concluded works for me wanting to measure the uptime in minutes and evaluate a numeric state on the same:

  #HASS uptime
  - platform: uptime
    name: Uptime

  - platform: template
    sensors:
      uptimev2:
        friendly_name: Uptimev2
        value_template: >
          {{ (as_timestamp(now()) - as_timestamp(states('sensor.uptime'))) // 60|int }}

And then I evaluate the uptime based on the uptimev2 numeric state, for example between 2 and 3 minutes:

I need to ask …
This code works for you? In my case the sensor is not available du to an error of the calculation.
When I put this {{ (as_timestamp(now()) - as_timestamp(states(‘sensor.uptime’))) // 60|int }} to the dev tools I get the following error:
TypeError: unsupported operand type(s) for -: ‘float’ and ‘NoneType’

Yes, it works. I had a look in my config file and I’ve apparently added another type of entity as well:

sensor:

  #HASS uptime
  - platform: uptime
    name: Uptime

  - platform: template
    sensors:
      uptimev2:
        friendly_name: Uptimev2
        value_template: >
          {{ (as_timestamp(now()) - as_timestamp(states('sensor.uptime'))) // 60|int }}

  - platform: template
    sensors:
     home_assistant_uptime:
        friendly_name: Home Assistant Uptime
        value_template: >- 
          {% set up_time = as_timestamp(now())-as_timestamp(states('sensor.uptime')) %}
          {% set minutes = (up_time // 60)|int %}
          {% set hours = minutes // 60 %}
          {% set days = hours // 24 %}
          {% 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(days,'day'),phrase(hours,'hour'),
                         phrase(minutes,'min')]
                         |select('!=','')|list|join(', ') %}
          {% set last_comma = text.rfind(',') %}
          {% if last_comma != -1 %}
            {% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}
          {% endif %}
          {{text}}

Seems there are others with similiar errors and recommended checking the template editor for debugging but maybe that is what you’ve already tried?:

1 Like

Yep. Other errors …
It was just a typo. What about AI? :wink:

Hi, I have a question:

Is this still the correct way to get the uptime sensor?

sensor:
  - platform: uptime
    name: Time Online

Or should it follow the new template format?

template:
  - sensor:
      - name: "Server uptime"
        state: ???

Thank you.

did you read Uptime - Home Assistant ?

1 Like

Yes, but isn’t it a template sensor? I feel that code follows the legacy sensor configuration format

no, where did you get the idea this is a template sensor? some of the others above are, but this is a core integration

1 Like

I see, thank you.

Here is how I would do it:

{{ states('sensor.ha_uptime') }}
{% set total_seconds = as_timestamp(utcnow())-as_timestamp(states('sensor.ha_uptime')) %}
{{ total_seconds }}
{% set days = (total_seconds / 86400) | int %}
{{ days }}
{% set hours = ((total_seconds % 86400) / 3600 ) | int %}
{{ hours }}
{% set minutes = ((total_seconds % 3600) / 60 ) | int %}
{{ minutes }}
{% set seconds = (total_seconds % 60) | int %}
{{ seconds }}
{{ [days, hours, minutes, seconds]|join(':') }}

You can cut & paste this in to developer templates and you should get something like this:

if you want a nicer state than the uptime sensor, why not use the template sensor posted above somewhere:

template:

  - sensor:

      - unique_id: ha_uptime_phrase
        name: Ha uptime phrase
        icon: mdi:history
        state: >-
          {%- set up = now().timestamp()-as_timestamp(states('sensor.uptime')) %}

          {%- macro phrase(name,divisor,mod=None) %}
            {%- set value = ((up//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}}

That output is basically identical to a timedelta as a string.

{{ utcnow() - states('sensor.ha_uptime') | as_datetime | default(utcnow()) }}

This would not give the OP the days as requested.

Am I missing something?

You overwrote total_seconds with a time from 2 days ago, so your as_timestamp calc has a difference of 2 days. OP is asking for days hours and minutes, not seconds. So in that regard, they are both wrong. Either way, this is the real difference (without incorrectly overwriting the difference)