tous les articles

APEX #4 — MQTT, Node-RED, API REST : l'automate qui regardait passer les poissons

21 octobre 2026 · 6 min

#distech-controls,#eclypse-apex,#node-red,#bacnet,#api-rest,#mqtt,#zigbee,#serie-apex

Série ECLYPSE APEX — épisode 4/6 · Précédent : #3 Zigbee2MQTT

On y est. Vos données arrivent gentiment dans le broker MQTT. Et pendant ce temps-là, l’automate regarde tout ça passer comme un chat devant un aquarium. Il voit les poissons. Il ne peut pas les attraper. C’est beau, dans le genre pathétique.

Un chat robot devant un aquarium MQTT où nagent des poissons de données, à côté d'un ECLYPSE APEX sur son rail DIN

Rappelez-vous l’épisode 1 : le MQTT embarqué des ECLYPSE ne sait que publier. Pas d’abonnement. Un client MQTT qui n’écoute pas, c’est un standardiste sans oreilles. Alors on contourne, avec Node-RED et l’API REST de l’APEX.

Logo Node-RED

Ceci n’est pas un tuto

Soyons clairs tout de suite : ici, pas de « copiez-collez et ça marche chez vous ». Je vous raconte ce que j’ai monté, ce qui a tenu sur mon banc de test avec un SONOFF ZBMINIR2, et ce qui m’a fait perdre mes soirées. Votre source, vos noms de points, vos plages d’instances, votre façon de ranger les choses : c’est à vous de les adapter. Les pistes sont là, le reste, c’est votre métier.

Et puisqu’on en parle : Zigbee n’est qu’un exemple. Ce qui compte, c’est la mécanique, et elle tient en une ligne :

MQTT en entrée → Node-RED au milieu → API REST de l’APEX → objets BACnet bien réels au bout.

Zigbee2MQTT, c’est juste ce que j’avais sous la main. Remplacez-le par un capteur LoRaWAN, un ESP32 bricolé dans le garage, ou n’importe quoi qui sait publier en MQTT. Seule la partie « découverte » change.

Rendons à César, et filez voir chez lui

Avant d’aller plus loin, un détour obligatoire : Sylvain Montagny a déjà abattu un gros morceau côté LoRaWAN. Son projet LoRaBAC est un pont LoRaWAN ↔ BACnet open source (licence MIT), sous Node-RED, qui marche dans les deux sens (uplink et downlink), avec ChirpStack, Actility ou The Things Stack, et qui sait parler BACnet natif comme à l’API REST de Distech.

On a bossé sur des sujets voisins presque en même temps, chacun dans son coin. Lui décrit chaque type d’appareil dans un JSON et assume que ce n’est pas du plug and play, c’est écrit dans son README. Moi je suis parti de l’autre bout : créer les points tout seul à partir de ce que l’appareil annonce. Deux approches, deux philosophies. Je ne vais pas refaire sa doc, elle est meilleure que mon résumé : allez la lire.

La brique de base : Node-RED dans un conteneur

Voilà le JSON que l’OPA a bien voulu avaler.

{
  "Image": "nodered/node-red:4.0",
  "ExposedPorts": { "1880/tcp": {} },
  "HostConfig": {
    "CpusetCpus": "0",
    "RestartPolicy": { "Name": "unless-stopped", "MaximumRetryCount": 0 },
    "PortBindings": { "1880/tcp": [{ "HostPort": "50080" }] },
    "Mounts": [
      { "Target": "/data", "Source": "nodered-data", "Type": "volume", "ReadOnly": false, "Consistency": "default" }
    ]
  }
}

Le port hôte doit être 50080. J’ai essayé 50880, l’OPA a dit non, sans un mot d’explication, comme d’habitude. Le volume /data garde vos flows entre deux redémarrages. Interface sur http://IP_APEX:50080, et protégez l’éditeur avec adminAuth dans settings.js dès que vous sortez du banc de test, sauf si vous aimez les surprises.

L’API REST v2 : le levier

Un flow Node-RED relié par l'API REST v2 à l'ECLYPSE APEX, qui crée des objets BACnet AV et BV

Toute la magie repose sur quelques routes de l’API REST v2 de l’APEX, qui manipulent les objets BACnet locaux de l’automate :

ActionRequête
Lister les AV ou BVGET /api/rest/v2/services/bacnet/local/objects/analog-values (ou binary-values)
Créer un objetPOST /api/rest/v2/services/bacnet/local/objects/add
Écrire une valeur, une descriptionPOST /api/rest/v2/services/bacnet/local/objects/analog-values/{instance}
Lire un objetGET /api/rest/v2/services/bacnet/local/objects/binary-values/{instance}

Authentification Basic avec un compte Facilities, en HTTPS. Le certificat est auto-signé, donc on désactive la vérification côté Node-RED. Sur un réseau maîtrisé, évidemment. Pas sur Internet, hein.

