Last_updated State and last-changed in Lovelace

Yes, of course I did, that’s why I said it was a great thread, and I understood it too :wink:
There’s only the state and 3 attributes so I’ll put them all in a Lovelace dashboard and take some screen grabs to compare side-by-side.

I must be missing something, or not fully understanding then Petro.
The one that says “Now” was taken 15mins after the other one and since nothing has changed it should say 41mins (26+15).
The attributes are the three entries at the top ( “latestValue”, “parameterStatusEN”, “latestTime”) and the state (“titleEn”) is “Garnswllt raingauge”, shown below the graph.
(‘1 updated’ is the friendly name for “sensor.nrw1”)

The Rest sensor is defined as:

- platform: rest
  name: 'nrw1'
  resource: https://api.naturalresources.wales/rivers-and-seas/v1/api/StationData/byLocation?distance=3500&lat=51.770371&lon=-4.0004888
  headers:
    Ocp-Apim-Subscription-Key: !secret nrw_key
  value_template: '{{ value_json[0].titleEn }}'
  json_attributes_path: "$[0].parameters[0]" 
  json_attributes:
    - "latestValue"
    - "parameterStatusEN"
    - "latestTime"
  scan_interval: 1800

BTW I have a sensor to extract the rainfall for use in Garafana, could this be significant, although it isn’t really involved in sensor.nrw1?

    garnswllt_rainfall:
      friendly_name: "Last hours rainfall"
      unit_of_measurement: 'mm'
      value_template: "{{ state_attr('sensor.nrw1', 'latestValue') }}"

Don’t waste any time on this, I can probably get around it by using {{ state_attr(‘sensor.nrw1’, ‘latestTime’) }} and seeing if I can get a timestamp out of it.
Many thanks, Bob.

Screenshot 2022-02-06 14.32.54

Screenshot 2022-02-06 14.33.18

Hi
I have created the sensor in configuration.yaml. but I am unable to show the data in Lovelace

Could you kindly provide me any resources that could help

Thanks

THIS… is a fantastic explanation. Thanks Petro.

1 Like

@petro
Can you help me understand a condition used in my automation. I can’t remember where I copied it from, but the intent was to stop the automation from looping or repeating after completion… If I recall, it is a do not repeat until 10 seconds have passed. I have tried evaluating this in the developer tools to understand and evaluate but I could not get the format correct.

condition: 
  - condition: template # Inhibit retrigger loops
    value_template: "{{ ( as_timestamp(now()) - as_timestamp(state_attr('automation.basement_lights_timeout', 'last_triggered')) |int(0) ) > 10 }}"      

that looks fine but can be simplified
"{{ (now() - state_attr('automation.basement_lights_timeout', 'last_triggered')).seconds > 10 }}"

2 Likes

awesome writeup!

Hi @petro

I’m trying to implement a notification system that should warn me when my wind sensor has not reported an update for a certain period of time. My use case is I want to get notified about this happening in order to manually evaluate whether my awning needs to be closed manually, should the wind sensor had dropped out of my network.

Thanks to the awesome writeup above, I came up with this syntax:

 {{ as_timestamp( now()) - as_timestamp( states.sensor.os_wgr800_wind_gust.last_updated)}}

at successfully calculates the difference between “now” and the last updated timestamp. And this looks promising.

I’m testing this syntax in the developer section of HA and it gives a numeric result, but the frontend will only update the numeric result when the last updated attribute is updated.

Wind sensor last update value {{ states.sensor.os_wgr800_wind_gust.last_updated }}.

Wind sensor last update {{ as_timestamp( states.sensor.os_wgr800_wind_gust.last_updated) | timestamp_custom('%a %b %-d %-I:%M%p', False)}}

Wind sensor last update {{ as_timestamp( states.sensor.os_wgr800_wind_gust.last_updated) | timestamp_custom('%H %M %S', False)}}

Time difference between now () last updated timestamp {{ as_timestamp( now()) - as_timestamp( states.sensor.os_wgr800_wind_gust.last_updated)}}

Captura de pantalla 2022-08-03 a les 9.20.49

I’m concerned with when the condition will be evaluated. I guess there is a difference between me evaluating the condition on the dev section and when the condition is written in code and processed by HA core.

Could you kindly give me a hand with this?

Thanks and congratulations again for this nice thread!

How I can make template how much time is pass when switch last triggered?

I tried like this but not working correctly?

{% set value = as_timestamp( now()) - as_timestamp(states.switch.livingroom_relay_heating_dogs_bed.last_updated) %}
{% set time = value | int %}
{% set minutes = ((time % 360000) / 60 ) | int %}
{% set hours = ((time % 8640000) / 3600) | int %}
{% set days = (time / 86400) | int %}

