Index
Le 11 germinal an CCXXX

Compteurs d'eau Kamstrup

Il y a quelque temps, Water-Link mon fournisseur d'eau, a remplacé mon ancien compteur idiot par un nouveau compteur, intelligent celui-ci.

J'ai laissé ça un peu traîner, mais j'aimerais bien maintenant en récupérer les données, mes données, pour en faire des statistiques. À partir de mon compte, qui n'est d'ailleurs pas le mien parce que le contrat ne peut être lié à qu'un seul compte utilisateur (qui aurait pu prévoir que deux personnes habiteraient au même endroit ?!) j'ai bien accès à des données journalières.

Je passe sur le fait que pour y accéder, il faille entrer ses identifiants Water-Link sur un autre site : ondemand.com, avec comme seule indication les mots "Waylay-portal". Il se trouve qu'ondemand.com est un domaine appartenant à SAP, qui est en charge du SSO de Water-Link pour l'authentification pour l'accès à Waylay, une boîte gantoise qui doit gérer les données de compteurs connectés pour le compte de Water-Link.

On arrive ensuite sur une page mal branlée (qui se recharge quand elle perd le focus ? pratique pour le screenshot) mais qui affiche les données jusqu'à hier.

L'API

À partir de là on peut trouver les points d'accès d'une API qui permettent de récupérer les données :

https://water-link-customer-portal.waylay.io/api/devices pour des informations générales sur le compteur, date d'installation, modèle, etc, ainsi que des liens du style "https://api.hydroko4iot.com/devices/DEVICE_ID/gdpr/optout" qui donnent sur une erreur 500. Propre. D'après ce que je comprends, Hydroko fournit des vannes connectées, qui pourraient servir à couper l'eau à distance dans certains cas j'imagine. Il n'y a pas de telle vanne installée chez moi d'où l'erreur 500 probablement.

https://water-link-customer-portal.waylay.io/api/daily?from=2022-03-17&to=2022-03-31 donne le détail de le consommation par jour jusqu'à la veille (on ne peut pas obtenir de données pour la journée en cours, mêmes partielles).

https://water-link-customer-portal.waylay.io/api/yearly?from=2021-03-01&to=2022-03-31, même combat mais par mois.

https://water-link-customer-portal.waylay.io/api/monthly?from=2021-03-01&to=2022-03-31, donne des données plus détaillées que "daily", et aussi par jour.

On note la cohérence entre "daily" et "monthly" qui donnent des informations journalières, et "yearly" des informations mensuelles. Je n'ai pas trouvé de "hourly" ou de "weekly".

Bon, c'est mieux que rien, mais d'une ce n'est pas si facile à récupérer automatiquement à cause de l'authentification complexe (après avoir contacté Water-Link, ils m'ont bien dit que l'API n'était pas publique et qu'ils n'avaient pas encore prévu de système pour s'interfacer avec un autre outil) et de deux ce sont des vieilles données. Moi ce que je veux, c'est connaître au litre près ma consommation d'eau, au moment où je l'utilise.

Le compteur

Puisque l'API ne donne pas les données que je cherche, alors regardons directement du côté du compteur.

Mon compteur est un Kamstrup Multical 21. C'est un petit appareil très bien fichu, la fiche technique est visible ici.

M-BUS

Dans la configuration installée chez moi, ça tourne 16 ans sur une pile au lithium, en envoyant toutes les 96 secondes un message radio contenant la consommation et éventuellement la température de l'eau, température de l'air, débit minimal, maximal, etc.

Tout ça est envoyé avec le protocole M-BUS sur 868 MHz. Comment on fait pour recevoir ce genre de signal ? En fait c'est assez simple, j'ai un vieil adaptateur USB pour capter la TNT, Realtek RTL2832 qui est connu pour pouvoir servir de récepteur radio générique parce qu'il peut être réglé sur une large plage de fréquences, et permet de récupérer les signaux reçus bruts.

Donc armé de ma clé USB TNT et de wmbusmeters qui s'occupe de décoder les messages, j'ai pu rapidement capter les messages des nombreux compteurs autour de chez moi :

Received telegram from: XXXXXXXX
          manufacturer: (KAM) Kamstrup Energi (0x2c2d)
                  type: Cold water meter (0x16) encrypted
                   ver: 0x1b
                device: rtlwmbus[00000001]
                  rssi: 123 dBm
                driver: multical21
