Trigger automation if no state update for x minutes

Hi,

I have a number of wireless temperature and humidity sensors that report to Home Assistant via MQTT. Occasionally one of the sensors fails for a number of reasons (connectivity drops, power down, crash etc.) but I will often not release this for hours or sometimes days as it relies on me noticing a reading hasn’t changed.

I would like to write an automation that sends a notification when a sensor value does not change over a set time period (maybe an hour??). This way I will know to check that the sensor hasn’t crashed as no updated information has been received for an extended period of time.

Problem is I cannot work out how to write the trigger, would any one be able to help?

Thanks,

Tim

Your best bet would be to create a template sensor to measure the state change and then use a for statement to measure the update time in your automation trigger.

Thanks, but struggling with the template sensor. I have pasted the error I get below but I believe I know why this isn’t working. The temperature sensor is an MQTT sensor so the value for the sensor is not defined for a few seconds at boot until Home Assistant connects to my MQTT broker. I have tried to put an if statement in to try and capture this but it’s not working. Does anyone have any thoughts on how to capture this?

Template rule:

{% if is_state("sensor.back_room","Undefined") %} 0 {% else %} {{ relative_time(states.sensor.back_room.last_updated) }} {% endif %}

Error:

16-09-23 09:59:19 homeassistant.components.sensor: Error while setting up platform template
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/entity_component.py", line 107, in _setup_platform
    discovery_info)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/sensor/template.py", line 53, in setup_platform
    entity_ids)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/sensor/template.py", line 77, in __init__
    self.update()
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/components/sensor/template.py", line 108, in update
    self._state = template.render(self.hass, self._template)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/helpers/template.py", line 62, in render
    }).render(kwargs).strip()
  File "/usr/local/lib/python3.4/dist-packages/jinja2/environment.py", line 989, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.4/dist-packages/jinja2/environment.py", line 754, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.4/dist-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
  File "/usr/local/lib/python3.4/dist-packages/jinja2/sandbox.py", line 355, in call
    return __context.call(__obj, *args, **kwargs)
  File "/usr/local/lib/python3.4/dist-packages/homeassistant/util/dt.py", line 186, in get_age
    delta = now() - date
TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'Undefined'

Fixed it:

‘{% if states(“sensor.back_room”) is not number %} 0 {% else %} {{ relative_time(states.sensor.back_room.last_updated) }} {% endif %}’

does it update also?

for me it stays at 0 seconds all the time

First solution didn’t work as ReneTode rightly points out

My best solution is a bit hacky so happy for any one to suggest a better solution. I have created a new input boolean and an automation which switches it off 1 minute after home assistant_start. The new template sensor is:

{% if is_state(“input_boolean.starting_up”, “off”) %} {{ relative_time(states.sensor.back_room.last_updated) }} {% else %} 0 {% endif %}’

The next problem is that the value of this sensor is a string, i.e. 7 seconds or 1 minute so I cannot set up an automation that triggers if value is great than x. I also tried manually calculating the time since last change but this gives you another string e.g 00:00:07.85775. I would ideally like a float/int of how many seconds (or minutes) it has been since it last updated but cannot workout how to do it

i’m still truing to find a working solution without appdaemon, but i think you need that for it.

@ReneTode @timstanley1985

I have replicated this situation and it appears to be working for me. Not sure if it will be useful or not but here it goes…

I am using the ping function of the speed test component as my sensor.

sensor:
  - platform: speedtest
    server_id: 1234
    minute:
     - 0
     - 30
    monitored_conditions:
     - ping

I then created a template sensor that counts the time it has been since it was last updated.

  - platform: template
    sensors:
      ping_last_update:
        value_template: "{{ relative_time(states.sensor.speedtest_ping.last_updated) }}"

My automation uses a template trigger to read the state of the template sensor

automation:
- alias: notify if sensor state unchanged
  trigger:
    platform: template
    value_template: "{% if is_state('sensor.ping_last_update', '2 minutes') %}true{% endif %}"
  action:
    service: persistent_notification.create
    data:
      notification_id: "1234"
      message: "Sensor is Down"
      title: "Test"

I get a notification when the template sensor hits 2 minutes.

Regards

2 Likes

but does the template sensor change value in the frontend?

It changes value in real time and you can watch it update the time since the last update of the sensor (sensor you are monitoring). Since it is an entity you can add it to the front end but it is not necessary. I was just watched it from the Dev tools-> states page. If I forced the speedtest sensor to update then the template sensor went back to 0 and started counting up again. It appeared to update every minute.

2 Likes

i finally found a general way to see how long ago a sensor is updated. in a format i like and it updates in the frontend.
@PtP got me thinking again.

i made a date_time sensor and use that as entity from the template.

so it is:

sensors:
  - platform: time_date
    display_options:
      - 'date_time'
  - platform: template
    sensors:
      controle_sensor:
        friendly_name: any sensor
        value_template: '{% if states.sensor.your_sensor.last_updated is undefined %}{{"00:00:00"}}{% else %}{{ ((as_timestamp(states.sensor.date__time.last_updated)-as_timestamp(states.your_sensor.last_updated))|timestamp_utc)[11:19] }}{% endif %}'
        entity_id:
          - sensor.date__time

it gives the time gone by as 00:00:00 (but it is a string)
to lose the seconds change [11:19] to [11:16]
to see the amount of seconds gone by as int replace |timestamp_utc with .seconds and lose the [11:16] part

8 Likes

The thread is very interesting. Monitoring for stale data from a sensor looks to be very useful. I am trying another approach, however. I am attempting, with mixed sucess to use device_tracker to determine if a sensor is transmitting. NMAP performs the needed function for showing on the UI status (Home or Away) for the sensor. However, NMAP causes my rpi3 wifi to lockup after a short run time. Still trying to sort out the cause of that. NOTE: edited original post to correct error citing nodemcu wifi issue instead of rpi3 wifi issue.

Trying to get the seconds version to work and have below based on you comment “replace |timestamp_utc with .seconds and lose the [11:16] part”.

Could you point me in the right direction (again)?

  - platform: template
    sensors:
      last_motionv2:
        friendly_name: Last motionv2
        value_template: '{% if states.group.motion_indoors.last_updated is undefined %}{{"00:00:00"}}{% else %}{{ ((as_timestamp(states.sensor.date__time.last_updated)-as_timestamp(states.group.motion_indoors.last_updated)).seconds) }}{% endif %}'
        entity_id:
          - sensor.date__time

the part with .seconds doesnt seem to work anymore.

please try:

{% if states.group.motion_indoors.last_updated is undefined %}{{"00:00:00"}}{% else %}{{ ((as_timestamp(states.sensor.date__time.last_updated)-as_timestamp(states.group.motion_indoors.last_updated))|int) }}{% endif %}

i tried it and it works for me.

1 Like

Thanks. That did it.

An Appdaemon solution: https://gist.github.com/adrianlzt/f0c073dd163e4512510ca3d8fa91a4c2

Can i check, is this working for anyone?

I have added an option “expire_after” to mqtt sensor that does exactly what you describe here. See https://github.com/home-assistant/home-assistant/issues/6705 for details. Pull request is coming as soon as my test runs.

1 Like

As of 0.53, there’s a new counter component that might be used to check if something isn’t working. For example, setting a counter at 24, and decreasing it by one every hour (resetting it at 24 whenever an event arrives), you could set an automation triggered by the counter reaching 0 that would let you know it’s been 24h since last update.

Does it work with 0.54? HA show 0 seconds on this sensor and does not sens alerts.