Alert when sensors stop updating

Kindof solved it but dont know if its the right approach

{{ as_timestamp(states.sensor.vardagsrum_temperature.last_changed) | timestamp_custom('%D %H:%M:%S',True) }}

this gives me the wrong date format though: 12/15/21 12:03:27 instead of 2021-12-15 12:03:27.091115+00:00

EDIT.

forget that I think @tom_l solved this in his original post here
or mabye even better I just saw that @RubenKelevra seems to have the easiest solution so I’m tryin that one. Hope it works!

I cannot figure out what is happening in these state changes/updates :frowning:

I have a sensor integrated thought MQTT integration. It works well, but I wanted to add notification we sensors stop updating. Based on this thread, I’ve created automation, comparing last_updated with utcnow() and if its older than 10 minutes it sens notification. Looks ok, but I’ve got strange behavior:

20:24:52 - automation triggered, payload:
sensor has not updated since 10 minutes
sensor has updated exactly 902 seconds ago
now local   : 2022-01-07 20:24:52.172910+01:00
last_updated: 2022-01-07 20:09:49.879704+01:00
last_changed: 2022-01-07 18:49:08.860460+01:00

Is there any scheduler working each 900 seconds? Why 900 if I’ve set it for 600 (10 minutes)?

after ~5 minutes it is the same:

sensor has not updated since 10 minutes
sensor has updated exactly 903 seconds ago
now local   : 2022-01-07 20:29:55.277688+01:00
last_updated: 2022-01-07 20:14:52.162965+01:00
last_changed: 2022-01-07 18:49:08.860460+01:00

so now it looks like sensor was updated BEFORE first occurrence of automation trigger - so why it was triggered?
Strange.

What’s even stranger, situation is the same, when I’ve change timeout to 31minutes:

sensor not updated for 31 minutes
sensor updated exactly 2162 seconds ago
---
now local   : 2022-01-08 01:13:05.612959+01:00
last_updated: 2022-01-08 00:37:03.321747+01:00
last_changed: 2022-01-08 00:37:03.321747+01:00

and second occurance:

sensor not updated for 31 minutes
sensor updated exactly 2162 seconds ago
---
now local   : 2022-01-08 01:18:08.189436+01:00
last_updated: 2022-01-08 00:42:05.602653+01:00
last_changed: 2022-01-08 00:37:03.321747+01:00

both triggered with 5 minutes delay (strange, but let’s skip it), but showing different last_updated historical values. Any idea why?

Hi, I would like to ask what the code will look like if I want the notification to appear if the sensor is not updated for 12 minutes? I don’t know “60 > 30” at the end.

Mine automation looks like follows, it’s simple and should work, but as I mentioned above - something is wrong :frowning:

- id: '1641575869039'
  alias: sensors not updating
  description: triggered by state not changed for 31min but only if additionaly last_upd$
    not changed for 31min -> sends notification
  trigger:
  - platform: state
    entity_id: sensor.gleba01_moisture
    for: 00:31:00
  - platform: state
    entity_id: sensor.gleba02_moisture
    for: 00:31:00
  condition:
  - condition: template
    value_template: '{{ (utcnow() - trigger.from_state.last_updated).seconds > 31*60}}'
  action:
  - service: notify.pawel_mail
    data_template:
      # multiple lines literals are a bit tricky in YAML [https://stackoverflow.com/ques$
      #   HA uses single quotes '' and double line end
      message: '{{ trigger.from_state.attributes.friendly_name }} not updated for
        31 minutes

        updated exactly {{(utcnow() - trigger.from_state.last_updated).seconds}} seconds$

        state:  {{ trigger.from_state.state }}

        ---

        now local   : {{now()|as_local}}

        last_updated: {{ trigger.from_state.last_updated|as_local }}

        last_changed: {{ trigger.from_state.last_changed|as_local }}

        ---

        UTC now         : {{utcnow()}}

        UTC last_updated: {{ trigger.from_state.last_updated }}

        UTC last_changed: {{ trigger.from_state.last_changed }}

        '
  mode: single

