feat(watchdog): stale-entity auto-heal — reload, notify, guarded restart [#789]
ci / lint (push) Failing after 14s
ci / lint (push) Failing after 14s
5-min staleness checks on 12 critical entities; reload_config_entry auto-heal (no restart); notify on failure; auto-restart behind input_boolean arm (default OFF). https://projects.knownelement.com/issues/789
This commit is contained in:
@@ -526,3 +526,113 @@
|
||||
back to {{ states(trigger.entity_id) }}°F and holding — was
|
||||
{{ trigger.from_state.state }}°F when the alert cleared (tier fire line {{ fire }}°F).
|
||||
mode: single
|
||||
- id: pfv_watchdog_stale_entities
|
||||
alias: PFV watchdog - stale entity auto-heal
|
||||
description: >
|
||||
Detects silent poller wedges (2026-09-04: snmp tsys9 went 12h
|
||||
undetected; NUT APC 3h) and auto-heals config-entry platforms via
|
||||
homeassistant.reload_config_entry — no restart needed. Escalates to
|
||||
notify when reload does not recover. Auto core restart ONLY while
|
||||
input_boolean.pfv_watchdog_auto_restart is ON and entities stay
|
||||
stale — restart costs ~1 min downtime and re-registers webhooks
|
||||
(#345, #789). v1 notify repeats each cycle while stale (visible
|
||||
alarm); throttle in v2.
|
||||
mode: single
|
||||
max_exceeded: silent
|
||||
triggers:
|
||||
- trigger: time_pattern
|
||||
minutes: /5
|
||||
variables:
|
||||
checks:
|
||||
- [sensor.pfv_tsys1_rack_temperature, 20]
|
||||
- [sensor.pfv_tsys1_drive_temperature, 30]
|
||||
- [sensor.pfv_tsys3_cpu_temperature, 20]
|
||||
- [sensor.pfv_tsys4_ambient_temperature, 20]
|
||||
- [sensor.pfv_tsys6_cpu_temperature, 20]
|
||||
- [sensor.pfv_tsys6_drac_ambient, 30]
|
||||
- [sensor.pfv_tsys7_cpu_temperature, 20]
|
||||
- [sensor.pfv_tsys7_drac_inlet, 30]
|
||||
- [sensor.pfv_tsys9_cpu_temperature, 20]
|
||||
- [sensor.pfv_tsys9_drive_temperature, 30]
|
||||
- [sensor.tsys1_ups_status, 15]
|
||||
- [sensor.tsys1_triplite_status, 15]
|
||||
actions:
|
||||
- variables:
|
||||
stale_list: >-
|
||||
{% set ns = namespace(stale=[]) %}
|
||||
{% for pair in checks %}
|
||||
{% set s = states[pair[0]] %}
|
||||
{% if s is not none and s.last_updated is defined
|
||||
and (now() - s.last_updated).total_seconds() > pair[1] * 60 %}
|
||||
{% set ns.stale = ns.stale + [pair[0]] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.stale }}
|
||||
- condition: template
|
||||
value_template: "{{ stale_list | length > 0 }}"
|
||||
- repeat:
|
||||
for_each: "{{ stale_list }}"
|
||||
sequence:
|
||||
- action: homeassistant.reload_config_entry
|
||||
data:
|
||||
entity_id: "{{ repeat.item }}"
|
||||
- delay:
|
||||
hours: 0
|
||||
minutes: 2
|
||||
seconds: 0
|
||||
- variables:
|
||||
still_stale: >-
|
||||
{% set ns = namespace(stale=[]) %}
|
||||
{% for pair in checks %}
|
||||
{% set s = states[pair[0]] %}
|
||||
{% if s is not none and s.last_updated is defined
|
||||
and (now() - s.last_updated).total_seconds() > pair[1] * 60 %}
|
||||
{% set ns.stale = ns.stale + [pair[0]] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.stale }}
|
||||
- action: notify.send_message
|
||||
target:
|
||||
entity_id:
|
||||
- notify.ultix_sidecar_new
|
||||
- notify.allthes_ipad
|
||||
data:
|
||||
title: WATCHDOG
|
||||
clickAction: /lovelace-pfv-server-room/temps
|
||||
url: /lovelace-pfv-server-room/temps
|
||||
message: >-
|
||||
Stale after auto-reload: {{ still_stale | join(', ') }}.
|
||||
Auto-restart is {{ 'ON' if is_state('input_boolean.pfv_watchdog_auto_restart','on')
|
||||
else 'OFF (arm it on the watchdog switch if you want unattended restarts)' }}.
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: "{{ is_state('input_boolean.pfv_watchdog_auto_restart','on') }}"
|
||||
then:
|
||||
- delay:
|
||||
hours: 0
|
||||
minutes: 30
|
||||
seconds: 0
|
||||
- variables:
|
||||
hard_stale: >-
|
||||
{% set ns = namespace(stale=[]) %}
|
||||
{% for pair in checks %}
|
||||
{% set s = states[pair[0]] %}
|
||||
{% if s is not none and s.last_updated is defined
|
||||
and (now() - s.last_updated).total_seconds() > pair[1] * 60 %}
|
||||
{% set ns.stale = ns.stale + [pair[0]] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{{ ns.stale }}
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: "{{ hard_stale | length > 0 }}"
|
||||
then:
|
||||
- action: notify.send_message
|
||||
target:
|
||||
entity_id:
|
||||
- notify.ultix_sidecar_new
|
||||
- notify.allthes_ipad
|
||||
data:
|
||||
title: WATCHDOG — restarting core
|
||||
message: "Still stale after reload + 30 min: {{ hard_stale | join(', ') }}. Restarting HA core now."
|
||||
- action: homeassistant.restart
|
||||
|
||||
Reference in New Issue
Block a user