Helpers Home Assistant : 3 patterns pour des automatisations qui ne se battent plus entre elles
Une automatisation qui éteint la lumière à 23h, et un interrupteur mural qui la rallume juste après parce qu’un humain était encore dans la pièce. Une automatisation “mode nuit” et une automatisation “mode absent” qui s’activent en même temps et se contredisent. Un seuil de luminosité codé en dur dans une automatisation, qu’il faut rouvrir et modifier en YAML chaque fois qu’on veut l’ajuster de dix lux. Ce ne sont pas des bugs de Home Assistant — c’est l’absence d’un état partagé entre les automatisations. Les helpers (input_boolean, input_select, input_number, timer…) sont la brique qui résout exactement ça : une mémoire que plusieurs automatisations peuvent lire et écrire, sans dépendre les unes des autres.
Ce que sont les helpers
Un helper est une entité virtuelle, sans capteur ni appareil physique derrière, que Home Assistant garde en mémoire et expose comme n’importe quelle autre entité : état, historique, carte sur le dashboard, utilisable dans un déclencheur, une condition ou une action. Ils se créent sans YAML, depuis Paramètres → Appareils et services → Helpers, bouton “Ajouter un helper”. Les types utiles pour des automatisations (par opposition aux helpers purement calculés comme Min/Max ou Statistiques) sont au nombre de quatre :
- Interrupteur (
input_boolean) — un booléen on/off - Nombre (
input_number) — une valeur numérique bornée (min, max, pas) - Liste déroulante (
input_select) — une valeur parmi une liste d’options fixes - Minuteur (
timer) — un compte à rebours qui déclenche un événement à expiration
La différence avec une variable dans un script Python ou un template Jinja : un helper persiste après un redémarrage, a un historique consultable dans Lovelace, et surtout peut être lu et modifié par n’importe quelle automatisation du système — pas seulement celle qui l’a créé. C’est cette propriété qui permet les trois patterns suivants.
Pattern 1 : le verrou manuel, pour que l’automatique n’écrase pas l’humain
Le bug classique : une automatisation éteint une lumière après X minutes d’inactivité, mais un humain la rallume manuellement et l’automatisation l’éteint à nouveau dix minutes plus tard, en pleine conversation. La solution n’est pas de désactiver l’automatisation — c’est de lui donner une condition qui respecte l’intervention manuelle.
# Helper : input_boolean.verrou_salon (créé via l'UI)
automation:
- alias: "Verrou salon - activation sur action manuelle"
trigger:
- trigger: state
entity_id: light.salon
to: "on"
# ignore les changements déclenchés par une automatisation
# (contexte différent de celui d'un interrupteur physique)
condition:
- condition: template
value_template: "{{ trigger.to_state.context.parent_id is none }}"
action:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.verrou_salon
- action: timer.start
target:
entity_id: timer.verrou_salon
data:
duration: "02:00:00"
- alias: "Extinction automatique salon"
trigger:
- trigger: time
at: "23:00:00"
condition:
- condition: state
entity_id: input_boolean.verrou_salon
state: "off"
action:
- action: light.turn_off
target:
entity_id: light.salon
- alias: "Verrou salon - fin"
trigger:
- trigger: event
event_type: timer.finished
event_data:
entity_id: timer.verrou_salon
action:
- action: input_boolean.turn_off
target:
entity_id: input_boolean.verrou_salon
Le timer est la partie qui fait la différence avec un simple input_boolean : sans lui, le verrou reste actif indéfiniment jusqu’à ce que quelqu’un l’éteigne manuellement, et l’automatisation “intelligente” finit désactivée en silence pendant des semaines. Le timer.finished relâche le verrou tout seul après deux heures. Le value_template sur context.parent_id filtre les changements d’état provoqués par une automatisation (qui ont un parent_id) pour ne garder que les actions humaines — un détail qui évite que le verrou se réarme lui-même en boucle.
Pattern 2 : la machine à états avec input_select, contre l’explosion de booléens
Un piège fréquent : empiler des input_boolean indépendants — mode_nuit, mode_absent, mode_vacances, mode_invites — pour représenter l’état de la maison. Rien n’empêche techniquement mode_nuit et mode_absent d’être actifs en même temps, et chaque nouvelle automatisation doit vérifier l’état de tous les booléens existants pour ne pas entrer en conflit. Un input_select à options exclusives élimine le problème à la racine : un seul état possible à la fois.
# Helper : input_select.mode_maison
# Options : Jour, Nuit, Absence, Vacances, Soiree
automation:
- alias: "Transition vers mode Absence"
trigger:
- trigger: state
entity_id: group.presence
to: "not_home"
for: "00:10:00"
condition:
- condition: state
entity_id: input_select.mode_maison
state: "Jour"
action:
- action: input_select.select_option
target:
entity_id: input_select.mode_maison
data:
option: "Absence"
- alias: "Actions du mode Absence"
trigger:
- trigger: state
entity_id: input_select.mode_maison
to: "Absence"
action:
- action: climate.set_temperature
target:
entity_id: climate.salon
data:
temperature: 16
- action: light.turn_off
entity_id: all
La logique se lit : une automatisation par transition (qui a le droit de passer de quel état à quel état) et une automatisation par état (que faire une fois dans cet état). Ça sépare proprement “quand on change de mode” de “ce que fait chaque mode” — et ça évite d’avoir à récrire toutes les conditions quand on ajoute un cinquième mode plus tard. C’est le même principe qu’une machine à états finis en programmation, appliqué sans ligne de code.
Pattern 3 : seuils externalisés et anti-rebond avec input_number
Un seuil codé en dur ({% if states('sensor.luminosite')|float < 50 %}) oblige à rouvrir l’automatisation en YAML pour l’ajuster. Un input_number sur le dashboard permet de le régler depuis le téléphone, sans toucher à la config — et sert aussi de mémoire pour un anti-rebond, en combinant un input_datetime qui stocke l’horodatage du dernier déclenchement :
# Helpers : input_number.seuil_luminosite (0-200, pas de 5)
# input_datetime.dernier_declenchement_volet
automation:
- alias: "Fermeture volet si luminosité basse"
trigger:
- trigger: numeric_state
entity_id: sensor.luminosite_salon
below: input_number.seuil_luminosite
condition:
- condition: template
value_template: >
{{ (now() - states('input_datetime.dernier_declenchement_volet')
| as_datetime | as_local).total_seconds() > 600 }}
action:
- action: cover.close_cover
target:
entity_id: cover.volet_salon
- action: input_datetime.set_datetime
target:
entity_id: input_datetime.dernier_declenchement_volet
data:
timestamp: "{{ now().timestamp() }}"
Le below: input_number.seuil_luminosite dans le déclencheur accepte directement l’entity_id d’un helper numérique depuis les versions récentes de Home Assistant — pas besoin de dupliquer la condition. L’input_datetime en condition empêche l’automatisation de se redéclencher à chaque petite fluctuation du capteur de luminosité pendant les dix minutes qui suivent une fermeture.
+ Les points forts
- Zéro YAML pour la création — tous les helpers se créent et se renomment depuis l’UI, seule la logique des automatisations qui les utilisent demande d’écrire des conditions/actions
- État partagé entre automatisations — contrairement à une variable locale à un script, un helper est lisible et modifiable par n’importe quelle automatisation, carte Lovelace ou script
- Persistant et historisé — l’état survit à un redémarrage et son historique est consultable comme un capteur classique
- Combinable avec Assist — un
input_booleanouinput_selectexposé à Assist devient contrôlable à la voix ou en langage naturel par un LLM, ce qui transforme un mode manuel en commande vocale sans code supplémentaire
- Les points faibles
- Pas de garde-fou contre les conflits d’écriture — rien n’empêche deux automatisations différentes de modifier le même
input_selecten même temps ; la discipline (une automatisation par transition) doit être tenue par celui qui écrit la config, Home Assistant ne l’impose pas - Prolifération d’entités — chaque helper est une entité de plus à ranger, nommer et documenter ; sur une installation avec beaucoup d’automatisations avancées, la liste peut vite devenir illisible sans convention de nommage stricte
- Pas de versioning natif — la valeur d’un helper n’est pas dans un fichier YAML suivi par git, contrairement à la logique des automatisations ; un changement de seuil depuis le dashboard ne laisse aucune trace dans l’historique de config
- Logique éclatée entre plusieurs automatisations — le pattern machine à états est propre sur le papier, mais relire “que fait le mode Absence” demande de retrouver toutes les automatisations qui réagissent à cet état, pas un seul fichier centralisé
Comparaison : helpers vs alternatives pour la logique d’état
| Helpers natifs | Node-RED | pyscript / AppDaemon | |
|---|---|---|---|
| Courbe d’apprentissage | Faible — UI + YAML basique | Moyenne — flow-based | Élevée — Python |
| Où vit la logique | Éclatée entre automatisations | Centralisée dans un flow | Centralisée dans un fichier |
| Debug | Historique d’entité, logbook | Debug node intégré | Logs Python classiques |
| Versioning git | Non (sauf export manuel YAML) | Export JSON possible | Natif (fichiers .py) |
| Overhead d’installation | Aucun, inclus dans le core | Add-on à installer | Intégration tierce à installer |
Pour des cas simples à moyens — verrou, mode maison, seuil ajustable — les helpers natifs suffisent et évitent une dépendance supplémentaire. Au-delà d’une dizaine d’automatisations interdépendantes, Node-RED ou pyscript deviennent plus faciles à auditer qu’une toile d’automatisations qui se déclenchent les unes les autres.
En résumé
Les helpers ne sont pas un gadget de dashboard : utilisés comme verrou, comme machine à états ou comme seuil externalisé, ils remplacent une bonne partie de ce qui pousserait sinon à écrire un script Python ou à installer Node-RED. La limite arrive quand le nombre d’automatisations interdépendantes grossit — à partir d’un certain seuil, la logique éclatée entre dix automatisations devient plus dure à suivre qu’un seul fichier de règles centralisé.
Voir aussi :
- Construire un assistant IA personnel avec Home Assistant Assist et un LLM — exposer ces helpers à Assist pour les piloter à la voix ou en langage naturel
- Recycler un vieux mini PC en serveur Home Assistant — installer le serveur Home Assistant qui fera tourner ces automatisations