I do this for both sensors and zwave devices. This is a template for a zwave device that has a temperature sensor. When I add a new device like this I use sed to create the new package.

First, there is a sensor that calculates the latency. Second, there is a binary_sensor that determines if the latency exceeds a limit. When that binary_sensor fires it can run an automation, generate an alert,etc. With this sensor, whenever is gets a power fluctuation it stops reporting temperature and I’ve determine that if I repush the zwave configuration it starts reporting again - so I run an automation automatically to do it, Most of my config is now templated like this and it makes is easy to change things.


sed 's/multisensor_1/basement/g' zwave_template_aoetec_multisensor_package.yaml | sed 's/50/50/g' > /mnt/c/github/ha_sage/packages/zwave_template_basement_package.yaml


# multisensor_1
sensor:
  - platform: template
    sensors:
      zwave_multisensor_1_latency:
        unit_of_measurement: secs
        value_template: "{{ as_timestamp(now(), 0) | int(0) - as_timestamp(state_attr('zwave.multisensor_1','receivedTS') | string | truncate(19,True,'',0) | as_datetime, 0)| int(0) }}"
        availability_template: "{{ as_timestamp(state_attr('zwave.multisensor_1','receivedTS') | string | truncate(19,True,'',0) | as_datetime,0)| int(0) > 0 }}"
      zwave_multisensor_1_temp_latency:
        unit_of_measurement: secs
        value_template: "{{ ((as_timestamp(now(), 0) | int(0)) - as_timestamp(states.sensor.multisensor_1_temperature.last_updated,0) | int(0)) }}"
        availability_template: "{{ as_timestamp(states.sensor.multisensor_1_temperature.last_updated,0) | int(0) > 0 }}"

binary_sensor:
  - platform: template
    sensors:
      zwave_multisensor_1_online:
        value_template: "{{ (( state_attr('zwave.multisensor_1','wake_up_interval')|int(0) * 2) - (states('sensor.zwave_multisensor_1_latency') | int(0))) > 0}}"
      zwave_multisensor_1_temp_online:
        value_template: "{{ (( state_attr('zwave.multisensor_1','wake_up_interval')|int(0) * 2) - (states('sensor.zwave_multisensor_1_temp_latency') | int(0))) > 0}}"

recorder:
  include:
    entities:
      - binary_sensor.zwave_multisensor_1_online
      - binary_sensor.zwave_multisensor_1_temp_online
      - zwave.multisensor_1

You can trigger a notification using a restartable automation. Just set a delay has the first action that longer than the interval between updates and if a new update is not received, the next action is fired which sends you a notification.

alias: Notify if CumulusMX data not updating
description: ''
trigger:
  - platform: mqtt
    topic: CumulusMX/Interval
condition: []
action:
  - delay:
      hours: 0
      minutes: 2
      seconds: 0
      milliseconds: 0
  - service: notify.mobile_app_dave_phone
    data:
      message: CumulusMX Data not received
      title: CumulusMX Down
mode: restart
2 Likes

this simple automation works for me with no extra tamplate sensors.

as I use it for my rtl4332mqtt sensors, so I always include a time as atribute in any update I publish in rtl4332mqtt. so I can simply utilize that atribute.

alias: 'sensor not updating notifications '
description: ''
trigger:
  - platform: state
    entity_id:
      - sensor.boysroom433
      - sensor.office433
      - sensor.playroom433
      - sensor.library433
      - sensor.outside433
    attribute: time
    for:
      hours: 0
      minutes: 10
      seconds: 0
condition: []
action:
  - service: notify.whatsapp
    data:
      message: >-
        {{ trigger.from_state.attributes.friendly_name }} not updated for 10
        minutes
mode: parallel

As I said I use this on the “last seen” attribute, which change which each received package from the device. So the temperature doesn’t need to change for it to trip properly.

