API de téléchargement de données et exemples de scripts

La première étape consiste à obtenir un jeton sur la page de la plateforme de données.

Une fois que vous disposez de votre propre jeton, vous pouvez utiliser le script suivant pour télécharger vos données. Après avoir téléchargé les données de votre première station, accédez à aqicn.org/data-feed/verification/ pour configurer vos stations et vérifier les données téléchargées.

Plateformes logicielles prises en charge :

Nous fournissons le logiciel prêt à l'emploi pour ces 3 plateformes :

  • Arduino : si vous disposez d'un processeur Arduino, utilisez le logiciel prêt à l'emploi disponible sur github.com à l'adresse aqicn/gaia-a08-arduino.
  • Python : utilisez l'extrait de code ci-dessous.
  • Ligne de commande (CURL) : utilisez l'extrait de code ci-dessous.

Si vous n'avez pas de station de surveillance et souhaitez en obtenir une, consultez nos stations de surveillance de la qualité de l'air GAIA.

Si vous préférez une station DIY, consultez le GAIA A08.


--

Exemple de code (python)

import requests
# Sensor parameter
sensorReadings = [
{'specie':'pm25', 'value': 393.3},
{'specie':'pm10', 'value': 109.3}
]
# Station parameter
station = {
'id': "station-001",
'location': {
'latitude': 28.7501,
'longitude': 77.1177
}
}
# User parameter - get yours from https://aqicn.org/data-platform/token/
userToken = "dummy-token-for-test-purpose-only"
# Then Upload the data
params = {'station':station,'readings':sensorReadings,'token':userToken}
request = requests.post( url = "https://aqicn.org/sensor/upload/", json = params)
#print(request.text)
data = request.json()
if data["status"]!="ok":
print("Something went wrong: %s" % data)
else:
print("Data successfully posted: %s"%data)

Exemple de code (boucle)

curl -X POST https://aqicn.org/sensor/upload -H 'Content-Type: application/json' --data '{\
"token": "dummy-token-for-test-purpose-only",\
"station": { "id": "station-001" },\
"readings": [{"specie":"pm2.5", "value": 393.3}]\
}'

Exemple de code (arduino)

Check github.com/aqicn/gaia-a08-arduino for the full code.
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#define LATITUDE 28.7501
#define LONGITUDE 77.1177
void upload(float pm25_concentration, float pm10_concentration, const char * token)
{
static char stationID[32];
uint64_t efuseMac = ESP.getEfuseMac();
uint16_t chip = (uint16_t)(efuseMac >> 32);
snprintf(stationID, 32, "station-%x", chip);
doc["token"] = token;
doc["station"]["id"] = stationID;
doc["station"]["location"]["latitude"] = LATITUDE;
doc["station"]["location"]["longitude"] = LONGITUDE;
doc["readings"][0]["specie"] = "pm25";
doc["readings"][0]["value"] = pm25_concentration;
doc["readings"][0]["unit"] = "µg/m3";
doc["readings"][1]["specie"] = "pm10";
doc["readings"][1]["value"] = pm10_concentration;
doc["readings"][1]["unit"] = "µg/m3";
static char json_body[1024];
serializeJson(doc, json_body);
HTTPClient http;
http.begin("https://aqicn.org/sensor/upload");
http.addHeader("Content-Type", "application/json");
int httpResponseCode = http.POST(json_body);
if (httpResponseCode > 0)
{
String response = http.getString();
Serial.println(httpResponseCode);
Serial.println(response);
}
else
{
Serial.print("Error on sending POST: ");
Serial.println(httpResponseCode);
}
http.end();
}

Options de l'API

Parameter Type Optional/Mandatory Explanations
token string mandatory

Obtenez votre propre jeton sur aqicn.org/data-platform/token.

station
station.id string mandatory

ID de station unique - vous pouvez sélectionner n'importe quel nom avec un maximum de 128 caractères.
Ce nom n'est utilisé qu'en interne pour vous. Personne d'autre ne verra cet identifiant

station.name string optional

Nom de la station - peut être par exemple le nom de votre bâtiment, le nom d'une rue, le nom d'un département universitaire, le code de votre station météo personnelle.
Ce nom sera utilisé comme suffixe pour l'URL de votre station.

station.latitude float optional

Longitude de votre station

station.longitude float optional

Longitude de votre station

organization
org.website string optional

Si vous disposez d'un site Web contenant plus d'informations sur votre station/capteur, nous ajouterons ce lien sur notre carte lorsqu'il sera utilisé pour voir votre station

org.name string optional

Si vous spécifiez un site Web, ce « nom d'organisation » sera associé au site Web.

readings
readings[*].specie string mandatory