{%- if time < 60 -%}
  Less than a minute
{%- else -%}
  {%- if days > 0 -%}
    {{ days }}d
  {%- endif -%}
  {%- if hours > 0 -%}
    {%- if days > 0 -%}
      {{ ' ' }}
    {%- endif -%}
    {{ hours }}h
  {%- endif -%}
  {%- if minutes > 0 -%}
    {%- if days > 0 or hours > 0 -%}
      {{ ' ' }}
    {%- endif -%}
    {{ minutes }}m
  {%- endif -%}
{%- endif -%}

Where and how do you want to use this?

One solution is to make a template sensor using the duration device class. Just make the state value the number of seconds between now and then. HA will display it smartly. Also look at the relative_time template function (in the HA template docs; the link is in your template editor).

I find solution, but still not perfect:)

Can I somehave make this part for days shorter? I need shorter code for days and months.

{%- elif time > 86400 -%}
 1 day ago
{%- elif time > 172800 -%}
 2 day ago
{%- elif time > 259200 -%}
 3 day ago

template:

{% set value = as_timestamp( now()) - as_timestamp(states.switch.livingroom_relay_heating_dogs_bed.last_updated) %}
{% set time = value | int %}
{%- if time < 60 -%}
  Less than a minute
{%- elif time > 60 -%}
{{ time  | timestamp_custom('%Mm ago', false) }}
{%- elif time > 3600 -%}
{{ time  | timestamp_custom('%Hh ago', false) }}
{%- elif time > 86400 -%}
 1 day ago
{%- elif time > 172800 -%}
 2 day ago
{%- elif time > 259200 -%}
 3 day ago
{%- endif -%}

I’d like to urge you to consider the feedback I’ve given before and understand whether the built-in mechanisms can do the job for you. Assessing your current solution, I would suggest it’s probably better for you to stick with bundled mechanisms, unless you have a very good reason not to (but also, I don’t want to limit your learning).

Anyway, since you’re insistent, here’s are some very old template sensors of mine that I still use and never adapted (I can totally just use relative_time, but I’m rather spending my time on building other things):

- platform: template
  sensors:
    security_camera_last_clip:
      device_class: timestamp
      value_template: "{{ states('input_datetime.security_camera_last_clip') | as_datetime | as_local }}"
    security_camera_last_clip_relative:
      value_template: >
        {%- set _ = states('sensor.time') %}
        {%- set t = state_attr('input_datetime.security_camera_last_clip', 'timestamp') %}
        {%- if t != None %}
          {%- set n = now().timestamp() %}
          {%- set d = n - t %}
          {%- set midnight_today = as_timestamp(strptime(now().date() | string, "%Y-%m-%d")) %}
          {%- set midnight_yesterday = midnight_today - 86400 %}
          {%- set midnight_week_ago = midnight_today - 604800 %}
          {%- if d < 60 %}
            {{ d | int }} seconds ago
          {%- elif d >= 60 and d < 120 %}
            1 minute ago
          {%- elif d < 3600 %}
            {{ (d // 60) | int }} minutes ago
          {%- elif d < n - midnight_today %}
            Today at {{ t | timestamp_custom('%H:%M') }}
          {%- elif d < n - midnight_yesterday %}
            Yesterday at {{ t | timestamp_custom('%H:%M') }}
          {%- elif d < n - midnight_week_ago %}
            {{ t | timestamp_custom('%A at %H:%M') }}
          {%- else %}
            {{ t | timestamp_custom('%Y-%m-%d %H:%M:%S') }}
          {%- endif %}
        {% else %}
          unknown
        {% endif %}

The credit should mostly go to someone else, but I don’t have the link to the post I’ve adapted this from anymore.

1 Like

This is such a valuable method of enumerating attributes of an entity seemingly documented nowhere!

State objects are documented.

1 Like

State objects are documented.

Sorry, now I see and understand.

So how would I fill an array with the attributes in a loop for multiple entities in order to e.g. formulate a notification message with all attributes and their current value?

Non working example:

for_each {{ room_list }}
  sequence:
    - variables:
        attribs_room: "{{ states.climate.room_climate_ ~repeat.item~ .attributes }}"
...

If anybody’s worried about the relative_time output not being localized, a quick work-around is to add some jinja filters, adapt to your language:

  {{ "Mudado há " ~ relative_time(states.input_boolean.ring_app.last_updated) 
       | replace("second", "segundo") 
       | replace("minute", "minuto") 
       | replace("hour", "hora") 
       | replace("day", "dia") 
  }}

note that the s for the plurals works well in my language (Portuguese) but won’t work well in others, so you’ll have to add separate replace commands for singulars and plurals. For example: in Italian, the plural of giorno is not giornos, it’s giorni.

or use https://github.com/Petro31/easy-time-jinja or https://github.com/TheFes/relative-time-plus.
If your language is not added, you can submit an issue or PR to have them added.

1 Like

I would need some guidance here: let’s say I have a sensor that updates every minute, but most of the time returns the exact same value. Will the last_changed property be updated every time the sensor updates, or only when the value of the sensor changes ?
Thank you :slight_smile:

Only when the main stage changes value.

1 Like