Hey there, so I am struggling to understand the purpose of the if/else logic in your template…

  {% if states.sensor.outside_front_temperature.last_changed > states.sensor.outside_front_humidity.last_changed %}
            {{ (states.sensor.time.last_changed - states.sensor.outside_front_temperature.last_changed).total_seconds() | round(0) }}
          {% else %}
            {{ (states.sensor.time.last_changed - states.sensor.outside_front_humidity.last_changed).total_seconds() | round(0) }}
          {% endif %}

Could you explain why you’re comparing two values from presumably the same physical device? If something where hung I would assume both sensors of the device would be hung at the same time

Yes. Because it reports separate values, there are 3 possible cases.

Temperature changed
Humidity changed
Temperature AND Humidity changed

I want to capture the “last changed” as whichever most recently changed for the purposes of debugging and validation.

Psudocode:

If ( temperature_changed "more recently than" humidity_changed ); then
    return ( now - when temperature changed )
else
    // This means humidity changed more recently than temperature
    return ( now - when humidity changed )

Note: “changed” is not the same as “updated”. I was using “changed” because in some cases if the incoming MQTT data is corrupted (yay wireless sensors) and I receive a value outside of the sensor’s min/max range possible like -80F or +300F, I throw it out and copy the last valid data when it brings the MQTT value in. But that process still counts as an “update”. By using the “last changed” value I can tell if it’s stuck spewing garbage data (which sometimes happens with low batteries), and in my use the odds of neither temp nor humidity changing by even 0.1F or 1% over some minutes are basically zero so it gives me a good measure.

Note 2: I think now states.sensor.time.last_changed can be replaced by now() but it used to be you had to use a separate sensor in templates long ago.

I tried to use this seemingly clear and simple code for my purposes, but it doesn’t seem to work

are there any prerequisites for this to operate as expected?

Genius! That’s so slick. Thanks.

Is there a way to perform this check within an IF statement rather than a trigger?

The communication between our Pentair pump and IntelliCenter2 will drop and the only method to check is if the GPM has been updated in over five minutes.

When the pump is OFF the GPM would not be updated, using your method would trigger the automation too frequently.

That’s what a condition is for in an automation.

I tend to build one automation to control a device, then chose what to do based off the Trigger ID.

Without any organization structure the number of automations was growing to be unmanageable.
Guess I should rethink how I’m filtering out…

make a template binary sensor

I do that already for other parts…
Sadly I have a LOT of devices that go offline (local control) due to poor hardware and software. I have had to use helpers and such to ensure I do not get stuck into a loop of resetting devices.

This is one automation that I have found works well.

alias: Network Closet - Eagle Integration Unavailable
description: Reloads the Rainforest Eagle integration should it become unavailable
trigger:
  - platform: state
    entity_id:
      - sensor.eagle_200_meter_power_demand
    for:
      hours: 0
      minutes: 1
      seconds: 0
  - platform: homeassistant
    event: start
    id: HA Start
condition:
  - condition: state
    entity_id: input_boolean.power_online
    state: "on"
  - condition: state
    entity_id: input_boolean.rainforest_eagle_error
    state: "off"
