I'm Stumped, Last Changed Sensor

I have a PIR sensor I intend on placing in a Cat Kennel… I’d like to be able to see the last time this sensor triggered to on/detected so I can get a good idea on if the cats in the kennel or not.

I’m feeling really stupid right now, i cannot figure out how best to do this. It seems pretty simple comparing to some of my other config.

Any pointers?

I use this in my automations

      - condition: template
        value_template: "{{ (as_timestamp(now())-as_timestamp(states.binary_sensor.my_presence.last_changed)) < 60 }}"

So last changed less than 60 seconds ago

1 Like

I have this that works, instead of last_changed, I have last_updated:

  - platform: template
    value_template: '{% if (as_timestamp(now())-as_timestamp(states.sensor.kitchen_motion.last_updated)) > 600 %}true{% endif %}'
1 Like

I’ve been trying to figure out the same thing. The PIR sensors I have don’t have an attribute of last_changed or last_updated. However it’s in the front end. I want to use it for my garage door to close after X minutes of no activity.

image

Modify as need, but this works for me with my motion sensor. The “input_boolean.garage_changed_with_ha” is something I use to diferenate between manually opening and opening via automation

- alias: 'Garage Door Close with No Motion for Three Minutes'
  trigger:
  - platform: state
    entity_id: input_boolean.garage_changed_with_ha
    from: 'off'
    to: 'on'
    for:
      minutes: 3
  - platform: state
    entity_id: binary_sensor.motion_sensor_garage_motion
    from: 'on'
    to: 'off'
    for:
      minutes: 3
  condition:
  - condition: state 
    entity_id: binary_sensor.motion_sensor_garage_motion
    state: 'off'
    for:
      minutes: 2
  - condition: state
    entity_id: input_boolean.garage_changed_with_ha
    state: 'on'
  action:
  - service: cover.close_cover
    entity_id: cover.garage_door_opener
  - service: homeassistant.turn_off
    entity_id: input_boolean.garage_changed_with_ha

You could check out the custom ui https://github.com/andrey-git/home-assistant-custom-ui, with this, you can have a last changed attribute under the PIR sensor in the default UI, as seen here in my setup,

sensors

Or if you are using Lovelace UI you can do it without adding anything extra to it, this is my config on Lovelace,

cards:
  - type: entities
    title: Movement / Door Sensor's
    show_header_toggle: true
    entities:
      - entity: binary_sensor.door_window_sensor_158d000239432d
        name: Front Door
        secondary_info: last-changed
      - entity: binary_sensor.door_window_sensor_158d00027b3daa
        name: Garage Door
        secondary_info: last-changed
      - entity: binary_sensor.door_window_sensor_158d000241c505
        name: Letterbox
        secondary_info: last-changed
      - entity: sensor.downstairs_motion_motion_sensor
        name: Downstairs Motion
        secondary_info: last-changed
      - entity: sensor.hallway_motion_motion_sensor
        name: Hallway Motion
        secondary_info: last-changed
      - entity: binary_sensor.motion_sensor_158d0002281e2f
        name: Living Room Motion
        secondary_info: last-changed

And that will give you the same results as the pictures above. Hope this helps you out.

9 Likes

This seems pretty simplistic. I’ll have to test it out. Thanks!

Thanks for all the tips.

My Z-Wave sensors don’t have last_changed or last_updated attributes, so I’m unable to pull this into a template. I’m still unsure on how to achieve this without getting really hacky for a seemingly simple sensor.

I believe those attributes are part of HA itself. I’m not positive but pretty sure. It’s not coming from the device itself. Have you tried it yet?

If necessary I guess you could create an input Boolean tie that Boolean to your motion sensor on/off using a template and then use that for your automations.

Thank you for the tip @ptdalen indeed they are coming from Home Assistant. Anybody who find this thread and wants similar below is the config I ended up with. Seems to be working great so far.

- platform: template
  sensors:
    cat_kennel_last_motion:
      value_template: >-
        {% set today = now().day | int %}
        {% set cat_date = ((as_timestamp(states.sensor.cat_kennel_motion.last_changed) | timestamp_custom("%d")) | int) %}
        {% if today == cat_date %}
          {% set day = "Today" %}
        {% elif (today - 1) == cat_date %}
          {% set day = "Yesterday" %}
        {% elif today == 1 and cat_date > 27 %}
          {% set day = "Yesterday" %}
        {% else %}
          {% set day = as_timestamp(states.sensor.cat_kennel_motion.last_changed) | timestamp_custom("%A")%}
        {% endif %}
        {% set time = as_timestamp(states.sensor.cat_kennel_motion.last_changed) | timestamp_custom("%l:%M %p")%}
        {{[day,time]|join(" at ")}}
      entity_id:
        - sensor.cat_kennel_motion
      friendly_name: 'Cat Kennel Last Motion'
