Statut : brouillon, ouvert au débat
Discussion : ce sujet du forum
Salut à tous,
Je vous propose une nouvelle fonctionnalité qui va changer la manière dont les intégrations sont développées dans Gladys.
C’est un projet longuement mûri, et je serais ravi d’avoir vos retours, vos idées et vos remarques pour continuer à l’améliorer ![]()
Pourquoi maintenant
Depuis le début du projet, toutes les intégrations de Gladys vivent dans le core. N’importe qui peut en développer une ou l’améliorer via une pull request, mais chaque ligne passe par ma review avant d’être mergée. Ce choix a un énorme avantage : quand vous installez Gladys, tout est déjà là. Pas de store, pas de dépendances à gérer, pas de plugin cassé après une mise à jour. C’est une des raisons pour lesquelles Gladys est plus simple à prendre en main que d’autres solutions.
Mais ce modèle a un plafond, et je suis en train de le toucher. Il existe des milliers de marques, de protocoles, de services, et la moindre modification d’une intégration, même un simple changement de traduction, doit passer par moi : review, merge, release. Ça ne passe pas à l’échelle, et ça fait de moi le goulot d’étranglement du projet.
On pourrait se dire que Matter va résoudre ce problème. Matter arrive, et va à mon avis devenir le protocole de référence qui contrôlera tous les appareils connectés à l’avenir : un seul standard, tous les appareils compatibles nativement, plus besoin d’une intégration par marque. Sauf qu’on ne sait pas quand cet avenir sera une réalité, et le projet ne peut pas se permettre d’attendre indéfiniment que le parc installé bascule.
Et surtout, Matter ne couvre que le contrôle des appareils connectés. Il reste tout un pan d’intégrations qui n’a rien à voir avec des appareils : la communication (Telegram, etc.), la météo (OpenWeather, Météo France), les calendriers (CalDAV, Google Calendar)… Tout ça ne passera jamais par Matter. Si on veut que Gladys devienne un projet avec la même ambition que Home Assistant, on doit pouvoir permettre l’installation d’intégrations externes.
Cette RFC propose donc d’ouvrir Gladys aux intégrations externes : des intégrations développées et publiées par n’importe qui, sans validation préalable de ma part, installables en un clic depuis l’interface.
Le défi, c’est de faire ça sans sacrifier ce qui fait Gladys. Concrètement, quatre exigences non négociables ont guidé cette proposition :
- Une intégration qui plante ne doit jamais faire planter Gladys.
- Pas d’états incompréhensibles : si une intégration ne répond plus, l’utilisateur doit le voir et pouvoir agir.
- Les interfaces doivent rester propres et cohérentes entre elles.
- Zéro manipulation technique pour l’utilisateur. Pas de terminal, pas de YAML, pas de redémarrage manuel.
Ce que cette RFC ne propose pas
- On ne remplace pas les intégrations natives. Les intégrations des protocoles universels (Matter, Zigbee, Z-Wave…) resteront toujours dans le core, pré-installées, maintenues comme aujourd’hui. Le nouveau système s’ajoute à côté, et vise toutes les intégrations de protocoles ou de services qui ne sont pas universels : désormais, n’importe qui pourra créer une intégration séparée.
- On ne vise pas la compatibilité avec les intégrations Home Assistant / HACS. Elles sont profondément couplées à l’architecture de HA ; les exécuter dans Gladys est irréaliste. En revanche, je m’inspire de leur modèle de distribution (dépôt Git + manifeste + store).
- On ne permet pas aux intégrations d’injecter du code dans l’interface. C’est un choix assumé, détaillé plus bas.
Architecture proposée
Un conteneur Docker par intégration
Gladys tourne déjà exclusivement dans Docker, avec la socket Docker montée. On s’appuie dessus : chaque intégration externe tourne dans son propre conteneur, créé et supervisé par le core Gladys.
Ce conteneur est verrouillé au maximum :
- pas de mode privilégié, pas d’accès à la socket Docker
- pas d’accès à la base de données ni aux fichiers de Gladys
- système de fichiers en lecture seule, sauf un petit répertoire de données qui lui est propre
- limites strictes de mémoire, CPU et nombre de processus
- réseau restreint aux hôtes que l’intégration a déclarés dans son manifeste.
Une intégration qui crashe, qui fuit de la mémoire ou qui part en boucle infinie reste confinée dans sa boîte. Et une intégration malveillante ou mal écrite ne peut pas « aller modifier la base en direct » : le fichier SQLite n’existe tout simplement pas dans son système de fichiers.
Ce choix apporte un bonus important : les intégrations ne sont plus limitées à Node.js. Une image Docker peut contenir du Python, du Go, du Rust. Chaque auteur embarque ses dépendances dans son image, et tout le build est fait en amont, au moment de la publication, jamais au runtime chez l’utilisateur.
À terme, ce choix apporte aussi quelque chose d’intéressant : il sera possible de faire tourner des intégrations déportées !
Toute communication passe par l’API-hôte
Une intégration ne touche jamais les internals de Gladys. Sa seule porte d’entrée est une API-hôte : l’intégration dialogue avec le core via une API REST HTTP JSON toute simple, dans le même esprit que ce qui existe déjà dans Gladys aujourd’hui.
Les primitives envisagées pour la v1 :
- déclarer des appareils et leurs fonctionnalités, dans le modèle device/feature existant de Gladys ;
- publier des états et recevoir des commandes
- stocker sa configuration et ses secrets (stockés en DB côté core)
- écrire des logs structurés
- demander une découverte réseau médiée : c’est le core, qui a accès au réseau de l’hôte, qui effectue les scans mDNS et le passthrough des périphériques USB, puis transmet les résultats. L’intégration n’a ainsi jamais besoin du mode
hostni d’accès matériel direct.
Ce contrat au niveau du protocole est le vrai fondement de la proposition. Le conteneur n’est « que » le mécanisme qui rend ce contrat impossible à contourner. Il permet aussi de faire évoluer le schéma interne de Gladys sans casser l’écosystème : tant que l’API-hôte est stable, les intégrations continuent de fonctionner.
Supervision : pas d’états zombie
Le core embarque un superviseur qui gère le cycle de vie complet de chaque intégration, avec une machine à états toujours visible dans l’interface :
Installée → Démarrage → En fonctionnement → Dégradée → En panne → Arrêtée
Le superviseur envoie un heartbeat régulier à chaque intégration. Pas de réponse ? L’intégration passe en « Dégradée » et est redémarrée automatiquement, avec un délai croissant entre les tentatives. Si elle crashe en boucle, on arrête d’insister : elle passe en « En panne », et l’utilisateur voit un message clair avec les logs de l’intégration et les actions possibles (redémarrer, désactiver, signaler au développeur).
Tous les appels entre le core et l’intégration ont un timeout. Une intégration qui pend ne bloque jamais Gladys.
L’objectif : qu’il n’existe plus aucun état non observable ou non récupérable. Quand quelque chose ne va pas, on le voit, on comprend, on agit, depuis l’interface.
Interface : déclarative, pas de code arbitraire
C’est probablement le choix le plus discutable de cette RFC, donc autant l’assumer clairement.
Les intégrations ne fournissent pas de composants d’interface. Elles décrivent leurs besoins, et c’est Gladys qui rend l’interface avec son propre design system :
- la configuration est décrite par un schéma (type JSON Schema) : Gladys génère le formulaire, la validation, les messages d’erreur, de façon identique pour toutes les intégrations ;
- les appareils sont déclarés dans le modèle device/feature existant : ils s’affichent automatiquement avec les mêmes cartes et les mêmes contrôles que les intégrations natives ;
- pour les besoins plus spécifiques, un vocabulaire de widgets déclaratifs sera défini et enrichi progressivement, en fonction des besoins réels remontés par les développeurs.
Ce que ça coûte : un développeur ne pourra pas créer un écran totalement sur mesure. Ce que ça garantit : une interface cohérente partout, aucune faille XSS venue d’un plugin, aucun conflit de versions front, et une expérience identique pour l’utilisateur quelle que soit l’origine de l’intégration. Vu les priorités du projet, je pense que c’est le bon compromis. Mais c’est exactement le genre de point sur lequel j’attends vos retours.
Distribution : un store dans Gladys
L’utilisateur découvre et installe les intégrations depuis un store intégré à l’interface. Installer = un clic. Le core télécharge l’image, la vérifie, lance le conteneur, affiche le formulaire de configuration si l’intégration a besoin d’identifiants. Aucun terminal, aucun fichier à éditer.
Chaque intégration est publiée avec un manifeste : nom, version, versions de Gladys compatibles, permissions demandées (hôtes réseau, périphériques), schéma de configuration. Les permissions sont affichées à l’utilisateur avant l’installation, comme sur un store mobile.
Toutes les intégrations externes sont « community based » : je ne prévois pas de les relire une par une, ce serait retomber dans le goulot d’étranglement que cette RFC cherche justement à supprimer. Un avertissement clair est affiché à l’installation pour rappeler qu’il s’agit de code tiers non audité. C’est le rôle des permissions déclarées et de l’isolation par conteneur de rendre cette ouverture acceptable.
Développer une intégration à l’ère de l’IA
Un point qui change tout par rapport à il y a quelques années : développer une intégration est devenu très facile grâce à l’IA. Mon intention est de fournir un template d’intégration officiel, propre et documenté. À partir de ce template, avec Claude Code/Cursor, créer une intégration pour un service ou un protocole donné devient l’affaire de quelques heures plutôt que de quelques jours.
C’est ce qui rend cette proposition réellement puissante : au lieu d’attendre que je développe ou que je relise chaque intégration, la communauté pourra en produire beaucoup plus, beaucoup plus vite.
Le rythme d’apparition de nouvelles intégrations ne sera plus limité par ma disponibilité.
Feuille de route proposée
- Définir l’API-hôte et le SDK, puis proposer à quelques développeurs de créer les premières intégrations externes dessus.
- Spécifier le manifeste et le schéma d’interface déclarative.
- Implémenter le superviseur et le lancement de conteneurs verrouillés, en preuve de concept sur une seule intégration.
- Construire le store et le parcours d’installation, avec le template d’intégration officiel.
- Ouvrir la publication à tous.
Mon objectif est de sortir ce nouveau système le plus vite possible : avec les IA, il est possible d’aller très vite.
Je compte commencer le travail dès cette semaine avec Fable 5, tant qu’il est disponible.
Questions ouvertes à la communauté
- Le compromis « UI déclarative uniquement » vous semble-t-il acceptable ? Quels cas d’usage réels ne rentreraient pas dedans ?
- Quelles primitives manquent à l’API-hôte pour vos intégrations rêvées ?
- Faut-il limiter la v1 aux intégrations en Node.js (avec un SDK officiel) pour simplifier, ou ouvrir tous les langages dès le départ ?
Cette proposition est un point de départ, pas une décision gravée dans le marbre : vos critiques, vos objections et vos idées sont exactement ce que j’attends pour la rendre meilleure ![]()