action:
  - if:
      - condition: state
        entity_id: input_boolean.power_online
        state: "on"
      - condition: not
        conditions:
          - condition: state
            entity_id: sensor.eagle_200_meter_power_demand
            state: unavailable
        alias: Current Power Demand Available?
    then:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: input_boolean.rainforest_eagle_error
      - stop: "RESOLVED: No Action Necessary"
    else:
      - service: input_boolean.turn_on
        data: {}
        target:
          entity_id: input_boolean.rainforest_eagle_error
    alias: Current Power Demand Available?
    enabled: true
  - if:
      - condition: state
        entity_id: input_boolean.power_online
        state: "on"
      - condition: not
        conditions:
          - condition: state
            entity_id: sensor.eagle_200_meter_power_demand
            state: unavailable
        alias: Current Power Demand Available?
    then:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: input_boolean.rainforest_eagle_error
      - stop: "RESOLVED: No Action Necessary"
    else:
      - wait_for_trigger:
          - platform: state
            entity_id:
              - sensor.eagle_200_meter_power_demand
        timeout:
          hours: 0
          minutes: 2
          seconds: 0
          milliseconds: 0
    alias: Current Power Demand Available? If not, wait up to 2 minutes.
  - service: homeassistant.reload_config_entry
    data: {}
    target:
      entity_id: sensor.eagle_200_meter_power_demand
  - if:
      - condition: state
        entity_id: input_boolean.power_online
        state: "on"
      - condition: not
        conditions:
          - condition: state
            entity_id: sensor.eagle_200_meter_power_demand
            state: unavailable
        alias: Current Power Demand Available?
    then:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: input_boolean.rainforest_eagle_error
      - stop: "RESOLVED: Eagle Integration Reload"
    else:
      - wait_for_trigger:
          - platform: state
            entity_id:
              - sensor.eagle_200_meter_power_demand
        timeout:
          hours: 0
          minutes: 2
          seconds: 0
          milliseconds: 0
    alias: Current Power Demand Available? If not, wait up to 2 minutes.
  - if:
      - condition: state
        entity_id: input_boolean.power_online
        state: "on"
      - condition: not
        conditions:
          - condition: state
            entity_id: sensor.eagle_200_meter_power_demand
            state: unavailable
            alias: Confirm Current Power Demand is Available
        alias: Current Power Demand Available?
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.eagle_power_outlet_switch_3
      - delay:
          hours: 0
          minutes: 0
          seconds: 10
          milliseconds: 0
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.eagle_power_outlet_switch_3
      - delay:
          hours: 0
          minutes: 0
          seconds: 30
          milliseconds: 0
      - service: homeassistant.reload_config_entry
        data: {}
        target:
          entity_id: sensor.eagle_200_meter_power_demand
    alias: >-
      If Current Power Demand Unavailable then Power Cycle Rainforest Eagle,
      Reload Integration
    else: []
  - if:
      - condition: state
        entity_id: input_boolean.power_online
        state: "on"
      - condition: not
        conditions:
          - condition: state
            entity_id: sensor.eagle_200_meter_power_demand
            state: unavailable
        alias: Current Power Demand Available?
    then:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: input_boolean.rainforest_eagle_error
      - stop: "RESOLVED: Power Cycles of Rainforest Eagle"
    else:
      - wait_for_trigger:
          - platform: state
            entity_id:
              - sensor.eagle_200_meter_power_demand
        timeout:
          hours: 0
          minutes: 2
          seconds: 0
          milliseconds: 0
    alias: Current Power Demand Available? If not, wait up to 2 minutes.
  - if:
      - condition: state
        entity_id: sensor.eagle_200_meter_power_demand
        state: unavailable
      - condition: state
        entity_id: input_boolean.power_online
        state: "on"
    then:
      - service: notify.mobile_app_billy_iphone14pro
        data:
          title: Eagle Rainforest Unavailable
          message: Eagle Rainforest is Unavailable after Reload
      - service: input_boolean.turn_on
        data: {}
        target:
          entity_id: input_boolean.rainforest_eagle_error
      - stop: Unable to Resolve Rainforest Eagle Error
        error: true
    alias: "Unable to Resolve: Alert Billy"
  - if:
      - condition: not
        conditions:
          - condition: state
            entity_id: sensor.eagle_200_meter_power_demand
            state: unavailable
          - condition: state
            entity_id: sensor.eagle_200_meter_power_demand
            state: unknown
    then:
      - service: input_boolean.turn_off
        data: {}
        target:
          entity_id: input_boolean.rainforest_eagle_error
    alias: If Current Power Demand is available then turn off error
mode: single

well triggers can’t have conditions, so if you build your condition into your template sensor, you have a ‘trigger with a condition’

Thanks for that suggestion!

I was using IF/THEN blocks based on the TriggerID but the automations were triggering a lot, only to hit STOP (all’s good). This allowed me to keep the number of automations lower by one automation being used for one device.

I am still trying to find the balance between AND best organization method for automations / scripts. It seems each blog I follow has a different methodology. Sadly due to the way many of my devices behave scenes have never been successful (Mii Home / Govee go offline for 30-60s each hour).

Is there a Home Assistant “Best Practice” guide?