4 Likes

I’m trying to use:

(as_timestamp(now())-as_timestamp(states.sensor.kitchen_motion.last_updated))

As part of an icon template… Basically, I have a crappy z-wave smoke alarm that doesn’t have a test mode. I have 60 seconds to test the alarm when I turn on this switch, I can test the alarm by pressing the physical test button on it and it won’t trigger all my other automations. The switch automatically turns off after 120 seconds. All of that part is working fine I’m just a bit stumped with the icon template. What am I doing wrong?

# Smoke alarm test
- platform: template
  switches:
    smoke_alarm_test:
      value_template: "{{ is_state('input_select.smoke_alarm_mode', 'Test') }}"
      turn_on:
        service: input_select.select_option
        data:
          entity_id: input_select.smoke_alarm_mode
          option: Test
      turn_off:
        service: input_select.select_option
        data:
          entity_id: input_select.smoke_alarm_mode
          option: Armed
      icon_template: >-
        {%- if is_state('input_select.smoke_alarm_mode', 'Armed') %}
          mdi:access-point
        {%- elif is_state('input_select.smoke_alarm_mode', 'Test') %}
          {%- if (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 7.5 %}
            mdi:circle-slice-1
          {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 15 %}
            mdi:circle-slice-2
          {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 22.5 %}
            mdi:circle-slice-3
          {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 30 %}
            mdi:circle-slice-4
          {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 37.5 %}
            mdi:circle-slice-5
          {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 45 %}
            mdi:circle-slice-6
          {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 52.5 %}
            mdi:circle-slice-7
          {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 60 %}
            mdi:circle-slice-8
          {%- endif %}
        {% else %}
          mdi:alert-decagram-outline
        {%- endif %}

What is happening with the icon? I’m going to guess that it “works”, but never changes. Just a quick thought, you need to have <= 15, and then > 16 <=30, etc.

Not an icon template, but I have this for a sensor

        {% if states("sensor.time_to_work") | int >= 32 %}
            Heavy
          {% elif states("sensor.time_to_work") | int < 32 and states("sensor.time_to_work") | int >= 27 %}
            Moderate
          {% elif states("sensor.time_to_work") | int < 27 and states("sensor.time_to_work") | int >= 2 %}
            Normal
          {% else %}
            You're Here
          {% endif %}
1 Like

Hi thanks for your help :grinning: yep at the moment the icon doesn’t change.

I’ve tried this as you suggested - now it updates to “mdi:circle-slice-1” when the switch turns on - and back to “mdi:access-point” when the switch turns off, either manually or automatically. But it doesn’t change to “mdi:circle-slice-2, 3, 4 etc.” as time progresses.

# Smoke alarm test
- platform: template
  switches:
    smoke_alarm_test:
      value_template: "{{ is_state('input_select.smoke_alarm_mode', 'Test') }}"
      turn_on:
        service: input_select.select_option
        data:
          entity_id: input_select.smoke_alarm_mode
          option: Test
      turn_off:
        service: input_select.select_option
        data:
          entity_id: input_select.smoke_alarm_mode
          option: Armed
      icon_template: >-
        {%- if is_state('input_select.smoke_alarm_mode', 'Armed') %}
          mdi:access-point
        {%- elif is_state('input_select.smoke_alarm_mode', 'Test') %}
            {%- if (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 0 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 7.5 %}
              mdi:circle-slice-1
            {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 7.5 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 15 %}
              mdi:circle-slice-2
            {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 15 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 22.5 %}
              mdi:circle-slice-3
            {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 22.5 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 30 %}
              mdi:circle-slice-4
            {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 30 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 37.5 %}
              mdi:circle-slice-5
            {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 37.5 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 45 %}
              mdi:circle-slice-6
            {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 45 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 52.5 %}
              mdi:circle-slice-7
            {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 52.5 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 60 %}
              mdi:circle-slice-8
            {%- endif %}
        {% else %}
          mdi:alert-decagram-outline
        {%- endif %}

I’ve also tried it without:

(as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 0 and

maybe something like this

       {%- elif is_state('input_select.smoke_alarm_mode', 'Test') and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 0 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 7.5 %}
              mdi:circle-slice-1
       {%- elif is_state('input_select.smoke_alarm_mode', 'Test') and(as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) > 7.5 and (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) <= 15 %}
              mdi:circle-slice-2

Ok so I’ve tested this and low and behold it should work. If I toggle the switch to on, and paste this into Developer tools > Template and I hit return every few seconds - the output cycles through each of the different icons mdi:circle-slice-1, 2, 3 etc. and back to mdi:access-point when the switch is turned off after 60 seconds.

But for some reason - this isn’t what shows up in lovelace - it only gets as far as mdi:circle-slice-1 so something else is going on :frowning: @frenck any ideas?


icon_template: >-
  {%- if is_state('input_select.smoke_alarm_mode', 'Armed') %}
    mdi:access-point
  {%- elif is_state('input_select.smoke_alarm_mode', 'Test') %}
      {%- if (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) < 7.5 %}
        mdi:circle-slice-1
      {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) < 15 %}
        mdi:circle-slice-2
      {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) < 22.5 %}
        mdi:circle-slice-3
      {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) < 30 %}
        mdi:circle-slice-4
      {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) < 37.5 %}
        mdi:circle-slice-5
      {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) < 45 %}
        mdi:circle-slice-6
      {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) < 52.5 %}
        mdi:circle-slice-7
      {%- elif (as_timestamp(now())-as_timestamp(states.input_select.smoke_alarm_mode.last_changed)) < 60 %}
        mdi:circle-slice-8
      {%- endif %}
  {% else %}
    mdi:alert-decagram-outline
  {%- endif %}

