Intégrer un compteur M-Bus à Home Assistant

Intégrer un compteur M-Bus à Home Assistant

M-Bus (aussi appelé Meter-Bus) est un standard datant des années '90, destiné au relevé de compteurs d'eau et d'électricité. Une variante wireless qui utilise le même codage des données a été définie ultérieurement, mais pour cet article nous allons nous intéresser à la version d'origine, qui permet d'alimenter et de relever jusqu'à 250 compteurs sur 1 km, reliés par une simple paire de fils torsadés.



Objectif du projet

Notre objectif est de mettre en place une solution pérenne pour mesurer différents points de consommation d'eau dans un foyer, afin de pouvoir

  1. mesurer leur importance relative pour mieux cibler les mesures d'économie;
  2. détecter les fuites éventuelles rapidement et efficacement.

Il y a six ans, nous avions montré comment interfacer un compteur d'eau à impulsion. Mais ce type de compteur ne fournit pas une valeur absolue de la consommation totale, et est donc sujet à des erreurs en cas de coupure de courant.

Au contraire, un compteur M-Bus intègre une batterie qui lui permet de fournir un relevé numérique absolu de la consommation totale, même après une coupure d'alimentation électrique. C'est donc une solution plus fiable. Voici le compteur fourni par notre plombier:

Un compteur d'eau avec interface M-Bus
Un compteur d'eau avec interface M-Bus


Il nous faut maintenant trouver comment raccorder ce compteur M-Bus à notre infrastructure MQTT, de sorte à ce qu'il soit disponible dans Home Assistant pour être surveillé en permanence.

M-Bus: principes de transmission

A la base, M-Bus est basé sur une simple transmission série synchrone, comme RS-485. Mais pour permettre aux capteurs de s'alimenter directement par le bus de donnée, sans électronique complexe, M-Bus a opté pour les conventions suivantes:

  • Lorsqu'il ne transmet pas, le maître du bus fournit une tension constante de 36V (état "1").
  • Pour transmettre un bit "0", le maître descend la tension à 24V.
  • Lors qu'il ne transmet pas, un compteur doit consommer un courant constant.
  • Pour transmettre un bit "1", un compteur augmentent sa consommation de 15mA(+-5mA).

Le maître transmet donc ses bits en modulant la tension, alors qu'un compteur transmet ses bits en modulant sa consommation. Le fait d'utiliser des tensions et des courants importants permet de garantir une bonne immunité aux interférences. Pour simplifier l'électronique, quelques règles supplémentaires s'appliquent:

  • Un seul compteur transmet à la fois, et seulement lorsque le maître ne transmet pas.
  • La charge maximale sur le bus est <400mA.
  • La résistance max. du bus est <30 Ohm.
  • Même à la charge maximale, chaque compteur est sûr de recevoir au moins 12V.

La vitesse de communication peut être configurée par l'installateur entre 300 baud et 9600 baud, selon la longueur du bus. M-Bus utilise 8 bits de données, une parité paire et un stop bit (8E1).

Raccorder un bus M-Bus à Home Assistant

Au vu de la description ci-dessus, on ne va pas pouvoir utiliser directement une interface RS-232 ou RS-485 pour communiquer avec des capteurs M-Bus: il faut une électronique dédiée.

Dans l'idéal nous aurions utilisé un Yocto-MBus, mais il n'existe pas: nous n'avons eu à ce jour qu'une demande en ce sens, il y a une dizaine d'années...

Nous aurions éventuellement pu utiliser le M-Bus Master Hat pour Raspberry Pi, mais d'une part ses capacités d'alimentation du bus sont très limitées, et d'autre part nous ne voulons pas complexifier le maintenance de notre système de domotique par l'ajout d'un mini-PC supplémentaire.

Nous avons donc choisi une option un peu plus chère, mais entièrement stateless: la passerelle RS232 vers M-Bus MM20-24, fabriquée par la société DECODE. Nous n'avons pas besoin de la variante Ethernet plus chère, car nous allons raccorder la passerelle directement à un Yocto-RS232, qui se chargera de l'interrogation périodique des compteurs:

Un Yocto-RS232 et une passerelle MM20-24 permettent d'intégrer M-Bus à l'écosystème Yoctopuce
Un Yocto-RS232 et une passerelle MM20-24 permettent d'intégrer M-Bus à l'écosystème Yoctopuce


A partir de là, l'intégration dans Home Assistant pourra se faire via MQTT comme pour l'intégration de la pompe IntelliFlo présentée l'année dernière.

