Last_updated State and last-changed in Lovelace

My sensor appears to not have a last_updated attribute:
And yet Lovelace can show it’s last-changed

      - entity: binary_sensor.pir_hall
        secondary_info: last-changed



Ok, so this is where things get funky. You should familiarize yourself with home assistant state objects. This is what home assistant passes around when doing pretty much anything. These state objects contain 8 or so properties. Do not get these properties confused with the devices attributes.

These properties are:

Field Description
state.state String representation of the current state of the entity. Example off.
state.entity_id Entity ID. Format: .<object_id>. Example:
state.domain Domain of the entity. Example: light.
state.object_id Object ID of entity. Example: kitchen. Name of the entity. Based on friendly_name attribute with fall back to object ID. Example: Kitchen Ceiling.
state.last_updated Time the state was written to the state machine. Note that writing the exact same state including attributes will not result in this field being updated. Example: 2017-10-28 08:13:36.715874+00:00.
state.last_changed Time the state changed. This is not updated when there are only updated attributes. Example: 2017-10-28 08:13:36.715874+00:00.
state.attributes A dictionary with extra attributes related to the current state.

So whenever you use this function:

state_attr(entity_id, ‘attribute’), you are only getting items inside the state.attributes. When you look at the states page, you will only see things that are inside the state.attributes section. But ALL state objects in home assistant have the fields/properties that are listed above. And they are OUTSIDE the attributes field/property.

So how do you access them? Well the only way to access them is through the state object itself. There is no method that will get you these items.

{{ states.domain.object_id.<field> }}

So if you have a light, and it’s entity_id is light.living_room, access any of the properties outside the attributes (or state), would be:

{{ states.light.living_room.entity_id }} # for the entity_id 'light.living_room'
{{ states.light.living_room.domain }} # for the domain 'light'
{{ states.light.living_room.object_id }} # for the object_id 'living_room'
{{ }} # for the friendly_name 'Living Room'
{{ states.light.living_room.last_updated }} # for the datetime object in UTC when it was last updated
{{ states.light.living_room.last_changed }} # for the datetime object in UTC when the state last changed

So you can kinda start to see how where we can access the state and attributes using that method too. You’ve probably seen this many times before without realizing it.

{{ states.light.living_room.state }} # for the state
{{ }} # for the attribute 'xxx' if it exists

An excellent reply… Thank you.

Yes I have!
And I have always actively avoided that format because it returns an error when it doesn’t exist but now I can see a use for it.

There’s ways you can get around that too, just takes more code than the methods.

{% if states.light.living_room is defined %}


Im new to HA, is there any way to show the last update subtitle if in my config, I use yaml mode?

  mode: yaml

Some cards allow you to display it via the an attribute. You gotta look through the cards configuration options and see if last-updated is an option for any of the fields. For example, the entities card has this ability.

1 Like

Thank you for your reply.

That secondary_info is available in yaml mode? I tested in customized.yaml and it seems doesnt work.

My config is here:

configuration.yaml is the main file, it loads groups.yaml is the one I have for the UI.
it reads the sensors state from customize.yaml

I have no idea where to put secondary_info in.

it needs to be placed in the configuration for the card. This can be done in yaml mode or not. It goes in ui-lovelace.yaml.

Are you familiar with how the docs work? They essentially tell you where to place the information.

Yes I do, now I have to remove my groups.yaml, then creating new ui-lovelace.yaml to use this

Groups has nothing to do with lovelace, nor do they do anything with the interface. The used to do things with the interface back in 2018. Since then, they’ve been completely separate.

1 Like

It seems that there is a bug when parsing sensor name:
Test with template in Developer Tool
{{ states.binary_sensor.0x00158d000273bbe4_contact.last_updated }}

Got this:

Error rendering template: TemplateSyntaxError: expected token 'end of print statement', got 'x00158d000273bbe4_contact'

Right, now I am converting groups.yaml, customize.yaml into new ui-lovelace.yaml and get rid of those old style.

Thats because your object_id starts with a number, which is a no-no. To access it…

{{ states.binary_sensor['0x00158d000273bbe4_contact'].last_updated }}

Thank you so much!

I got Unknown error when trying to convert timezone,

         {{ as_timestamp( states.binary_sensor['0x00158d000273bbe4_contact'].last_updated + '+06:00') | timestamp_custom('%a %b %-d %-I:%M%p')}}

Unknown error rendering template


This printed a UTC date time, but converting like above having error.

last updated is a datetime object. You can’t add a string to it.

{{ as_timestamp( states.binary_sensor['0x00158d000273bbe4_contact'].last_updated) | timestamp_custom('%a %b %-d %-I:%M%p', False)}}
1 Like


I’m looking for to show the last changed of the sensor, but the “timestamp_custom” doesn’t work. This is my conf :

{{ states.binary_sensor.porte_entree.last_changed | timestamp_custom('%H %M',False) }}

The result :

2019-11-20 08:57:18.122862+00:00

The custom format isn’t apply (I just want 08:57), and, the local time isn’t correct, because I need to add 1 hour in more ( either 2019-11-20 09:57:18.122862+00:00 and when I try with the timestamp_local the time is incorrect ).

Do you have some idea why ?

I found a solution, I’m not sure is the good solution :

{{ as_timestamp(states.binary_sensor.porte_entree.last_changed) | timestamp_custom('%H %M',True)  }}

It is, if you look at the template I posted 14 days ago, you’ll notice that it uses as_timestamp()