API voor het uploaden van gegevens en voorbeeldscripts

De eerste stap is het verkrijgen van een token van de data-platformpagina.

Zodra u uw eigen token heeft, kunt u het volgende script gebruiken om uw gegevens te uploaden. Nadat u uw eerste stationgegevens heeft geüpload, gaat u naar aqicn.org/data-feed/verification/ om uw stations te configureren en de geüploade gegevens te verifiëren.

Ondersteunde softwareplatforms:

Wij leveren de kant-en-klare software voor deze 3 platforms:

  • Arduino: als je een Arduino CPU hebt, gebruik dan de kant-en-klare software die beschikbaar is op github.com op aqicn/gaia-a08-arduino.
  • Python: gebruik het onderstaande codefragment
  • Commandoregel (CURL): gebruik het onderstaande codefragment

Als u geen meetstation heeft en er wel een wilt aanschaffen, bekijk dan onze GAIA meetstations voor luchtkwaliteit.

Als je de voorkeur geeft aan een doe-het-zelf-station, kijk dan eens naar de GAIA A08.


--

Voorbeeldcode (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) 

Voorbeeldcode (krul)

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}]\ 
}'

Voorbeeldcode (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(); 
}

API-opties

Parameter Type Optional/Mandatory Explanations
token string mandatory

Haal uw eigen token op van aqicn.org/data-platform/token.

station
station.id string mandatory

Unieke zender-ID - u kunt elke naam met maximaal 128 tekens selecteren.
Deze naam wordt alleen intern voor u gebruikt. Niemand anders zal deze ID zien

station.name string optional

Naam van het station - kan bijvoorbeeld de naam van uw gebouw zijn, de naam van een straat, de naam van een universiteitsafdeling, de code van uw persoonlijke weerstation.
Deze naam wordt gebruikt als achtervoegsel voor uw station-URL.

station.latitude float optional

Lengtegraad van uw station

station.longitude float optional

Lengtegraad van uw station

organization
org.website string optional

Als u een website heeft met meer informatie over uw station/sensor, zullen wij deze link op onze kaart toevoegen wanneer u uw station bekijkt

org.name string optional

Als u een website opgeeft, wordt deze ‘organisatienaam’ aan de website gekoppeld.

readings
readings[*].specie string mandatory

Naam van de verontreinigende stof die u rapporteert. Voor gassensoren gebruik: "pm2.5", "pm10", "pm1.0", ... Voor gassensor gebruik: "co2", "no2", "o3", ... Voor weersensor, gebruik: "temp", "vochtigheid", "druk", "windsnelheid", "windstoot", "windrichting", ..
Je kunt eigenlijk elke soortnaam gebruiken die je wilt. Wanneer uw station gevalideerd is, worden de namen genormaliseerd in ons systeem.

readings[*].value float mandatory

Als uw sensor elke seconde waarden produceert en u uploadt slechts elke minuut, moet deze waarde het gemiddelde zijn van alle waarden die de afgelopen minuut zijn gelezen.

readings[*].unit string optional

Eenheid van de waarde. Bijvoorbeeld "mg/m3" voor stofsensor, ppb voor gassensoren, C voor temperatuursensor.

readings[*].time string optional

Datum en tijd van de meting in ISO 8601-formaat

readings[*].min float optional

Als de meetwaarden zijn gebaseerd op het middelen van meerdere waarden, komt dit overeen met de minimale waarde van alle waarden die voor het middelen zijn gebruikt.

readings[*].max float optional

Als de meetwaarden zijn gebaseerd op het middelen van meerdere waarden, komt dit overeen met de maximale waarde van alle waarden die voor het middelen zijn gebruikt.

readings[*].median float optional

Als de meetwaarden zijn gebaseerd op het middelen van meerdere waarden, komt dit overeen met de mediaanwaarde van alle waarden die voor het middelen zijn gebruikt.

readings[*].stddev float optional

Als de meetwaarden zijn gebaseerd op het middelen van meerdere waarden, komt dit overeen met de standaardafwijking van alle waarden die voor het middelen zijn gebruikt.

readings[*].averaging float optional