Nom du polluant que vous signalez. Pour les capteurs de gaz, utiliser : "pm2.5", "pm10", "pm1.0", ... Pour les capteurs de gaz, utiliser : "co2", "no2", "o3", ... Pour les capteurs météo, utilisez : "temp", "humidité", "pression", "vitesse du vent", "rafale de vent", "direction du vent", ..
Vous pouvez en fait utiliser le nom d'espèce de votre choix. Lorsque votre station sera validée, les noms seront normalisés dans notre système.

readings[*].value float mandatory

Si votre capteur produit des valeurs toutes les secondes et que vous téléchargez uniquement toutes les minutes, cette valeur doit être la moyenne de toutes les valeurs lues au cours de la dernière minute.

readings[*].unit string optional

Unité de la valeur. Par exemple "mg/m3" pour le capteur de poussière, ppb pour les capteurs de gaz, C pour le capteur de température.

readings[*].time string optional

Date et Heure de la lecture au format ISO 8601

readings[*].min float optional

Si les valeurs relevées sont basées sur la moyenne de plusieurs valeurs, cela correspond à la valeur minimale de toutes les valeurs utilisées pour la moyenne.

readings[*].max float optional

Si les valeurs de lecture sont basées sur la moyenne de plusieurs valeurs, cela correspond à la valeur maximale de toutes les valeurs utilisées pour la moyenne.

readings[*].median float optional

Si les valeurs relevées sont basées sur la moyenne de plusieurs valeurs, cela correspond à la valeur médiane de toutes les valeurs utilisées pour la moyenne.

readings[*].stddev float optional

Si les valeurs relevées sont basées sur la moyenne de plusieurs valeurs, cela correspond à l'écart type de toutes les valeurs utilisées pour la moyenne.

readings[*].averaging float optional

Si les valeurs ci-dessus sont basées sur la moyenne de plusieurs valeurs, cela correspond à la durée, en secondes, de la période de moyenne.
Par exemple, utilisez 60 pour les données moyennes par minute et 3 600 pour la moyenne horaire.

Exemple 1

{
"token": "......",
"station": {
"id": "station-001",
"name": "HCPA Santa Cecília",
"latitude": 103.37893,
"longitude": 43.17108,
},
"org": {
"website":"https://pacto.upsensor.com/",
"name":"Porto Ar Alegre",
},
"readings": [
{"time":"2025-03-07T09:47:59+09:00","specie":"pm2.5", "value": 393.3, "unit":"mg/m3", "min":390.3, "max": 402.3, "stddev": 0.332},
{"time":"2025-03-07T09:47:59+09:00","specie":"pm10", "value": 109.3, "unit":"mg/m3"},
{"time":"2025-03-07T09:47:59+09:00","specie":"co2", "value": 459.3, "unit":"ppb"},
{"time":"2025-03-07T09:47:59+09:00","specie":"temp", "value": 26.8, "unit":"C"},
]
}

Exemple 2

{
"token": "......",
"station": {
"id": "station-001",
},
"readings": [
{"specie":"pm2.5", "value": 393.3}
]
}

Exemple de code complet

Vous pouvez utiliser ce code pour lire en continu à partir d'un capteur SDS et le télécharger toutes les minutes : (script également disponible sur https://github .com/aqicn/sds-sensor-reader).

