Monitor if entity is changed, set alert if not changed within a time period

I need an automation to check when some entity is not changed for some specified time.
If not changed → set some flag.

Here is how it works:

  1. Wait for a change of the entity’s state.
  2. If the entity’s state is NOT changed within some time period → set the flag ON.
  3. If the entity’s state IS changed within this period → set the flag OFF.
  4. Goto step 1.

Probably this task is already solved ny someone, I was not looking for long.

I made an automation which uses two entities:

  • input_number.test_number - the monitored entity;
  • input_boolean.test_boolean - the flag.

The code:

alias: xxxxxxxxxxxx
description: ''

variables:
  NOTIFICATION_CHANNEL: test
  NOTIFICATION_FLAG: input_boolean.service_true_value
  TIMEOUT: 2

mode: single

trigger:
  - platform: homeassistant
    event: start

condition: []

action:
  - repeat:
      sequence:
        - variables:
            VALUE_LAST_STATE: '{{states("input_number.test_number")}}'
        - wait_for_trigger:
            - platform: state
              entity_id: input_number.test_number
          timeout:
            minutes: >-
              {% if is_state("input_boolean.test_boolean","off") -%}
              {{TIMEOUT}}
              {%- else -%}
              99999
              {%- endif %}
          continue_on_timeout: true

        - choose:
            - conditions:
                - condition: template
                  value_template: '{{ wait.trigger is not none }}'
              sequence:
                - choose:
                    - conditions:
                        - condition: template
                          value_template: '{{ is_state("input_boolean.test_boolean","on") }}'
                      sequence:
                        - service: input_boolean.turn_off
                          target:
                            entity_id: input_boolean.test_boolean
                          data: {}
          default:
            - choose:
                - conditions:
                    - condition: template
                      value_template: '{{ is_state("input_boolean.test_boolean","off") }}'
                  sequence:
                    - service: input_boolean.turn_on
                      target:
                        entity_id: input_boolean.test_boolean
                      data: {}

        - variables:
            VALUE_NEW_STATE: '{{states("input_number.test_number")}}'
        - service: .... ### send a notification
          data:
            message: |-
              {% if wait.trigger is not none -%}Changed{%- else -%}Timeout{%- endif %}
              Last: {{VALUE_LAST_STATE}}, New: {{VALUE_NEW_STATE}}
              Flag: {{states("input_boolean.test_boolean")}}

      until:
        - condition: template
          value_template: '{{false}}'

I am not an expert in automations and would be grateful if someone suggests any improvements & find errors.

P.S. This automation - if is properly constructed - will be transformed into blueprint, I find it’s purpose very useful.

You don’t need an automation for this.
Just create a template binary sensor like this:

template:
  - binary_sensor:
      - name: "Test Number unchanged for 1h"
        state: "{{ as_timestamp(now()) | round - as_timestamp(states.input_number.test_number.last_changed) | round > 3600 }}"

Where 3600 is the number of seconds.

If you don’t need this in more than one automation, you can just use the template directly in your automation as a template trigger.

I’m not sure how often this template is evaluated, so you might want to add rate-limiting if it’s straining your CPU.

2 Likes

Templates are already rate limited. The template you provided will update at most once per minute, on the minute.

1 Like

Ah, that’s good to know, since now() updates every second. Didn’t read that in the docs. Thanks :slight_smile:

  • now() inside a template will cause the template to update on the minute, no rate_limit.
  • entities inside a template will cause to update when the entity changes state, no rate_limit.
  • using states without a domain will cause the template to update on all state changes, however it’s rate limited to 1 update a minute.
  • using states.<domain> will cause the template to update on all state changes, however it’s rate limited to 1 update a second
1 Like

Too easy)) Thank you!

The only problem is here.
After HA restart the monitored sensor is not actually updated - but it’s last_changed says that it was changed recently (because HA restarted).
So the binary_sensor flag is not set on startup.

My automation is triggered when the sensor is really changed.
The flag is restored after HA restart and may be toggled by the automation.

If the specified timeout is 5 minutes, it may not be a problem - the flag will be set in 5 minutes after HA restart.
If the timeout is bigger, that it may be critical.

if you want this to persist over a startup, store the last changed in an input_datetime or in a MQTT sensor that’s restored on startup. Otherwise, what you’re describing is how everything in HA works. Last changed for all entities are set to the startup time of HA upon restart.

Or, add a ‘just started’ template binary_sensor that’s on for the first 6 minutes of a reboot and use that as a condition in your automation or the other binary sensor.

Yes, I know it, thank you for reminding.

Need some time to understand this method.

Let’s assume I have 10 monitored sensors.
Here is my method.

  1. I can use my automation from the 1st post which sets an input_boolean helper - 10 automations.
  2. 10 input_boolean helpers (toggled by that automation).
  3. 10 binary_sensor alert flags - states are equal to those input_boolean helpers.

Hard to say what is more complex/cumbersome.
Probably my automation is more complex… But it seems to work)))

Could you have a look at that automation?

I am not getting the idea , need some more time to understand.

One more thing.
Since - as you reminded - the problem “all sensors update last_changed on HA startup” - probably I will need a common mechanism to “restore a real last_changed” after HA restart for many sensors (not only mentioned here).

Sure, post the automation

It is in the 1st post

Do you have MQTT?

No, have not started learning it yet…
Does it have ready solutions for this?

no, but it makes it so you don’t need helpers as you can just dynamically create anything on the fly and have it load into your system and persist restarts.

I have scripts that do this, I think @123 has a “copy/paste” solution that might work right out of the box without much editing. All mine are locked into a rigid plan that would require heavy edits.

123 sorry for the @ but you seem to have a good solution for this and I could not find it.

Fedot’s solution is basically what I have suggested to others but using datetime objects in the subtraction instead of timestamps (slightly more compact template).

  {{ now() - states.input_number.test_number.last_changed > timedelta(hours=1) }}

What you might be thinking of is this automation that periodically checks for stale sensors.

The requirement was to check every 4 hours for any sensor or binary_sensor that hasn’t been updated in several hours. It uses a Time Pattern Trigger in order to control the polling interval (to avoid checking every minute as in a template employing now()). It can be easily adapted to check every few minutes and could be made to check on startup as well (add the appropriate homeassistant startup trigger).

2 Likes