MQTT
MQTT est le choix habituel pour un firmware que vous écrivez vous-même : une connexion maintenue ouverte, et une publication chaque fois que vous avez un relevé.
Avant de commencer, récupérez l'UUID de l'appareil, le topic MQTT et les Identifiants MQTT (nom d'utilisateur et mot de passe) sur Détails de l'appareil : voir ce que la plateforme doit vous fournir d'abord.
Paramètres de connexion
| Paramètre | Valeur |
|---|---|
| Hôte | mqtt.sensocan.com |
| Port | 8883 pour TLS, 1883 pour TCP en clair |
| Identifiant client | L'UUID de l'appareil, à l'identique |
| Nom d'utilisateur | Le nom d'utilisateur MQTT indiqué sur Détails de l'appareil (il se présente comme device- suivi de l'UUID de l'appareil) |
| Mot de passe | Le mot de passe MQTT indiqué sur Détails de l'appareil |
| Clean session | Oui |
| QoS | 0 ou 1. Utilisez 1 sur une liaison peu fiable |
| Keep-alive | À votre convenance ; des keep-alive plus courts détectent plus vite une liaison coupée |
Utilisez le port 8883 en production. Le port 1883 transporte le mot de passe de votre appareil en clair ; il est prévu pour les essais en atelier, sur un réseau que vous maîtrisez.
Une clean session (session propre — rien à reprendre d'une session précédente) suffit : les appareils ne font que publier. Les abonnements sont refusés, il n'existe donc aucun état de session qui mérite d'être repris.

Le mot de passe est stocké chiffré. Rouvrir la boîte de dialogue affiche le même mot de passe : l'interface ne permet pas de le renouveler, et un nouveau mot de passe n'est émis automatiquement que si l'identifiant stocké vient à être perdu ou ne peut plus être déchiffré.
La règle de l'identifiant client
Toute connexion qui présente un autre identifiant client (client ID) est refusée, quels que soient le nom d'utilisateur et le mot de passe. C'est la panne la plus fréquente après une modification du firmware, car beaucoup de bibliothèques MQTT inventent un identifiant client à votre place : PubSubClient reprend ce que vous passez à connect(), et d'autres retiennent par défaut une chaîne aléatoire ou l'adresse MAC. Définissez-le explicitement.
Deux appareils ne doivent jamais partager un identifiant client. Quand cela arrive, chaque connexion chasse l'autre : la session la plus ancienne est fermée à chaque reconnexion de l'autre appareil, et les deux appareils oscillent indéfiniment entre connecté et déconnecté. Si vous avez copié votre firmware sur une deuxième unité, créez-lui son propre enregistrement d'appareil et son propre UUID.
Les topics
Il existe trois topics de publication. Celui que vous employez décide de la façon dont la charge utile (payload) est lue.
1. Un relevé pour un capteur
tenant/{tenant_id}/device/{device_uuid}/sensor/{sensor_identifier}
{
"data": {
"value": 24.5,
"timestamp": "2026-09-03T10:00:00Z"
},
"battery_voltage": 3.7
}
2. Plusieurs relevés pour un capteur
Notez le pluriel sensors. Employez ce topic pour vider le tampon d'un seul capteur.
tenant/{tenant_id}/device/{device_uuid}/sensors/{sensor_identifier}
{
"data": [
{ "value": 24.0, "timestamp": "2026-09-03T09:00:00Z" },
{ "value": 24.2, "timestamp": "2026-09-03T09:15:00Z" },
{ "value": 24.4, "timestamp": "2026-09-03T09:30:00Z" }
]
}
3. Des relevés pour plusieurs capteurs
Le topic au niveau de l'appareil, celui qui est affiché sur Détails de l'appareil. C'est l'option la plus efficace lorsqu'un appareil porte plusieurs capteurs.
tenant/{tenant_id}/device/{device_uuid}
{
"data": [
{ "sensor_slug": "temp_01", "value": 24.5 },
{ "sensor_slug": "humidity_01", "value": 45.2 },
{ "sensor_uuid": "7a8b9c0d-1234-5678-90ab-cdef12345678", "value": 100 }
],
"battery_voltage": 3.7
}
Chaque entrée identifie son capteur par sensor_slug ou par sensor_uuid. Une entrée qui ne porte ni l'un ni l'autre est écartée.
Dans les deux premiers topics, {sensor_identifier} est lui aussi soit le slug du capteur (son identifiant court), soit son UUID : les deux figurent sur la page du capteur, et la correspondance est exacte, casse comprise.
Vous pouvez également publier la batterie seule, sans aucune clé data, sur n'importe lequel des trois topics :
{ "battery_voltage": 3.7 }
N'assemblez pas les topics à la main
Détails de l'appareil affiche en entier le topic au niveau de l'appareil, avec un bouton de copie, et le bouton Exemples de charges utiles MQTT placé à côté ouvre les trois topics et les charges utiles correspondantes, déjà renseignés avec l'organisation, l'UUID et le premier capteur de cet appareil.

Vous ne pouvez publier que sous le topic de votre propre appareil. Une publication dont le topic porte l'UUID d'un autre appareil, ou votre UUID sous une autre organisation, est refusée par la connexion, et non ignorée en silence.
L'enveloppe data
data est acceptée puis ignoréeLes relevés se placent sous une clé data de premier niveau. Publiez {"value": 24.5} et le message arrive bien, votre appareil est marqué en ligne, et aucun relevé n'est créé. Rien ne revient vous le signaler, car une publication MQTT ne donne lieu à aucune réponse.
Si vos messages arrivent manifestement — l'appareil est en ligne, Dernière connexion continue d'avancer — et qu'aucune valeur n'apparaît, vérifiez d'abord l'enveloppe.
Exemple : ESP32 / Arduino
#include <PubSubClient.h>
const char* mqtt_server = "mqtt.sensocan.com";
const int mqtt_port = 8883; // TLS — pass a WiFiClientSecure to PubSubClient
// for this port; 1883 takes a plain WiFiClient
// All three come from Device Details. The client ID must be the Device UUID;
// the username and password are the MQTT credentials shown on that page.
const char* device_uuid = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
const char* mqtt_user = "device-a1b2c3d4-e5f6-7890-abcd-ef1234567890";
const char* mqtt_password = "your-device-mqtt-password";
// Copy the topic from Device Details rather than assembling it here.
const char* topic = "tenant/123/device/a1b2c3d4-e5f6-7890-abcd-ef1234567890/sensor/temp_01";
void setup() {
client.setServer(mqtt_server, mqtt_port);
client.setBufferSize(512); // the default is too small for batches
client.connect(device_uuid, mqtt_user, mqtt_password);
}
void loop() {
if (!client.connected()) {
client.connect(device_uuid, mqtt_user, mqtt_password);
}
client.loop();
// The data envelope is required.
const char* payload = "{\"data\":{\"value\":25.3}}";
client.publish(topic, payload);
delay(60000); // once a minute
}
PubSubClient écarte silencieusement une publication qui dépasse la taille de son tampon, fixée par défaut à 256 octets : assez pour la charge utile à un seul relevé ci-dessus, pas assez pour un lot. Appelez setBufferSize() avant d'envoyer des lots.
Dépannage
La connexion est refusée
Parcourez cette liste dans l'ordre :
- Identifiant client — il doit être exactement l'UUID de l'appareil. Affichez ce que votre bibliothèque a réellement envoyé.
- Nom d'utilisateur et mot de passe — copiez-les de nouveau depuis la boîte de dialogue Identifiants MQTT ; elle affiche toujours le même mot de passe, qui ne change pas.
- Statut de l'appareil — un appareil dont le statut est Erreur sur Détails de l'appareil n'est pas autorisé à se connecter. Rétablissez son statut depuis la page de l'appareil.
- Statut du compte — les appareils d'un compte suspendu ou inactif sont refusés. Adressez-vous à un administrateur.
L'appareil se connecte, puis perd sa connexion dès qu'un autre appareil se connecte
Deux appareils partagent le même identifiant client. Voir la règle de l'identifiant client.
L'appareil est en ligne mais aucune valeur n'apparaît
C'est sur Détails de l'appareil que cela se vérifie. Dernière connexion et le badge de statut vous disent que les messages arrivent ; le tableau des capteurs indique la Valeur actuelle et la Dernière mise à jour de chaque capteur.
- Dernière connexion avance, mais aucun capteur n'affiche de données — le message arrive mais aucun relevé n'est créé. Vérifiez l'enveloppe
data, puis vérifiez quevalueest présent dans chaque objet de relevé. - Certains capteurs se mettent à jour, d'autres non — l'identifiant de ceux qui restent vides ne correspond à aucun capteur de cet appareil. Comparez-le caractère par caractère avec le slug et l'UUID indiqués sur la page du capteur.
- Tout semble correct et rien ne se passe — les relevés sont acceptés et transmis à la chaîne de règles, et c'est la chaîne qui les écarte. Une chaîne doit contenir une étape d'enregistrement pour que les valeurs apparaissent. Voir Gestion → Chaînes de règles.
- Dernière connexion n'avance pas — le message n'arrive pas du tout. Comparez votre topic à celui affiché sur Détails de l'appareil, et vérifiez que votre charge utile est un JSON valide.
Une valeur arrive une fois puis cesse de se mettre à jour
Si votre appareil envoie plusieurs fois la même valeur, les répétitions qui se suivent à quelques secondes d'intervalle sont supprimées pour certains types de capteurs. Changez la valeur ou attendez la fin de l'intervalle pour confirmer que la liaison est saine.