BUT Mesures Physiques · IUT Aix-Marseille · 2026-2027

Envoyer les mesures de votre capteur

Votre carte ESP32 doit envoyer ses mesures en Wi-Fi au serveur AirCarto. Cette page décrit ce que le serveur attend et ce qu'il répond ; le programme, c'est vous qui l'écrivez.

POST http://api.aircarto.fr/iut-amu/push
Clé du groupeEn-tête X-Group-Key, donnée par l'enseignant
CorpsJSON, Content-Type: application/json
RythmeUn envoi toutes les 10 s au plus
Protocolehttp:// simple, pas de certificat à gérer
Le message

Le JSON à envoyer

Un objet JSON « plat » : un nom, une valeur. device_id est obligatoire dans chaque envoi : c'est l'adresse MAC de la carte, son identifiant unique. Les mesures sont facultatives : envoyez celles que votre carte mesure. Un NebuleAir n'envoie pas de co2, et c'est normal.

Exemple NebuleAir
{
  "device_id": "A4:CF:12:34:56:78",
  "pm1": 2.1,
  "pm25": 3.5,
  "pm10": 6.0,
  "temp": 21.3,
  "hum": 55.0,
  "pressure": 1013.2,
  "uptime": 3600,
  "rssi": -67,
  "heap": 182344
}
Exemple ModuleAir
{
  "device_id": "A4:CF:12:9A:BC:DE",
  "pm1": 1.8,
  "pm25": 2.9,
  "pm10": 4.4,
  "temp": 22.8,
  "hum": 41.5,
  "pressure": 1011.7,
  "co2": 812,
  "uptime": 7260,
  "rssi": -58,
  "heap": 176512
}
ChampUnitéBornesNebuleAirModuleAirD'où vient la valeur
pm1 pm25 pm10µg/m³0 à 1000Capteur de particules
temp°C−40 à 85Capteur météo
hum%0 à 100Capteur météo
pressurehPa300 à 1100Capteur météo (hPa, pas Pa : divisez par 100)
co2ppm0 à 10 000Capteur de CO₂
uptimes≥ 0Temps depuis le démarrage de la carte : retombe à 0 à chaque redémarrage
rssidBm−120 à 0Force du signal Wi-Fi reçu
heapoctets≥ 0Mémoire vive libre : une baisse continue signale une fuite mémoire
npm_statuscode0 à 255État du NextPM (registre 0x13, entier) : 0 = tout va bien, 255 = le capteur ne répond pas
device_idtexte12 hexObligatoire. Adresse MAC de la carte (WiFi.macAddress()), avec ou sans : : le serveur enregistre A4CF12345678
x_votre_nomlibrenombrefacultatif, 10 au plusVos expériences : x_batterie, x_boucle…

Les trois pièges du JSON. Les nombres s'écrivent sans guillemets ("pm25": 12.3, pas "pm25": "12.3"). Un capteur non lu donne nan en C++, qui n'est pas du JSON valide : n'envoyez pas le champ dans ce cas. Les noms sont en minuscules : pm25, pas PM2.5.

Votre travail

Ce que votre programme doit faire

À vous de trouver comment le faire en C++ sur ESP32 : la documentation du cœur Arduino pour ESP32 et ses exemples sont le bon point de départ.

Conseil : commencez par envoyer uptime, rssi et heap, qui ne demandent aucun capteur. Quand l'envoi marche, ajoutez les mesures une par une.

Une réponse réussie du serveur ressemble à ceci :

Réponse HTTP 201
{
    "ok": true,
    "message": "1 mesure enregistrée.",
    "group": "g01",
    "device_type": "nebuleair",
    "points_written": 1,
    "device_id": "A4CF12345678",
    "fields": ["uptime", "rssi", "heap"],
    "first_ts": 1790611200,
    "last_ts": 1790611200,
    "server_time": 1790611200,
    "next_push_in_s": 10
}
Débogage

Lire la réponse du serveur

Chaque réponse est un JSON avec ok, error et un message en français qui dit quoi corriger. Commencez toujours par afficher le code HTTP et le corps de la réponse.

CodeerrorCe qui se passeQuoi faire
201–Mesures enregistréesRien, tout va bien
aucune–La requête n'est jamais partieWi-Fi connecté ? URL en http:// (pas https://) ?
404page HTMLL'URL est mal écriteRecopiez exactement /iut-amu/push
405method_not_allowedVous avez fait un GETEnvoyez en POST
401missing_key · invalid_keyClé absente ou mal recopiéeVérifiez X-Group-Key : 32 caractères, sans espace
400invalid_jsonLe JSON est mal forméCherchez nan, une virgule en trop, des guillemets simples
400not_a_numberUne valeur est une chaîne ou nullNombres sans guillemets ; ne pas envoyer un capteur non lu
400out_of_rangeValeur hors bornesValeur sentinelle (−1, 9999) ? Unité ? (hPa, pas Pa)
400unknown_fieldNom de champ inconnuMinuscules, noms du tableau ci-dessus, ou x_…
400missing_device_iddevice_id absentAjoutez l'adresse MAC de la carte à chaque envoi
400bad_device_idAdresse MAC mal formée12 caractères hexadécimaux, avec ou sans :
429rate_limitedEnvoi trop rapprochéAu moins 10 s entre deux envois
502storage_unavailableIncident côté serveurRéessayez dans une minute, prévenez l'enseignant si ça dure
Côté serveur

Voir ce que le serveur a reçu

Ouvrez cette adresse dans un navigateur, en remplaçant la fin par votre clé. Elle montre vos 20 dernières requêtes, acceptées ou refusées, avec le JSON exact reçu et le message d'erreur.

GET https://api.aircarto.fr/iut-amu/last?key=VOTRE_CLE

Si la liste est vide alors que votre carte « envoie », la requête n'arrive pas jusqu'au serveur : regardez le Wi-Fi et l'URL.

Pour récupérer vos mesures (analyse, tableur) : https://api.aircarto.fr/iut-amu/data?key=VOTRE_CLE&start=-24h&format=CSV. La documentation complète et testable est sur api.aircarto.fr/scalar.html.

Avant de flasher

Tester depuis le PC

Pour vérifier votre clé et votre JSON sans la carte, depuis un terminal (Linux, macOS, ou PowerShell avec curl.exe) :

Terminal
curl -X POST http://api.aircarto.fr/iut-amu/push \
  -H "X-Group-Key: VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"device_id": "A4:CF:12:34:56:78", "pm25": 7.8, "temp": 21.4}'
Quand ça ne marche pas

Dans l'ordre

  1. La carte est-elle connectée au Wi-Fi, avec une adresse IP ?
  2. Recevez-vous un code HTTP ? Sinon, la requête n'est pas partie (URL, Wi-Fi).
  3. Que dit le message de la réponse ? Il nomme le champ et la valeur fautive.
  4. Que montre /iut-amu/last ? Comparez le JSON reçu avec celui que vous pensiez envoyer.
  5. Le même JSON passe-t-il avec curl depuis le PC ? Si oui, le problème est dans le firmware.