My Habita Installer

Fonctions

Automatisations

Déclencheurs, conditions, actions, scripts et garde-fous.

Les automatisations s'exécutent dans le moteur, pas dans le navigateur. Trois niveaux, un même format :

  1. Recettes : formulaires guidés (lumière sur présence, extinction sans présence, éclairage horaire, mode nuit, fenêtre ouverte et chauffage, mode absence, batterie faible, appareil indisponible). L'automatisation produite reste visible et modifiable.
  2. Éditeur visuel : « Quand… → Et si… → Alors… », fait de blocs dépliables (voir plus bas).
  3. Mode avancé : définition JSON complète, plus l'action script (JavaScript isolé).

La page Automatisations a trois onglets : Automatisations, Scripts (suites d'actions réutilisables, lancées à la demande) et Variables (entités virtuelles). Sur le téléphone, l'application propose les mêmes onglets et un éditeur simplifié (les blocs essentiels) ; l'éditeur complet reste accessible depuis le téléphone et l'ordinateur.

L'éditeur visuel

Chaque déclencheur, condition ou action est une ligne qui se lit comme une phrase (« Quand « Détecteur du couloir » détecte un mouvement »). En la dépliant on règle le bloc, avec une courte explication et un lien « En savoir plus » (fonctionnement, ce avec quoi il marche, exemples). Le menu « ⋮ » de chaque bloc permet de le renommer, le dupliquer, le désactiver (il reste en place mais est ignoré, sans erreur bloquante), le déplacer (ou le glisser par sa poignée) et le supprimer. Les erreurs du moteur s'affichent sur le bloc concerné.

« Ajouter… » ouvre un sélecteur : catégories (Appareils, Heure et soleil, Variables, Maison et sécurité, Logique, Déroulement…), recherche, et pour chaque bloc ce qu'il fait, son comportement, ce avec quoi il fonctionne et des exemples. Les blocs inutilisables dans la maison (pas de caméra, pas de position…) sont signalés. Des modèles préremplis facilitent les cas courants : « Un mouvement est détecté », « Une porte ou une fenêtre s'ouvre », « Un bouton virtuel est appuyé », « Un minuteur se termine », « À l'heure d'une variable », « Une variable a une valeur », « Mémoriser / rétablir l'état d'appareils », « Lancer un script ».

Le catalogue des blocs (textes compris) est dans packages/shared/src/automation-catalog.ts et servi par GET /api/v1/automations/catalog (le téléphone l'utilise).

Variables (entités virtuelles)

Une variable est une entité créée par vous, sans appareil. Elle a une valeur, apparaît avec les appareils, se place sur les tableaux de bord, se commande depuis le téléphone, a un historique, et sert de déclencheur, de condition ou de cible. Sa valeur est gardée après un redémarrage (sauf si l'on choisit « revenir à la valeur initiale »).

Sorte Valeur Exemple
Interrupteur virtuel oui / non « Mode invités », « Vacances »
Nombre réglable nombre (min, max, pas, unité) seuil de luminosité réglable depuis le téléphone
Compteur entier (+1, −1, remise à zéro) passages de la porte d'entrée
Liste de choix un choix parmi une liste « Ambiance : Calme, Film, Repas »
Texte texte (avec valeurs du moment) « Dernière ouverture : garage à 18:42 »
Heure HH:MM heure du réveil (déclencheur « À l'heure d'une variable »)
Minuteur arrêté / en cours / en pause, temps restant éteindre 10 min après le dernier mouvement ; continue après un redémarrage
Bouton virtuel appui bouton « Je pars » d'un tableau qui lance plusieurs automatisations
Valeur calculée au moins une, toutes, nombre, minimum, maximum, moyenne, somme, médiane, écart « une fenêtre est ouverte », température moyenne de l'étage

L'action Modifier une variable (helper) donne une valeur, inverse, augmente, diminue, remet à la valeur initiale, passe au choix suivant, démarre / met en pause / annule un minuteur, appuie sur un bouton virtuel. La valeur donnée peut être fixe, celle d'une autre entité, une information du déclencheur, une variable locale, ou un texte avec des modèles ({{trigger.entity}}, {{time}}…).

API : GET/POST /api/v1/helpers, PUT/DELETE /api/v1/helpers/:id, POST /api/v1/helpers/apply ({ entityId, op, value?, amount?, durationS? }, permission « commander les appareils »).

Mémoires d'états : l'action « Mémoriser l'état d'appareils » enregistre sous un nom l'état de lumières, volets, thermostats… (marche, luminosité, couleur, position, consigne ; jamais les serrures ni l'alarme) ; « Rétablir un état mémorisé » renvoie seulement ce qui a changé (une lumière éteinte n'est qu'éteinte). Les mémoires survivent aux redémarrages (GET /api/v1/helpers/memories).

Scripts

Un script est une automatisation de sorte script : une suite d'actions lancée à la demande (bouton de tableau, téléphone, « Lancer », autre automatisation avec « Lancer un script »), sans déclencheur obligatoire. Il peut déclarer des champs (nombre, texte, oui / non, entité, liste) demandés au lancement, avec valeur par défaut et caractère obligatoire ; dans ses actions, un champ s'utilise comme une variable locale portant son identifiant ({ "var": "fois" }, {{var.fois}}). Par défaut, l'automatisation qui lance un script attend sa fin ("wait": false pour ne pas attendre).

Chaque automatisation dispose de :

  • une explication en français, générée par le moteur (« Quand … détecte un mouvement, si … est inférieure à 30 lx : allumer … ») ;
  • une validation avant activation, qui distingue les erreurs (bloquantes) des avertissements (risque de boucle, conflit avec le chauffage, conflit avec une autre automatisation) ;
  • un test : « Tester (simulation) » évalue les conditions maintenant et décrit ce qui serait fait sans rien envoyer, tandis que « Exécuter » lance réellement ;
  • des traces : déclencheur, conditions évaluées avec leurs valeurs, actions, et résultat confirmé ou non de chaque commande.

Déclencheurs

Type Exemple
state une entité change, éventuellement vers une valeur précise, pendant une durée minimale (forS)
numeric une mesure franchit un seuil (au-dessus et/ou en dessous), éventuellement pendant une durée
time à une heure (at), ou à l'heure contenue dans une variable « Heure » (entityId), certains jours ; recalculé dès que la variable change
sun lever ou coucher du soleil, avec décalage (position de la maison requise)
interval toutes les N minutes
availability un appareil (ou n'importe lequel) devient indisponible ou disponible, pendant une durée
battery la batterie d'un appareil passe sous un seuil
home_mode, alarm, manual, startup changement de mode, événement d'alarme, lancement manuel, démarrage du moteur

Chaque déclencheur peut porter un identifiant (id), testable par la condition trigger. Exemple : un déclencheur « allumage » et un déclencheur « extinction » dans la même automatisation.

Tous les blocs (déclencheurs, conditions, actions) acceptent alias (nom affiché à la place de la description automatique), enabled: false (bloc ignoré : une condition désactivée est considérée vraie, une action désactivée est notée « ignorée » dans la trace) et preset (modèle du catalogue qui l'a créé, pour l'éditeur).

Conditions

state (avec « depuis au moins N s »), numeric, time (plages qui passent minuit acceptées, jours), sun (jour ou nuit), home_mode, alarm_mode, available, variable (variable locale), compare, trigger, et les combinaisons and, or, not. Une entité indisponible rend la condition fausse.

compare compare deux valeurs quelconques (left, right) avec eq, ne, gt, gte, lt, lte, contains, et un écart facultatif ajouté à droite (offset) : « la température intérieure est supérieure à la température extérieure + 2 », « la luminosité est inférieure à la variable Seuil ». Les nombres se comparent comme des nombres, les heures « HH:MM » entre elles, le reste comme du texte sans tenir compte des majuscules.

Valeurs lues à l'exécution (dans compare, command, helper, variable, les champs d'un script) : une valeur fixe, { "entity": "ent_…", "capability": "…" } (valeur actuelle d'une entité ou d'une variable), { "trigger": "value" | "from" | "to" | "entity" | "device" | "label" }, ou { "var": "nom" } (variable locale ou champ du script).

Actions

command (cible : entités, ou pièces et domaine ; plusieurs capacités ; transition), scene, delay, wait (attendre une condition, avec délai maximal), if / else, choose (selon le cas : plusieurs cas avec leurs conditions, le premier vrai est exécuté, sinon default), repeat (un nombre de fois, tant que, jusqu'à ce que, ou pour chaque entité d'une liste avec les variables locales repeat_item et repeat_index ; 1000 passages au plus), notify (avec modèles {{trigger.entity}}, {{trigger.value}}, {{trigger.device}}, {{entity:ent_…}}, {{var.nom}}, {{now}}, {{time}}, {{date}}), variable (variable locale), helper (modifier une variable), snapshot (mémoriser / rétablir), log (note dans la trace), home_mode, alarm, camera, heating, kiosk, media (lire un contenu sur des enceintes ou une zone, pause, reprendre, arrêter, suivant, précédent, volume : voir multimedia.md), automation (lancer avec des valeurs pour les champs d'un script, activer, désactiver, basculer, arrêter ses exécutions en cours), parallel, script, stop.

Une commande attend la confirmation de l'équipement (20 s au plus) et l'inscrit dans la trace. Par défaut, l'exécution continue en cas d'échec ; l'option continueOnError: false l'arrête.

Concurrence

Mode Comportement si l'automatisation se redéclenche pendant son exécution
single Le nouveau déclenchement est ignoré (et noté dans la trace en cours)
restart L'exécution en cours est annulée, une nouvelle commence. Idéal pour « éteindre après N minutes sans mouvement ».
queued Mise en file d'attente (10 au plus)
parallel Exécutions simultanées (10 au plus)

Garde-fous

  • Boucles : chaque changement d'état porte la chaîne des automatisations qui l'ont provoqué. Une automatisation ne peut pas être redéclenchée par ses propres effets, même indirectement (A → B → A). La profondeur maximale est de 6. Un blocage est tracé et notifié.
  • Fréquence : 20 exécutions par minute par défaut (réglable). Au-delà, les déclenchements sont bloqués pendant la minute. Si cela dure 3 minutes de suite, l'automatisation est désactivée et vous êtes prévenu.
  • Durée : 6 h par défaut (réglable).

Redémarrage du moteur

Les attentes de plus de 5 s (delay, wait) et les durées des déclencheurs (« pendant 10 min ») sont enregistrées. Au redémarrage, chaque attente applique sa politique :

Politique (onRestart) Effet
resume (par défaut) La suite est exécutée, même en retard. Adapté aux extinctions et aux retours à la normale.
expire Reprise si l'échéance n'est pas dépassée de plus de 60 s, sinon abandon tracé (« expirée »). Adapté à ce qui n'a plus de sens en retard.
cancel Abandon.

Une automatisation modifiée entre-temps n'est pas reprise. Les déclencheurs « pendant N s » sont repris si la condition est toujours vraie ; ils sont rattrapés au plus 1 h après leur échéance. Les attentes situées dans une branche parallel ou dans un repeat ne sont pas reprises (celles d'un choose le sont). Un minuteur (variable) arrivé à échéance pendant l'arrêt se termine au démarrage, et les automatisations qui écoutent sa fin sont lancées. Les déclencheurs horaires manqués pendant un arrêt ne sont pas rattrapés.

Code JavaScript (mode avancé)

L'action script exécute du JavaScript dans un bac à sable QuickJS (WebAssembly), avec :

  • aucun accès au système, au réseau ni aux fichiers ;
  • 16 Mo de mémoire au plus ;
  • une durée limitée (1 s par défaut, 10 s au maximum) et une pile limitée.

L'API disponible : state(id), value(id, capacité?), command(id, { capacité: valeur }), notify(titre, message), log(…), les objets vars, trigger et now. Les commandes demandées sont exécutées après le script, avec les contrôles habituels (validation des valeurs, traces). Seuls les administrateurs peuvent écrire des automatisations.

// Allumer la prise si la température dépasse 26 °C, et mémoriser le maximum du jour
const t = value('ent_xxxx');                 // capteur de température
if (t > 26) command('ent_yyyy', { on: true });
vars.max = Math.max(vars.max ?? 0, t);

Format (extrait)

{
  "name": "Lumière du couloir la nuit",
  "enabled": true,
  "mode": "restart",
  "triggers": [{ "type": "state", "entityId": "ent_motion", "to": true }],
  "conditions": [{ "type": "sun", "when": "night" }],
  "actions": [
    { "type": "command", "target": { "entities": ["ent_lampe"] }, "set": { "on": true, "brightness": 20 } },
    { "type": "wait", "until": { "type": "state", "entityId": "ent_motion", "value": false }, "timeoutS": 3600, "onRestart": "resume" },
    { "type": "delay", "seconds": 120, "onRestart": "resume" },
    { "type": "command", "target": { "entities": ["ent_lampe"] }, "set": { "on": false } }
  ],
  "origin": { "kind": "advanced" }
}

Le schéma complet est dans packages/shared/src/automation.ts (types TypeScript et schémas Zod).

Boutons des tableaux de bord

Un bouton (tableaux du site et de l'application) est simple (chaque appui fait l'action) ou bascule (il montre un état allumé / éteint et alterne). Actions possibles : allumer / éteindre ou régler un appareil, scène, lancer un script (avec ses champs), automatisation : lancer, activer, désactiver, basculer, arrêter, modifier une variable, mode de la maison (et, dans l'application, ouvrir une fiche ou un écran).

Pour un bouton bascule, l'état est déduit de l'action (automatisation activée, variable à oui, minuteur en cours, mode de la maison…) ou choisi (état d'une entité, d'une automatisation, d'un mode) ; l'action d'extinction est l'inverse de l'action (désactiver pour activer, mettre à non…) ou une autre action choisie. Textes et icône de l'état allumé sont réglables. Activer ou désactiver une automatisation demande la permission automations.toggle (administrateurs et utilisateurs).