import requests
import random
import time
import math
import json
import sys
from serial import Serial
LOCATION = {'latitude': 28.7501, 'longitude': 77.1177}
TOKEN = "dummy-token-for-test-purpose-only"
SENSORID = "station-001"
USBPORT = "/dev/ttyUSB0"
class SensorDataUploader:
def __init__(self, station, token):
self.token = token
self.station = station
def send(self,readings):
params = {'station':self.station,'readings':readings,'token':self.token}
print("Uploading: %s"%json.dumps(params, indent=4))
request = requests.post( url = "https://aqicn.org/sensor/upload/", json = params)
data = request.json()
if data["status"]!="ok":
print("Something went wrong: %s" % data)
else:
print("Data successfully posted: %s"%data)
class Accumulator:
def __init__(self, name):
self.name = name
self.values = []
def add(self,val):
self.values.append(val)
def count(self):
return len(self.values)
def reset(self):
self.values=[]
def min(self):
return self.values[0]
def max(self):
return self.values[len(self.values)-1]
def median(self):
return self.values[len(self.values)/2]
def mean(self):
return float(sum(self.values)) / len(self.values)
def stddev(self):
l = len(self.values)
mean = self.mean()
return math.sqrt(float(reduce(lambda x, y: x + y, map(lambda x: (x - mean) ** 2, self.values))) / l)
def summary(self):
self.values.sort()
return {"specie":self.name,'value':self.mean(),'min':self.min(),'max':self.max(),'median':self.median(), 'stddev':self.stddev()}
class DummyReader:
def read( self ):
time.sleep(1.1)
return {"pm2.5":random.random()*10,"pm10":random.random()*10}
class SDS011Reader:
def __init__(self, inport):
self.serial = Serial(port=inport,baudrate=9600)
self.values = []
self.step = 0
def read( self ):
# time.sleep(1)
# return {"pm2.5":random.random()*100,"pm10":random.random()*100}
while self.serial.inWaiting()!=0:
v=ord(self.serial.read())
if self.step ==0:
if v==170:
self.step=1
elif self.step==1:
if v==192:
self.values = [0,0,0,0,0,0,0]
self.step=2
else:
self.step=0
elif self.step>8:
self.step =0
pm25 = (self.values[0]+self.values[1]*256)/10
pm10 = (self.values[2]+self.values[3]*256)/10
return {"pm2.5":pm25,"pm10":pm10}
elif self.step>=2:
self.values[self.step-2]=v
self.step= self.step+1
return None
def readAndUpload(sensor, uploader):
try:
while True:
accumulators = {}
startTime = time.time()
while time.time() < startTime+60:
values = sensor.read()
if values==None:
continue
print("Reading [%2d]: %s"%(int(time.time()-startTime),values))
for specie, value in values.items():
if not (specie in accumulators):
accumulators[specie]=Accumulator(specie)
accumulators[specie].add(value)
readings = []
for specie, accumulator in accumulators.items():
readings.append(accumulator.summary())
if len(readings)>0:
uploader.send(readings)
else:
print("No value read from the sensor...")
except KeyboardInterrupt:
print "Bye"
sys.exit()
print("Starting reading sensor "+SENSORID+" on port "+USBPORT)
# Station parameter
station = {'id':SENSORID, 'location':LOCATION}
uploader = SensorDataUploader(station, TOKEN)
sensor = SDS011Reader(USBPORT)
# sensor = DummyReader()
readAndUpload(sensor,uploader)

Connaissez-vous des stations de mesure de la qualité de l’air dans votre région ?
pourquoi ne pas participer à la carte avec votre propre station de qualité de l'air ?

Nos moniteurs de qualité de l'air GAIA sont très simples à mettre en place : vous n'avez besoin que d'un point d'accès WIFI et d'une alimentation compatible USB.

Une fois connecté, vos niveaux de pollution de l'air en temps réel sont instantanément disponibles sur les cartes et via l'API.

La station est livrée avec un câble d'alimentation étanche de 10 mètres, une alimentation USB, du matériel de montage et un panneau solaire en option.

À propos de la qualité de l'air et des mesures de la pollution atmosphérique :

À propos des niveaux de qualité de l'air

IQANiveau de pollution de l'air Impact sur la santé
0 - 50 Bon La qualité de l'air est jugée satisfaisante, et la pollution de l'air pose peu ou pas de risque.
51 -100 Modéré La qualité de l'air est acceptable. Cependant, pour certains polluants, il peut y avoir un risque sur la santé pour un très petit nombre de personnes inhabituellement sensibles à la pollution atmosphérique.
101-150 Mauvais pour les groupes sensibles La qualité de l'air est acceptable; Cependant, pour certains polluants, il peut y avoir un problème de santé modérée pour un très petit nombre de personnes qui sont particulièrement sensibles à la pollution de l'air.
151-200 Mauvais Tout le monde peut commencer à ressentir des effets sur la santé; les membres des groupes sensibles peuvent ressentir des effets de santé plus graves.
201-300 Très mauvais Avertissements de santé de conditions d'urgence. Toute la population est plus susceptible d'être affecté.
300+ Dangereux Alerte de santé: tout le monde peut ressentir des effets de santé plus graves.

Pour en savoir plus sur la qualité de l'air, consultez le sujet Qualité de l'air sur Wikipedia ou le guide AirNow de la qualité de l'air et de votre santé .

Pour des conseils de santé très utiles du Dr. Richard Saint Cyr, consultez le blog myhealthbeijing.com.


Notice d'utilisation: Toutes les données sur la qualité de l'air ne sont pas validées au moment de la publication et, pour des raisons d'assurance de la qualité, ces données peuvent être modifiées à tout moment et sans préavis. Le projet Indice de la qualité de l'air dans le monde a exercé toutes les compétences et l'attention réalisables dans la compilation du contenu de ces informations. Indice de la qualité de l’air dans le monde , l’équipe de projet ou ses agents ne peuvent être tenus responsables, contractuellement, judiciairement ou autrement, de toute perte, blessure ou préjudice résultant directement ou indirectement de la fourniture de ces données.



Paramètres


Choix de la langue :


Temperature unit:
Celcius