Failure mode: automation loop / runaway¶
Séptima entrada del catálogo. Dos automations cuyos triggers se feed mutuamente, o una automation cuya acción dispara su propio trigger. HA loguea WARN pero NO para — el bucle quema CPU, satura logs, y hace que devices Zigbee descubrir "burst rate" suspicious. Catch: pattern matching en logs + circuit breakers explícitos.
Cómo se manifiesta¶
- HA CPU al 100% sostenido.
- Logs Loki: mismo automation ID disparándose >10 veces/segundo.
- Z2M loguea "device commanded too quickly" / "rate limited".
- UX: luces parpadeando, devices ignorando commands legítimos.
- Recorder DB crece a 10× velocidad normal.
Causas comunes¶
| Patrón | Ejemplo |
|---|---|
| Direct circular trigger | Automation A: "if light.on → set switch.on"; Automation B: "if switch.on → set light.on" |
| State echo | Automation: "if motion → toggle light"; el toggle causa state change que dispara otra vez |
| MQTT retain loop | Service publish a topic con retain=true que es trigger de otra automation que publish a su vez |
| Sun + sunset bug | Automation con trigger: sun.sunset y action que modifica zone, recalculando sun events |
| Template entity feedback | Template sensor depende de input_number que la propia automation modifica |
Cómo se detecta proactivamente¶
Pattern matching en Loki¶
# Más de 60 disparos del mismo automation_id en 1 min
sum by (automation_id) (
rate({job="homeassistant"} |= "Executing automation" [1m])
) > 60
Métricas Prometheus¶
HA built-in: automation max setting¶
Cada automation debe tener:
automation:
- alias: My automation
max: 5 # max concurrent instances
max_exceeded: warning # log when limit hit
mode: single # default: skip new while running
mode: single + max: 5 ya previene el runaway. Pero hay que ponerlo explícito en cada automation.
Cómo se recupera (live, mid-loop)¶
Caso A — Detectado pronto (Gatus / agente alerta)¶
- Disable la automation con problema: Settings → Automations → toggle off.
- Pause MQTT publishes si el loop pasa por MQTT.
- Identificar el otro lado del loop (ver triggers).
- Disable también.
- Investigar logs para entender cuál es la circularidad.
- Fix: agregar
conditiondeterministic que rompe el bucle, o restructurar.
Caso B — HA UI no responde (loop saturando CPU)¶
- SSH al host.
ha core stop(HAOS) odocker compose stop homeassistant(Container).- Edit
automations.yamldirectamente — disable la automation conenabled: false. - Restart HA.
- Investigar.
Caso C — DB ya bloated por el loop¶
Ver failure-mode-recorder-db-bloat — purge + VACUUM.
Cómo se previene¶
Convención obligatoria en cada automation¶
Cada automation debe tener:
El multi-agent review de Dan Malone (Architecture Strategist) debe flagear automations sin esto.
Circuit breaker pattern¶
Para automations sensibles, agregar un guard:
automation:
- alias: HVAC adjust
trigger:
- platform: state
entity_id: sensor.outside_temp
condition:
# circuit breaker: max 6 ajustes por hora
- condition: template
value_template: >
{{ states('input_number.hvac_adjustments_this_hour') | int < 6 }}
action:
- service: input_number.increment
target:
entity_id: input_number.hvac_adjustments_this_hour
# ... resto de la action
# ... + un timer que resetea el counter cada hora
Verboso pero salva.
Pre-deployment test¶
Antes de promover una automation nueva al essentials: 1. Deploy al twin. 2. Forzar trigger manual. 3. Verificar count de invocations en 1 min → debería ser 1. 4. Si > 1, hay loop potencial.
Lo que el agente AI hace¶
| Acción | ¿Autónomo? |
|---|---|
| Detectar pattern de loop (>60 invocs/min) | Sí mes 1 |
| Disable la automation con problema | Sí mes 3+ (es recovery, no destructive) |
| Open PR analizando la causa del loop | Sí mes 3+ |
| Fix automático del loop (agregar condition) | No, pide approval (puede romper la intención original) |
Relaciones¶
- Séptima entrada del catálogo.
- Apoya: ../sources/dan-malone-ai-patterns-ha (Architecture Strategist agent detecta esto).
- Apoya: q5-observability-stack-v1 (queries Loki + Prometheus para detection).
Abierto / gaps¶
- Linter ESPHome / HA que detecta loops potenciales antes del deploy.
- Patrón de circuit breaker como template reusable.
- ¿HA tiene built-in protection para circular triggers? Validar.