Last-changed value of a sensor

I would like to display the last changed value of a device as an extra sensor.
My device has some sensors included (temperatur, humidity, pressur, battery level) and those do not update simultaniously. It seems, that the zigbee connection (with zigbee2mqtt) is not 100% stable, so I would like to check, when the sensor has sended the last updated.

I can grab the value, but the format with a value template is the absolute time.

  • How would I format the value to be a relative one like (“Updated 2 minutes ago”) when using the secondary value?
    That’s my value template:
    value_template: "{{ states.sensor.hygrothermo_1_temperature.last_changed }}"

  • Second question:
    How would I use the minimum last changed of all three sensor of my device?
    Min(last_changed(temp, humidty, batterie)

  • Third question - maybe on templates, too:
    I have to correct the temperature value by adding 0.5. After a reboot, I see 0.5 degree, till the sensor did send a new value. Is there an easy way to display NaN instead of 0.5, until I got the first real sensor value?

add device_class: timestamp to your configuration at the same indentation as value_template. When displayed in the UI, it will show “updated x min ago”. It will not display correctly in custom cards that don’t properly translate states. So as long as you use well made custom cards and the built in Lovelace cards, you should be good to go.

This would require a template sensor and some jinja magic

sensor:
  - platform: template
    sensors:
      my_new_sensor:
        value_template: >
          {% set values = [
            as_timestamp(states.sensor.sensor1.last_changed),
            as_timestamp(states.sensor.sensor2.last_changed),
            as_timestamp(states.sensor.sensor3.last_changed), ] %}
          {{ min(values) }}
        device_class: timestamp

Post that template sensor

1 Like

Thanks, works perfect. :+1:

That’s what I entered and I get an Invalid date.

  - platform: template
    sensors:
      hygrothermo_1_lastchanged:
        value_template: >
          {% set values = [
            as_timestamp(states.sensor.hygrothermo_1_temperature.last_changed),
            as_timestamp(states.sensor.hygrothermo_1_humidity.last_changed),
            as_timestamp(states.sensor.hygrothermo_1_battery.last_changed), ] %}
          {{ min(values) }}
        device_class: timestamp

Never posted a sensor. This will take some time to figure out the syntax.

You get invalid date? what’s the state though?

I’m not sure, what you are expecting me to answer…
From logbook:
Hygrothermo 1 Last Changed changed to 2019-07-02 20:54:00.707552+00:00

From States view:

Not sure if it makes any difference but there’s an unwanted extra comma in both the example and what you have entered after the third sensor.

Changed to:

  - platform: template
    sensors:
      hygrothermo_1_lastchanged:
        value_template: >
          {% set values = [
            as_timestamp(states.sensor.hygrothermo_1_temperature.last_changed),
            as_timestamp(states.sensor.hygrothermo_1_humidity.last_changed),
            as_timestamp(states.sensor.hygrothermo_1_battery.last_changed) ] %}
          {{ min(values) }}
        device_class: timestamp

Same result:
image
Hygrothermo 1 Last Changed changed to 2019-07-02 20:54:00.707552+00:00

ok, min is not in jinja so try this

  - platform: template
    sensors:
      hygrothermo_1_lastchanged:
        value_template: >
          {% set values = [
            as_timestamp(states.sensor.hygrothermo_1_temperature.last_changed),
            as_timestamp(states.sensor.hygrothermo_1_humidity.last_changed),
            as_timestamp(states.sensor.hygrothermo_1_battery.last_changed), ] %}
          {{ values | sort | first }}
        device_class: timestamp
1 Like

Good spot (sort of). Min should exist but the correct command would be

     {{ values | min }}

yah, that looks like it would work. the min() func from python isn’t in jinja but the min filter is.

still unkown… with both options…


  - platform: template
    sensors:
      hygrothermo_1_lastchanged:
        value_template: >
          {% set values = [
            as_timestamp(states.sensor.hygrothermo_1_temperature.last_changed),
            as_timestamp(states.sensor.hygrothermo_1_humidity.last_changed),
            as_timestamp(states.sensor.hygrothermo_1_battery.last_changed), ] %}
          {{ values | min }}
        device_class: timestamp

image

try adding | timestamp_local to the end. It may require ()

  - platform: template
    sensors:
      hygrothermo_1_lastchanged:
        value_template: >
          {% set values = [
            states.sensor.hygrothermo_1_temperature.last_changed,
            states.sensor.hygrothermo_1_humidity.last_changed,
            states.sensor.hygrothermo_1_battery.last_changed, ] %}
          {{ values | min }}
        device_class: timestamp

Tested in Template Editor:

When implemented as a Template Sensor:

Screenshot%20from%202019-07-05%2008-25-59

as long as it’s a date time object. as_timestamp converts it to a float and will always work even if last_changed is the date time as a string. I.E. through restart.

Nuts! I keep forgetting that (even when I have no reason to forget it). Hopefully pnbruckner’s correction is included in 0.96 to make this bug disappear into the dustbin of history.

Hold on … that’s for last_triggered whereas this is last_changed. Is this also affected by the deserialization bug?


EDIT
I don’t think the deserialization bug affects last_changed. The example I posted above was produced on my test system which I just turned on this morning. The last_changed for all three entities is a datetime object so the restoration feature performed the deserialization correctly.

Yah, it’s annoying. I’ll be happy when we can just deal with datetimes everywhere. So we never have to convert

Yep, it’s safe to assume that a string will go in there without tests.

Hhm, seems not so easy to figure out, when a sensor with multiple values has last submitted his value…

From my point of view, this should be easier than creating a complicate template for each device

if this is a single device, chances are that they all update at the same time. You are trying to get last changed. It’s a bit different because last_changed tells you the last value change. I don’t even know why you’d want last_changed for 3 different sensor values. To me, that value would be pointless.

Maybe sensor is missleading.
I would like to know the last value submitted of a device having 3, 5 or six sensors included.
In my case the sensors are Xiaomi weather sensors, one via Bluetooth and the others via zigbee2mqtt.


The three devices on the right side are connected via the same zigbee2mqtt