Créer un objet, c’est aussi simple que ça :

POST /api/rest/v2/services/bacnet/local/objects/add
{ "object-type": "AnalogValue", "instance-number": 3001, "name": "ZB_Salon_temperature" }

Et c’est ça qui change tout : ce sont de vrais objets locaux de l’automate, pas des Network Values. Ils apparaissent dans le programme GFX et sortent en BACnet comme n’importe quel autre point. Pas de bricolage, pas de pont bancal : du point, du vrai.

Notre flow, avec Zigbee2MQTT en cobaye

La découverte

Zigbee2MQTT publie en continu la liste des appareils sur zigbee2mqtt/bridge/devices, avec pour chacun ses « exposes » : ce qu’il sait mesurer, ce qu’il sait commander. Le flow lit cette liste et en déduit les points à créer :

Côté Zigbee2MQTTCôté BACnet
Attribut binaire (on/off)BV
Attribut numérique (température, puissance…)AV
Attribut énuméréAV, valeur 1..n, la correspondance est écrite dans la description
Attribut lisibleObjet état ZB_{nom}_{attribut}
Attribut commandableObjet ZB_{nom}_{attribut}_Cmd
Disponibilité de l’appareilBV ZB_{nom}_Online

On ne garde que les catégories utiles (principales et diagnostic, pas la configuration), avec des exceptions par modèle ou par nom. Une autre source ? Seule cette partie est à réécrire.

La création, un point à la fois

Des objets BACnet numérotés 3000, 3001, 3002 passent un par un un portique gardé par un chien robot avant d'entrer dans l'ECLYPSE APEX, sous l'écran EC-gfxProgram

Les objets sont créés dans une plage d’instances réservée au flow : 3000 à 3999, sur la première instance libre de chaque type. Ça évite de marcher sur les points du programme. Une autre source, prenez une autre plage.

Deux garde-fous qui m’ont évité bien des misères :

  • une vraie file d’attente qui crée un seul point à la fois, avec un watchdog. Sinon deux créations simultanées se disputent la même instance, et personne ne gagne ;
  • si un objet du même nom existe déjà dans l’APEX, il est retrouvé, pas recréé. On peut vider le cache et relancer le scan sans tout dupliquer.

Valeurs, disponibilité, commandes

  • Chaque message zigbee2mqtt/<nom> met à jour la present-value des objets état, sur changement, avec un rafraîchissement forcé toutes les 10 minutes.
  • zigbee2mqtt/<nom>/availability alimente le BV _Online et passe les objets en out-of-service quand l’appareil disparaît. Un module débranché, ça se voit tout de suite en supervision.
  • Les écritures sont limitées à 10 requêtes par seconde, pour ne pas assommer l’automate.
  • Dans l’autre sens, le programme GFX écrit dans les objets _Cmd. Node-RED les relit toutes les 2 secondes et, sur changement, publie sur zigbee2mqtt/<nom>/set. La première lecture sert juste à mémoriser l’état : sinon, au redémarrage de Node-RED, tous les relais du bâtiment claquent en chœur. Ambiance.

Le résultat

Avec un SONOFF ZBMINIR2, en quelques secondes, j’ai vu apparaître dans l’APEX l’état du relais, sa commande, sa disponibilité et ses infos de diagnostic. Le tout dans le programme GFX, prêt à servir. Je ne vais pas vous mentir, c’était un moment.

Le flow complet est ici : flow-zigbee2mqtt-apex.json. À importer dans Node-RED, puis à adapter : adresse de l’APEX, compte Facilities, plage d’instances, exceptions, broker MQTT. Je ne vous prends pas par la main, vous êtes grands.

Les pièges

  • Pas de / dans les noms conviviaux de Zigbee2MQTT.
  • Renommer un appareil dans Zigbee2MQTT crée de nouveaux objets ; les anciens sont à supprimer à la main.
  • Ne faites pas tourner en parallèle un ancien flow manuel sur les mêmes appareils.
  • Le principe vaut pour n’importe quelle source MQTT : seule la découverte change. Pour du LoRaWAN, on part des uplinks ChirpStack et non de bridge/devices.

La suite

Faisons le compte. Un automate de GTB qui fait tourner un broker MQTT, et un Node-RED qui transforme tout ce qui y circule en points BACnet sans intervention humaine. Le tout sur un rail DIN.

Et maintenant que vous avez la recette, vous allez voir qu’elle se répète. Au prochain épisode, on monte un serveur LoRaWAN complet avec ChirpStack… et vous allez avoir une franche impression de déjà-vu.

Liens

$ gtb react

Cet article t'a parlé ?

$ gtb comments --tail

Commentaires

// chargement…

open/gtb · MIT · hébergé en France
visiteurs github roadmap messages contact
SYS OK 15/18 outils en ligne uptime — T° baie 21,3 °C