·VA

Étude de cas

Désagrégation NILM · Linkya

ML · Séries temporelles · Traitement du signal

GitHub

Home Assistant mesure tout ce qu'il voit. Pas le ballon d'eau chaude, câblé direct, sans prise possible. Linkya branche le signal Linky sur un moteur ML : on entraîne à partir de signatures, le modèle détecte sur le signal agrégé et publie dans Home Assistant. L'angle mort se comble.

Rôle
R&D & dev
Stack
Python · TensorFlow · Keras · Seq2Point
Statut
En production
Le problème : les appareils hors de portée

Mon Home Assistant mesure : TV, PC, réfrigérateur, four, box. La consommation est couverte, appareil par appareil, sauf ce qui n'est pas ou ne peut pas être branché sur une prise connectée. 50 % de ma consommation est classée comme « Consommation Non Suivie ».

Le ballon d'eau chaude est un suspect typique : branché directement au mur, impossible d'y glisser une prise intelligente. Il tourne plusieurs fois par jour, consommant quelques kWh à chaque chauffe. C'est probablement mon premier poste de dépense après le chauffage en hiver et je ne le mesure pas.

L'approche Linkya

Le NILM pour Non-Intrusive Load Monitoring : déduire la consommation de chaque appareil à partir du seul signal agrégé du compteur.

Soyons honnêtes : je n'étais pas spécialiste ML avant ce projet. Je l'ai défriché en binôme avec l'IA, sans renier la rigueur qui rend le résultat fiable. Travailler avec l'IA →

Sous le capot, Linkya implémente un modèle Seq2Point sur architecture LSTM/GRU avec mécanisme d'attention.

On n'a rien compris, alors plus simplement :
Seq2Point : on donne au modèle une séquence (une fenêtre de quelques minutes du signal global) et il répond par un seul point : la puissance de l'appareil à l'instant situé au milieu de cette fenêtre.
LSTM / GRU : des mémoires courtes. Le modèle se souvient de ce qui s'est passé juste avant : c'est utile car une chauffe c'est une montée puis un palier puis une descente : c'est l'enchaînement qui fait la signature.
Attention : un projecteur. Le modèle apprend à se concentrer sur les moments qui comptent et à ignorer le reste.

En clair : imaginez une oreille qui apprend à reconnaître la voix d'une personne dans le brouhaha d'une foule. Le compteur Linky « entend » toute la maison d'un coup. On montre au modèle à quoi ressemble le ballon quand il fonctionne et il apprend à la repérer même quand d'autres équipements consomment en même temps.

Linkya en action
Interface Linkya : appareils, courbe de consommation Linky annotée avec les signatures et détections.
Interface Linkya : appareils, courbe de consommation Linky annotée avec les signatures et détections.

Côté UX/UI, je voulais quelque chose de simple à utiliser : on visualise le signal global Linky des N derniers jours, on zoome et se déplace facilement dans la courbe afin de repérer les plages de fonctionnement d'un appareil : un pic de puissance régulier, une heure de démarrage planifié (heures creuses pour le chauffe-eau).

On surligne sur la courbe et on les affecte à l'appareil désiré.

Interface Linkya : sélection d'une plage sur la courbe de consommation.
On sélectionne directement sur la courbe les périodes caractéristiques de l'appareil. Quelques clics suffisent pour créer une signature et l'affecter à l'appareil.

Après quelques signatures enregistrées, on entraîne le modèle à reconnaître ces empreintes dans le bruit du signal agrégé.

Affinage et détections négatives

On peut ensuite tester la détection sur le reste de la courbe et affiner les signatures si nécessaire.

Une détection correcte peut être validée par l'utilisateur et transformée en une signature « positive » pour le modèle : il apprend ainsi à mieux reconnaître l'appareil dans le signal Linky.

Une mauvaise détection peut être invalidée par l'utilisateur et transformée en une signature « négative » pour le modèle : il apprend ainsi à ne pas confondre le ballon avec un autre appareil.

Interface Linkya : une détection erronée annotée comme signature négative.
Une mauvaise détection devient un contre-exemple : le modèle apprend de ses erreurs.

Une fois le modèle satisfaisant et l'option activée, Linkya détecte en continu et publie l'état de l'appareil directement dans Home Assistant via MQTT.

En direct
NILM · Modèle Linkya entraîné Dernière détection Chauffe-eau le
Ce qui marche
Chauffe-eau détecté

L'angle mort est réduit : activations, consommation estimée, plages horaires. L'entité apparaît dans Home Assistant comme n'importe quel autre appareil.

La consommation d'un appareil non connecté est maintenant attribuée.

Zéro capteur additionnel

Tout repose sur le signal du compteur déjà capté. Pas de nouveau matériel, pas de câblage.

Confiance mesurée

Chaque détection est scorée contre les signatures de référence. La confiance moyenne sur 30 jours est visible en live.

Ce qui marche moins bien
Les signatures complexes.

Mon premier test se voulait basique : un chauffe-eau avec une signature simple (un gros palier de puissance pendant plusieurs minutes).

Les appareils avec des cycles plus complexes et variables (lave-linge, lave-vaisselle, four, plaques cuisson) sont plus difficiles à détecter. Le modèle a besoin de plus de signatures pour atteindre un détection stable.

Les appareils identiques.

Par exemple avec le même modèle de radiateur électrique dans des chambres et un bureau : même signature électrique. Le modèle voit bien qu'un radiateur est actif, mais ne peut pas deviner lequel.

C'est le vrai mur du NILM en général, pas un bug Linkya : une contrainte physique d'un signal agrégé.

Où ça tourne

Linkya n'est pas un projet à part : c'est une des applications déployées sur mon infra self-hosted aux côtés de Home Assistant et de ce site que tu parcours actuellement.

Même Raspberry Pi, même socle Docker Compose que le reste. Linkya est une application de plus derrière la porte d'entrée unique.

Voir l'infra →

Références