Determine state unchanged entities for a certain period

Hello.

I have been trying to figure out a way of having an automation triggered for a specific set of entities in case its state has NOT changed for a period of time (let’s say 24hours, for instance).

I considered the following:

automation:
  - alias: 'Longtime unchanged'
    id: longtime_unchanged
    trigger:
      - platform: template
        value_template: >-
          {% set check_entities = (
            'sensor.temperatura_diogo_bt', 
            'sensor.temperatura_quarto_bt', 
            'sensor.temperatura_sala_bt', 
            'sensor.temperatura_sara_bt', 
            'sensor.temperatura_wc_bt', 
            'sensor.temperatura_wc_quarto_bt'
            ) %}
          {% for item in states -%}
            {%- if item.entity_id in check_entities %}
              {{ (as_timestamp(now()) - as_timestamp(as_local(item.last_changed))) > 86400 }}
            {%- endif %}
          {%- endfor %}
    action:
      - service: notify.ios_papa
        data:
          title: "{{ states('sensor.ha_message_alert') }}"
          message: "{{ trigger.to_state.attributes.friendly_name }} unchanged for 1 day now"
          data:
            group: "not_available"

and thought that once my template trigger condition would become true (one entity without state changes for more than 24h), it would spam me with notifications until the condition would become false…

I also considered the following (triggering the automation at a specific time each day and use template as a condition instead):

automation:
  - alias: 'Longtime unchanged'
    id: longtime_unchanged
    trigger:
      - platform: time
        at: '15:00:00'
    condition:
      condition: template
      value_template: >-
        {% set check_entities = (
          'sensor.temperatura_diogo_bt', 
          'sensor.temperatura_quarto_bt', 
          'sensor.temperatura_sala_bt', 
          'sensor.temperatura_sara_bt', 
          'sensor.temperatura_wc_bt', 
          'sensor.temperatura_wc_quarto_bt'
          ) %}
        {% for item in states -%}
          {%- if item.entity_id in check_entities %}
            {{ (as_timestamp(now()) - as_timestamp(as_local(item.last_changed))) > 86400 }}
          {%- endif %}
        {%- endfor %}
    action:
      - service: notify.ios_papa
        data:
          title: "{{ states('sensor.ha_message_alert') }}"
          message: >-
            {% set check_entities = (
              'sensor.temperatura_diogo_bt', 
              'sensor.temperatura_quarto_bt', 
              'sensor.temperatura_sala_bt', 
              'sensor.temperatura_sara_bt', 
              'sensor.temperatura_wc_bt', 
              'sensor.temperatura_wc_quarto_bt'
              ) %}
            {% for item in states -%}
              {%- if item.entity_id in check_entities %}
                {%- if (as_timestamp(now()) - as_timestamp(as_local(item.last_changed))) > 86400 %}
                    {{ item.attributes.friendly_name }} unchanged for 1 day now
                {%- endif %}                
              {%- endif %}
            {%- endfor %}
          data:
            group: "not_available"

but “repeating” the template in the condition and the action, besides odd, it doesn’t guarantee that I get the same exact result in case more than 1 entity is state-unchanged for the last 24h.

I could not figure out if I could somehow bring the template condition result to the action (to allow identifying the exact entity ID friendly name that caused the condition to be true). Is that even possible?

Maybe I’m “overcomplicating”, but I would really appreciate any ideas on how to achieve my purpose, even if completely different from the ones I have shown above.

Has anyone have anything similar built only based on automations (not appdaemon or something)?

Thanks in advance for any insights.

Kind regards.

the problem with your template is that it will trigger off entities that are not your triggering entity. So it will tell you that the wrong entity is not available. Also, you don’t need a template.

trigger:
- platform: state
  entity_id:
         - sensor.temperatura_diogo_bt
         - sensor.temperatura_quarto_bt
         - sensor.temperatura_sala_bt
         - sensor.temperatura_sara_bt
         - sensor.temperatura_wc_bt
         - sensor.temperatura_wc_quarto_bt
  for: "23:59:59"

I’m not 100% sure 24 hours will work, but 23:59:59 will.

1 Like

If you are interested, I provided a method of reporting “stale” sensors here:

For your intended application, change timedelta(seconds=14400) in the example to timedelta(hours=24).

1 Like

also, as an FYI…

using long for: times like that isn’t a good practice.

any restart of HA or re-loading automations will result in the trigger never happening even if the state doesn’t ever change. But if the entities change state after the restart/re-load the timer function restarts and will trigger correctly again…as long as no restart or re-load occurs after it changes state again.

You can use it if it’s not critical that the trigger occurs but I wouldn’t rely on it if the trigger is important.

Every single possible solution posted so far will have this issue though, why single out for? This is nothing new. Restarts change last_changed.

As per petro’s comment, in this situation they’re all affected by a restart. However, you’re right about reloading automations; it will reset any State Trigger employing a for. The longer for waits, the greater the opportunity for it to be reset if automations are reloaded (like when one creates/modifies an automation using the Automation Editor).

Thanks everyone for your insights, I think I will try @123’s solution for stale sensors, that is actually similar for what I have now for battery sensors.

I will trigger an automation once a day and that should be enough, to avoid the for: issues with HA restarts/automation reloads (in my case, the second is more and more common to avoid the doing the first).

Thanks again.

because it was specifically recommended in this thread? :man_shrugging:

and not many understand the ramifications of using it (or any other timer based functions).

I didn’t say not to use it. I just explained why it isn’t the best to use it if it’s important that the triggers occur and the times involved are long.

yup, and that should be fixed.

but re-loading automations doesn’t but it kills the ‘for’ trigger.

So basically there is no real good reliable solution to any timer based functions.

the most reliable would be to create an input_datetime (which aren’t affected by a restart) for any entity you want to monitor and trigger on that.

but that gets really cumbersome when there are more than a couple entities to watch.

But again, it’s the most reliable way to do it with the limitations imposed by the way HA currently implements timers or timer based functions.

So if the trigger is that important then it’s the only way to accomplish it.