Received telegram from: YYYYYYYY
          manufacturer: (KAM) Kamstrup Energi (0x2c2d)
                  type: Cold water meter (0x16) encrypted
                   ver: 0x1b
                device: rtlwmbus[00000001]
                  rssi: 12 dBm
                driver: multical21


et même de compteurs de gaz :

Received telegram from: XXXXXXXX
          manufacturer: (FLO) Flonidan, Denmark (0x198f)
                  type: Gas meter (0x03) encrypted
                   ver: 0x21
                device: rtlwmbus[00000001]
                  rssi: 13 dBm
                driver: unknown!

Malheureusement pour moi dans ce cas particulier, mais heureusement quand même, Water-Link est assez compétent pour avoir choisi de chiffrer les messages. Mais de ne pas me donner la clé publique. C'est de l'AES, donc il n'est pas réaliste de s'y attaquer. La configuration de mon compteur se termine par un 3, ce qui indique (voir page 17 de la documentation) qu'il a une clé unique qui a été communiquée à Water-Link.

Water-Link a bien sûr répondu à côté de la plaque à mon email leur demandant la clé de mon compteur, mais je vais essayer d'insister un peu même si je n'ai pas le moindre espoir d'arriver à quelque chose.

Bricolage

Qu'est-ce qu'il me reste ? Le compteur possède un port de communication infrarouge, mais n'envoie pas d'impulsions par défaut, il faudrait régulièrement communiquer avec pour réactiver ce système qui donne une impulsion pour 10 litres, ce qui est assez peu précis par rapport à l'affichage numérique qui est au litre près.

Contrairement aux anciens compteurs idiots, celui-ci n'a aucune roue ou autre moyen de récupérer facilement des impulsions, il ne me reste plus qu'à lire les chiffres moi-même avec une caméra et un peu de bricolage.

J'ai donc fini par installer un ESP32-CAM flashé avec esphome, plus ou moins bien fixé sur le cul d'un gobelet en plastique blanc. Le goulot du gobelet fait à peu près le même diamètre que le compteur, et la profondeur du gobelet correspond assez bien à la distance qu'il me faut pour que la photo contienne les informations dont j'ai besoin.

Comme la caméra est de bien piètre qualité, je prends en réalité 5 frames dont je fais la moyenne (avec imagemagick -average). Ce n'est pas du vrai stacking, mais c'est déjà pas mal.

Ensuite c'est encore du bricolage imagemagick, je rotate, je croppe (avec des valeurs que je dois ajuster manuellement quand la caméra est déplacée) et puis un -lat 10x10-0.95% vient déterminer ce qui doit être blanc et ce qui doit être noir pour arriver à une image pas trop dégueu. Ce réglage est assez délicat puisque les chiffres sont en noir sur fond gris, donc avec peu de contraste, et que l'éclairage n'est pas uniforme. Je ne prends que les trois derniers chiffres parce qu'ils m'intéressent, et que je n'ai pas besoin du chiffre des milliers de litres qui ne change pas souvent :

Facile à lire pour un humain mais pas trop pour une machine, heureusement il y a ssocr qui est un petit programme d'OCR spécialisé dans la reconnaissance d'affichages à 7 segments, ce qui est mon cas. L'utilisation est assez bien documentée sur le site mais il ne fonctionne pas au moment où j'écris ces lignes.

Dans l'ensemble, les chiffres sont assez bien reconnus même si ce n'est pas toujours parfait.

Je mets tout ça dans le bazar et hop :

Des données de consommation en temps réel ! J'ai testé en me douchant, et ça marche vraiment bien, d'ailleurs ça fait un peu peur de voir la quantité d'eau propre que j'utilise pour me laver. Par contre je ne sais pas encore vraiment quel graphique adopter pour que les données soient faciles à lire, mais je trouverai bien quelque chose.

La prochaine étape, maintenant que j'ai des chiffres corrects et à jour, c'est de les afficher en direct dans la salle de bains. Pour ça, j'ai prévu d'utiliser un thermomètre Xiaomi LYWSD003MMC. J'ai déjà quelques uns de ces thermomètres, dont j'ai flashé le firmware avec un firmware alternatif et que j'utilise comme sondes de température (elles envoient la température en bluetooth low energy).

Le firmware ATC permet aussi d'afficher ce qu'on souhaite à l'écran (ça reste limité à quelques chiffres bien sûr) toujours en bluetooth. Donc c'est la prochaine chose que je tenterai.

@contact