Als de bovenstaande waarden gebaseerd zijn op het middelen van meerdere waarden, komt dit overeen met de duur, in seconden, van de middelingsperiode.
Gebruik bijvoorbeeld 60 voor gemiddelde gegevens per minuut en 3600 voor uurgemiddelden.

voorbeeld 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":"2024-12-22T12:09:27+09:00","specie":"pm2.5", "value": 393.3, "unit":"mg/m3", "min":390.3, "max": 402.3, "stddev": 0.332},  
		{"time":"2024-12-22T12:09:27+09:00","specie":"pm10", "value": 109.3, "unit":"mg/m3"}, 
		{"time":"2024-12-22T12:09:27+09:00","specie":"co2", "value": 459.3, "unit":"ppb"}, 
		{"time":"2024-12-22T12:09:27+09:00","specie":"temp", "value": 26.8, "unit":"C"}, 
	] 
}

Voorbeeld 2

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

Compleet codevoorbeeld

Je kunt deze code gebruiken om continu van een SDS-sensor te lezen en elke minuut te uploaden: (script ook beschikbaar via 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) 
 

Weet u of er in uw omgeving luchtkwaliteitsstations zijn?
Waarom zou u niet meedoen aan de kaart met uw eigen luchtkwaliteitsstation?

Onze GAIA luchtkwaliteitsmonitoren zijn zeer eenvoudig te installeren: u heeft alleen een WIFI-toegangspunt en een USB-compatibele voeding nodig.

Eenmaal verbonden, zijn uw realtime luchtverontreinigingsniveaus onmiddellijk beschikbaar op de kaarten en via de API.

Het station wordt geleverd met een waterdichte voedingskabel van 10 meter, een USB-voeding, bevestigingsmateriaal en een optioneel zonnepaneel.

Over de luchtkwaliteit- en vervuilingsmeting:

Over de luchtkwaliteitsniveaus

- Luchtkwaliteitsindex (AQI)-waardenNiveaus van gezondheidsproblemen
0 - 50 Goed Luchtkwaliteit wordt als bevredigend beschouwd en luchtverontreiniging vormt weinig of geen risico
51 -100 Matig Luchtkwaliteit is acceptabel; voor sommige verontreinigende stoffen kan er echter sprake zijn van een matige gezondheidsrisico voor een zeer klein aantal mensen dat ongewoon gevoelig is voor luchtvervuiling.
101-150 Ongezond voor gevoelige groepen Leden van gevoelige groepen kunnen gezondheidseffecten ervaren. Het grote publiek zal waarschijnlijk niet worden beïnvloed.
151-200 Ongezond Iedereen kan gezondheidseffecten ervaren; leden van gevoelige groepen kunnen ernstiger gezondheidseffecten ervaren
201-300 Zeer Ongezonde Gezondheidswaarschuwingen voor noodomstandigheden. De volledige populatie is mogelijk getroffen.
300+ gevaarlijk Gezondheidswaarschuwing: iedereen kan ernstigere gezondheidseffecten ervaren

Als u meer wilt weten over luchtkwaliteit en vervuiling, raadpleegt u het Wikipedia-onderwerp Luchtkwaliteit of de airnow-gids voor luchtkwaliteit en uw gezondheid .

Voor zeer nuttige gezondheidsadviezen van de Beijing-arts Richard Saint Cyr MD, kijk op de blog www.myhealthbeijing.com .


Gebruiksmelding: Alle gegevens van de luchtkwaliteit zijn niet-gevalideerd op het moment van publicatie en als gevolg van kwaliteitsborging kunnen deze gegevens op elk gewenst moment zonder voorafgaande kennisgeving worden gewijzigd. Het World Air Quality Index -project heeft alle redelijke vaardigheid en zorg besteed aan het samenstellen van de inhoud van deze informatie en onder geen enkele voorwaarde zal de World Air Quality Index projectteam of zijn agenten zijn aansprakelijk in contract, onrechtmatige daad of anderszins voor enig verlies, letsel of schade die direct of indirect voortvloeit uit de levering van deze gegevens.



Settings


Language Settings:


Temperature unit:
Celcius