If I had to guess, I would say the icon_template is only reevaluated upon an actual state change of the entity, so when it is either turned on or off.

@fanaticDavid ok that (frustratingly) makes some sense. Hmmm :roll_eyes: will have another think… if anyone has a solution I’m all ears!

This is not what you’re doing exactly, but I use this for weather, it the weather sensor triggers the change of the icon.

      weather_icon:
        entity_id: sensor.dark_sky_icon, weather.home_darksky, weather.woensdrecht
        friendly_name_template: >
          {{states('sensor.weather_icon').split('weather')[1]|replace('-',' ')|title}}
        value_template: >
          {% set mapper_icon =
            {'partly-cloudy-night': 'night-partly-cloudy',
             'clear-day': 'sunny',
             'clear-night': 'night',
             'sunny': 'sunny',
             'rainy': 'rainy',
             'rain': 'rainy',
             'snow': 'snowy',
             'sleet': 'snowy-rainy',
             'wind': 'windy',
             'fog': 'fog',
             'cloudy': 'cloudy',
             'partlycloudy': 'partly-cloudy',
             'partly-cloudy-day': 'partly-cloudy',
             'hail': 'hail',
             'thunderstorm': 'lightning',
             'tornado': 'hurricane'} %}
          {% set icon = states('sensor.dark_sky_icon') %}
          {% set weather = mapper_icon[icon] if icon in mapper_icon else 'sunny-alert' %}
            mdi:weather-{{weather}}

        icon_template: >
          {{states('sensor.weather_icon')}}

Maybe this will give you some ideas

I’m still no expert with all these scripting and I’m a little confused at the moment. I hope you can help me a little bit. I try to deactivate an automation (the notification is only an example) for one hour if a switch (switch.wz_tv) was toggled. In the comments i have the single steps what i tried within the one line above.

- alias: test last changed window
  trigger:
  - platform: time_pattern
    seconds: '/1'
  condition: 
    condition: template
      value_template: '{{ ( ( ( ( ( as_timestamp(now()) ) - ( as_timestamp(states.switch.wz_tv.last_changed) ) | int ) | round(0) ) / 60 ) | int ) > 880 }}'
      # value_template: >-
      #   {% set temp_now = as_timestamp(now()) %}
      #   {% set temp_lastchanged_absolute = as_timestamp(states.switch.wz_tv.last_changed) %}
      #   {% set temp_lastchanged_sec = ((temp_now - temp_lastchanged_absolute | int) | round(0)) %}
      #   {% set temp_lastchanged_min = (temp_lastchanged_sec / 60 ) | int %}
      #   {% if temp_lastchanged_min > 880 %}
      #     true
      #   {% else %}
      #     false
      #   {% endif %}
  action: 
  - service: notify.ha_message_manuel
    data:
      message: 'XXX'

I was searching for this option for couple hours. THANK YOU !!!