Since_last_boot gone, now how to?

Simple solution:

Replace

{% set text = text.replace(', ', ' and ', -1) %}

with

{% set last_comma = text.rfind(',') %}
{% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}

Try the remainder math symbol ‘%’. I use the following :

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

  {% 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(',') %}
{% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}


  {{ text }}

Edit: Added parentheses to make it easier to read on second minutes/hours/days.

1 Like

Yes, not having a Python background I only recently discovered // and % and I have already changed to using them in this script.
However I somehow overlooked the fact that ordering the set statements your way simplifies everything.

Thanks!

Also, I added this to account for when the uptime is less than an hour (i.e. there is no comma),

      {% if last_comma != -1 %}
        {% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}
      {% endif %}

I’ve done a lot of time display functions for uptimes on esp8266’s in the arduino IDE. The less operations the better. That’s how I found the % operator.

[This template contains no entities that will trigger an update, so we add an entity_id: line with an entity that will force an update - here we’re using a date sensor to get a daily update:](https://www.home-assistant.io/components/sensor.template/)

so add a sensor:

- platform: time_date
    display_options:
      - 'time'

or create a automation that update custom mins:

automation:
  - alias: 'nonsmoker_update'
    trigger:
      - platform: time_pattern
        minutes: '/5'
    action:
      - service: homeassistant.update_entity
        entity_id: sensor.nonsmoker

HI,

don’t want to bump this, but I think you might be able to help me.

have a related question for calculating the time between to last_changed’s, please have a look here Why is this timestamp template an hour off?

the macro provided in this thread doesn’t help…

Could I please ask for your help? I’m not a Python programmer, I’ve just blatantly stolen @khan3962’s code earlier in this thread to make an uptime sensor. However, as you noted, it doesn’t quite work right when the uptime is less than an hour, as it shows:

RPi%20Uptime

I’m not quite sure how to add the three lines of code you have in your post. I tried this:

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

  {% set days = (up_time // (60 * 60 * 24)) | int %}
  {% set weeks = (days // 7) | int %}
  {% set hours = (up_time // (60 * 60)) | int %}
  {% set hours =  hours - days * 24 %}
  {% set minutes = (up_time // 60) | int %}
  {% set minutes = minutes - (days * 24 * 60) - (hours * 60) %}

  {% set days = (days | int) - (weeks * 7) %}

  {% macro phrase(value, name) %}
            {%- set value = value | int %}
            {%- 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(',') %}
  {% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}
  
  {% if last_comma != -1 %}
    {% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}
  {% endif %}

  {{ text }}

thinking maybe it would replace the erroneous text with the correct text, but I still get the same result. I would really appreciate if you’d help me out. Thanks in advance!

(I used to program in FORTRAN about 30 years ago. In the years since I’ve taught myself a lot, and I’m learning all kinds of stuff since starting Home Assistant. Unfortunately solving this one is beyond me at the moment. So many languages, so little time! :smile: )

Ha, ha! Nor am I and…

No one has ever asked me for help in Python before :slight_smile:
Seriously though, the only Python I know is from using HA although I did also start with Fortran 30 something years ago.

My Up time sensor looks like this which was made better by @khan3962’s hint about using ‘%’

      rpi_uptime:
        friendly_name: RPi Uptime
        entity_id: sensor.time
        value_template: >
          {% set up_time = as_timestamp(now()) - as_timestamp(states('sensor.last_boot')) %}

          {% 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 }}

image

Feel free to ask any questions bearing in mind what I said about not being a Python expert :stuck_out_tongue_winking_eye:

4 Likes

Thank you so much for your quick response and your help! I’ve put your code in my sensors.yaml and it works so much better…well, 20 minutes since my host reboot, anyway :smile:

You may not consider yourself a Python expert but you’re way ahead of me! And I also stole your mdi icon, it’s nicer than the boring clock I had before :slight_smile:

Thanks again!

1 Like

I’ve stolen these templates from you! Hope you don’t mind :wink:

Any idea why I might be seeing the following results? I’m not familiar with a couple of things used here so I can’t really figure out what’s going on. (specifically macros in jinja, phrase(), and ‘{} {} {}’). Looks like I’ve got some googlin’ to do but was curious if your values are correct because this was a direct copy/paste.

As far as I can tell it’s interpreting the value here as days instead of hours maybe?

In this screenshot sensor.uptime is showing an accurate value. sensor.rpi_uptime (the stolen template) is showing a very incorrect value.

I think 7.24 is days in which case 1 week 5 hrs 45 minutes is likely 7.24 days and both are correct and identical.

The 7.24 was definitely hours. I just rebooted a few minutes ago.

Hassio Uptime is sensor.uptime and HA Uptime is sensor.ha_uptime

image

.14 days * 24 hours = 3.36 hours. 0.36 hour = 21 minutes.
You are definitely wrong. It is days.

@DavidFW1960 Like I said originally, I so believe the ha_uptime is interpreting sensor.uptime as days. Anyone can see that mathematically. I didn’t know why.

sensor.uptime was the correct value ha_uptime was incorrect I’m pretty sure I know how long ago I rebooted my system considering it was only 15 minutes ago.

So to answer my own question. I have the uptime sensor set to report in hours. I would bet my bottom dollar @klogg has his set up for days (the default) and that if I change mine to match all will be good with the world.

  - platform: uptime
    unit_of_measurement: hours  

Thank you for your input though.

Edit: That sounded snarkier than I meant. I do appreciate you looking at it.

Success.

image

Again, thank you for looking at it. Cranky tonight. Need coffee.

Can you share the completed code for both (hassio uptime and ha uptime)?

1 Like

i’d like to see it too please

Here is what I ended up using:

sensor:
    - platform: systemmonitor
    resources:
        - type: last_boot
        - type: disk_use_percent
        arg: /
        - type: memory_use_percent
        - type: processor_use

    # System Up Time
    - platform: uptime    

    - platform: template
    sensors:
        ha_uptime:
            friendly_name: HA Uptime
            value_template: >
            {% if states('sensor.uptime') == '0.0' %} 
                Just restarted...
            {% else %}
                {% macro phrase(value, name) %}
                {%- set value = value | int %}
                {%- set end = 's' if value > 1 else '' %}
                {{- '{} {}{}'.format(value, name, end) if value | int > 0 else '' }}
                {%- endmacro %}
                
                {% set weeks = (states('sensor.uptime') | int / 7) | int %}
                {% set days = (states('sensor.uptime') | int) - (weeks * 7) %}
                {% set hours = (states('sensor.uptime') | float - states('sensor.uptime') | int) * 24 %}
                {% set minutes = (hours - hours | int) * 60 %}

                {{ [ phrase(weeks, 'week'), phrase(days, 'day'), phrase(hours, 'hr'), phrase(minutes, 'min') ] | select('!=','') | list | join(', ') }}
            {% endif %}


        # NUC last boot date and time
        last_boot_date_time:
            friendly_name: Last Boot
            value_template: >
            {% set date = as_timestamp(states('sensor.last_boot')) | timestamp_custom('%d') %}
            {% set date = '{:01}'.format(date | int) %}
            {% if date in ('1', '21', '31') %}
                {% set date = date ~ 'st' %}
            {% elif date in ('2', '22') %}
                {% set date = date ~ 'nd' %}
            {% elif date in ('3', '23') %}
                {% set date = date ~ 'rd' %}
            {% else %}
                {% set date = date ~ 'th' %}
            {% endif %}

            {{ as_timestamp(states('sensor.last_boot')) | timestamp_custom('%H:%M on %a') }} {{ date }} {{ as_timestamp(states('sensor.last_boot')) | timestamp_custom('%b %Y') }}

        nuc_uptime:
            friendly_name: NUC Uptime
            entity_id: sensor.time
            value_template: >
            {% set up_time = as_timestamp(now()) - as_timestamp(states('sensor.last_boot')) %}

            {% 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 }}
1 Like

Thank you @JesseWebDotCom, works great :+1:

Hi

Have any of you rebooted as I got this today when testing ?

Also does the Hassio up time change from 0.1 days to weeks, hours and minutes eventually ?

image

Thanks Martyn