Le chemin complet d'un compteur M-Bus vers Home Assistant
Le chemin complet d'un compteur M-Bus vers Home Assistant


Cette solution de conversion rajoute quelques hops par rapport à ce que pourrait être une intégration native de M-Bus dans Home Assistant, mais elle a l'énorme avantage de faciliter grandement la maintenance du système et la traçabilité des données.

Mais pour que cela fonctionne, il nous faut encore configurer le Yocto-RS232 pour qu'il interroge les compteurs d'eau M-Bus et publie les mesures, de sorte à ce qu'elles soient automatiquement injectées dans l'infrastructure MQTT.

Configuration du Yocto-RS232

La première étape consiste à vérifier que l'on peut communiquer avec les compteurs. Nous allons donc commencer par envoyer des messages codés à la main avec l'interface de test du Yocto-RS232.

Selon le standard M-Bus, tous les compteurs M-Bus doivent répondre au message appelé SND_NKE, qui correspond à un ping. Il est formé de 5 octets, donnés en hexadécimal ci-dessous:

10code "start", présent au début de chaque message envoyé
40octet de contrôle correspondant à la commande SND_NKE
00adresse du compteur à qui le message est destiné
40somme de contrôle = (0x40 + 0x00) modulo 0x100
16code "stop", présent à la fin de chaque message envoyé


La réponse attendue est l'octet E5.

Test de connectivité M-Bus avec un Yocto-RS232
Test de connectivité M-Bus avec un Yocto-RS232


Pour que cela fonctionne, il faut que vous ayez configuré correctement votre Yocto-RS232. Le standard nous dit qu'il s'agit d'un protocole de messages binaires (frame-based binary protocol), transmis en utilisant huit bits de données, un bit de parité paire et un stop bit (8E1). Il est aussi précisé qu'à la sortie d'usine, un compteur devrait répondre à l'adresse 00. Par contre il n'est pas précisé quelle est la vitesse de communication par défaut, donc il faut faire quelques essais entre 300 baud et 9600 baud. Notre capteur nous a répondu lorsque qu'on lui a envoyé le SND_NKE à 2400 baud. Voici donc la configuration de notre Yocto-RS232:

Configuration du Yocto-RS232 pour communiquer en M-Bus
Configuration du Yocto-RS232 pour communiquer en M-Bus


Pour le cas où votre compteur ne répondrait jamais, quelque soit la vitesse de communication, vous pouvez essayer d'utiliser l'adresse FE: elle correspond à un broadcast auquel tous les compteurs doivent répondre, quelle que soit leur adresse. Si on y ajoute la somme de contrôle, le message à envoyer est 10 40 FE 3E 16.

Test d'un relevé de compteur

Pour demander un relevé du compteur 00, il faut envoyer le message REQ_UD2, soit:

10code "start", présent au début de chaque message envoyé
7Boctet de contrôle correspondant à la commande REQ_UD2
00adresse du compteur à qui le message est destiné
7Bsomme de contrôle = (0x7B + 0x00) modulo 0x100
16code "stop", présent à la fin de chaque message envoyé


Le format exact de la réponse est un peu plus compliqué, et il va varier selon le type de compteur. Mais il devrait respecter la structure décrite ci-dessous:

partie fixe
68 C4 C4 68entête RSP_UD, longueur=C4 (dans notre cas)
08 octet de contrôle correspondant à une réponse RSP_UD
00 adresse du compteur qui répond
72 info supplémentaire: 72 = réponse de taille variable
23 42 27 00numéro de série du compteur (format BCD): 00274223
47 5F identification du fabricant = 5F47
03 version du matériel: 03
07 type de compteur: 07 = compteur d'eau
44 40 00 00code d'accès, statut, signature
data block 1
04 variable 0, stockée sur 4 octets (32 bit)
13 unité de mesure: code 13 = 1 litre
E1 28 00 000x28E1 = 10'465 litres
data block 2
04 variable 0, stockée sur 4 octets (32 bit)
6D unité de mesure: timestamp
2B 11 1A 360x361a112b = 2024/06/26 19:49
etc.


