API-ul de încărcare a datelor și scripturi exemple

Primul pas este să obțineți un token de pe pagina platformei de date .

Odată ce aveți propriul token, puteți utiliza următorul script pentru a vă încărca datele. După ce încărcați primele date ale stației, accesați aqicn.org/data-feed/verification/ pentru a vă configura stațiile și a verifica datele încărcate.

Platforme software acceptate:

Oferim software-ul gata de utilizare pentru aceste 3 platforme:

  • Arduino : Dacă aveți un procesor Arduino, utilizați software-ul gata de utilizare disponibil pe github.com la aqicn/gaia-a08-arduino .
  • Python: utilizați fragmentul de cod de mai jos
  • Linia de comandă (CURL): Utilizați fragmentul de cod de mai jos

Dacă nu aveți nicio stație de monitorizare și doriți să obțineți una, verificați stațiile noastre de monitorizare a calității aerului GAIA .

Dacă preferați o stație de bricolaj, verificați GAIA A08 .


--

Exemplu de cod (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) 

Exemplu de cod (curl)

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

Exemplu de cod (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(); 
}

Opțiuni API

Parameter Type Optional/Mandatory Explanations
token string mandatory

Obțineți propriul token de pe aqicn.org/data-platform/token .

station
station.id string mandatory

ID unic al postului - puteți selecta orice nume cu maximum 128 de caractere.
Acest nume este folosit doar intern pentru dvs. Nimeni altcineva nu va vedea acest ID

station.name string optional

Numele stației - ar putea fi, de exemplu, numele clădirii dvs., numele unei străzi, numele unui departament universitar, codul stației dvs. meteo personale.
Acest nume va fi folosit ca sufix pentru adresa URL a postului dvs.

station.latitude float optional

Longitudinea stației dvs

station.longitude float optional

Longitudinea stației dvs

organization
org.website string optional

Dacă aveți un site web cu mai multe informații despre stația/senzorul dvs., vom adăuga acest link pe harta noastră când este utilizat, vedeți stația dvs.

org.name string optional

Dacă specificați un site web, acest „nume organizație” va fi asociat site-ului web.

readings
readings[*].specie string mandatory

Numele poluantului pe care îl raportați. Pentru senzori de gaz, utilizați: "pm2.5", "pm10", "pm1.0", ... Pentru senzorul de gaz, utilizați: "co2", "no2", "o3", ... Pentru senzorul de vreme, utilizați: „temperatură”, „umiditate”, „presiune”, „viteza vântului”, „rafala vântului”, „direcția vântului”, ..
De fapt, puteți folosi orice nume de specie doriți. Când stația dvs. este validată, numele vor fi normalizate în sistemul nostru.

readings[*].value float mandatory

Dacă senzorul dvs. produce valori în fiecare secundă și încărcați numai în fiecare minut, această valoare ar trebui să fie media tuturor valorilor citite în ultimul minut.

readings[*].unit string optional

Unitatea valorii. De exemplu, „mg/m3” pentru senzorul de praf, ppb pentru senzorii de gaz, C pentru senzorul de temperatură.

readings[*].time string optional

Data și ora citirii în format ISO 8601

readings[*].min float optional

Dacă valorile citite se bazează pe media mai multor valori, atunci aceasta corespunde valorii minime a tuturor valorilor utilizate pentru calcularea mediei.

readings[*].max float optional

Dacă valorile citite se bazează pe media mai multor valori, atunci aceasta corespunde valorii maxime a tuturor valorilor utilizate pentru calcularea mediei.

readings[*].median float optional

Dacă valorile citite se bazează pe media mai multor valori, atunci aceasta corespunde valorii mediane a tuturor valorilor utilizate pentru mediere.

readings[*].stddev float optional

Dacă valorile citite se bazează pe media mai multor valori, atunci aceasta corespunde abaterii standard a tuturor valorilor utilizate pentru calcularea mediei.

readings[*].averaging float optional

Dacă valorile de mai sus se bazează pe media mai multor valori, atunci aceasta corespunde duratei, în secunde, a perioadei de mediere.
De exemplu, utilizați 60 pentru datele medii pe minut și 3600 pentru media orară.

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

Exemplul 2

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

Exemplu de cod complet

Puteți folosi acest cod pentru citirea continuă de pe un senzor SDS și încărcarea în fiecare minut: (script disponibil și de la 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) 
 

Cunoașteți stații de calitate a aerului în zona dvs.?
de ce să nu participi la hartă cu propria ta stație de calitate a aerului?

Monitoarele noastre de calitate a aerului GAIA sunt foarte ușor de configurat: aveți nevoie doar de un punct de acces WIFI și de o sursă de alimentare compatibilă cu USB.

Odată conectat, nivelurile de poluare a aerului în timp real sunt disponibile instantaneu pe hărți și prin API.

Stația vine cu un cablu de alimentare rezistent la apă de 10 metri, o sursă de alimentare USB, echipament de montare și un panou solar opțional.

Despre măsurarea calității aerului și a poluării:

Despre nivelurile de calitate a aerului

- Valorile indicelui de calitate a aerului (AQI).Niveluri de îngrijorare pentru sănătate
0 - 50 Bun Calitatea aerului este considerată satisfăcătoare, iar poluarea aerului prezintă un risc mic sau deloc
51 -100 Moderat Calitatea aerului este acceptabilă; cu toate acestea, pentru anumiți poluanți poate exista o îngrijorare moderată de sănătate pentru un număr foarte mic de persoane care sunt neobișnuit de sensibile la poluarea aerului.
101-150 Nesănătos pentru grupurile sensibile Membrii grupurilor sensibile pot avea efecte asupra sănătății. Este puțin probabil ca publicul larg să fie afectat.
151-200 Nesănătos Toată lumea poate începe să experimenteze efectele asupra sănătății; membrii grupurilor sensibile pot avea efecte mai grave asupra sănătății
201-300 Foarte Nesănătoasă Avertismente de sănătate privind situațiile de urgență. Întreaga populație este mai probabil să fie afectată.
300+ Riscant Alertă de sănătate: toată lumea poate avea efecte mai grave asupra sănătății

Pentru a afla mai multe despre calitatea aerului și poluare, consultați subiectul wikipedia pentru calitatea aerului sau ghidul airnow despre calitatea aerului și sănătatea dvs.

Pentru sfaturi foarte utile de sănătate ale medicului doctor Richard Saint Cyr din Beijing, consultați blogul www.myhealthbeijing.com .


Notificare privind utilizarea: Toate datele privind calitatea aerului sunt nevalide la momentul publicării și, datorită asigurării calității, aceste date pot fi modificate, fără notificare, în orice moment. Proiectul Index al calității aerului mondial a exercitat toate competențele și îngrijirea rezonabilă în compilarea conținutului acestor informații și în nici un caz Echipa de proiect pentru indexul calității aerului sau agenții săi sunt răspunzători în contract, delictuală sau în alt mod pentru orice pierdere, vătămare sau daună care rezultă direct sau indirect din furnizarea acestor date.



Settings


Language Settings:


Temperature unit:
Celcius