Si nécessaire, vous trouverez tous les détails sur ces encodages mystérieux dans la spécification M-Bus, mais autant vous avertir, c'est assez indigeste. Elle a visiblement été rédigée par des automaticiens qui n'ont pas la même conception des structure de données que les informaticiens: c'est un mélange de représentation mélangeant inefficacement stockage et affichage (type BCD), de bits de contrôles avec des noms tous sauf explicites coincés partout là où c'est possible, et de codes arbitraires organisés sans logique apparente... Pour vous facilitez la tâche, vous trouverez:

  • à la page 74, la table des types de compteurs
  • aux pages 38-39, le codage du premier octet du data block, appelé le DIF
  • aux pages 42 et 78, le codage de l'octet du data block qui indique l'unité, appelé le VIF
  • à la page 41, l'explication des octets optionnels DIFE qui sont parfois insérés entre
    le DIF et le VIF; on identifie leur présence au fait que le bit supérieur de l'octet
    précédent est actif (valeur >= 0x80)
  • à la page 72, le format de représentation des dates et des timestamps sur 16 et 32 bits, qui illustre bien la remarque faite précédemment sur les formats de données de M-Bus...

Si vous êtes perdus, vous pouvez toujours envoyer un email à support@yoctopuce.com et on vous aidera.

Interrogation automatique

Une fois que vous avez vérifié que vous pouvez interroger votre compteur et que vous savez où trouver la réponse, vous êtes prêt à créer un job d'interrogation automatique dans le Yocto-RS232.

Si l'on se contente de remonter la valeur du compteur lui-même, le job peut se résumer à une tâche périodique de type custom protocol faite de deux commandes: l'envoi du message REQ_UD2, et la réception de la réponse:

writeHex107B007B16
expect68(WORD)68080072(DWORD)(DWORD)(DWORD)0413($1:DWORDL).*


L'expression expect se comprend comme suit: à la réception d'un message respectant le format attendu, on affecte au genericSensor1 (noté $1) la valeur du mot 32 bit en little-endian (noté DWORDL) à la position donnée. Dans notre cas, le format attendu correspond à l'extraction de la donnée du data block 1.

Si l'on veut faire un peu plus subtil, on peut même calculer directement dans le job le débit par minute, de sorte à ce qu'il puisse aussi être publié via MQTT. Pour cela, on stocke la valeur du compteur dans une variable $prevVal, et on calcule la différence toutes les 60 secondes. Basé sur ce principe, voici le job que nous utilisons pour relever deux compteurs (adresses 01 et 02) en parallèle, et publier le débit (en l/min) et la relevé du compteur (en m^3):

Tâche Init, exécutée une seule fois:
compute$prevTime = 0
compute$prevVal1 = 0
compute$prevVal2 = 0
Tâche Measure, exécutée toutes les 500ms:
compute$currTime = utctime() div 60
assert$currTime != $prevTime
writeHex107B017C16
expect68(WORD)68080172(DWORD)(DWORD)(DWORD)0413($currVal1:DWORDL).*
writeHex107B027D16
expect68(WORD)68080272(DWORD)(DWORD)(DWORD)0413($currVal2:DWORDL).*
compute$6 = $currVal1 / 1000.0
compute$7 = $currVal2 / 1000.0
compute$delta1 = $currVal1 - $prevVal1
compute$delta2 = $currVal2 - $prevVal2
compute$prevTime = $currTime
assert$delta1 != $currVal1 || $delta2 != $currVal2
compute$1 = $delta1
compute$2 = $delta2


Une fois ce job lancé, les mesures apparaissent toutes les minutes dans les fonctions genericSensor correspondantes.

Publication vers MQTT

Pour faciliter la récupération des mesures avec la Discovery MQTT, on a intérêt à indiquer leur nom et l'unité de mesure directement dans la configuration du Yocto-RS232:

Configuration des fonctions genericSensor
Configuration des fonctions genericSensor


Et surtout, pour que les mesures soient envoyées au broker MQTT, il faut activer l'envoi des timed reports pour les fonctions correspondantes, à la fréquence désirée:

Activation des timed reports, fréquence 1/min
Activation des timed reports, fréquence 1/min



Pour connecter votre Yocto-RS232 au broker MQTT, vous pouvez soit le connecter à un YoctoHub-Ethernet, soit le connecter directement au PC de Home Assistant en utilisant VirtualHub. Dans les deux cas, si ce n'est pas encore fait, configurez un callback HTTP de type MQTT vers votre broker MQTT, et si tout a été fait correctement, vous devriez rapidement voir apparaître votre Yocto-RS232 apparaître dans la liste des devices MQTT. Dans ses propriétés, vous découvrirez directement les capteurs que nous avons configurés. Il ne vous reste plus qu'à leur attribuer une jolie icône, et à les ajouter à votre dashboard !

Les capteurs trouvés par la Discovery MQTT
Les capteurs trouvés par la Discovery MQTT


Commenter aucun commentaire Retour au blog












Yoctopuce, get your stuff connected.