Data Upload API a ukázkové skripty

Prvním krokem je získání tokenu ze stránky datové platformy .

Jakmile budete mít svůj vlastní token, můžete k nahrání dat použít následující skript. Po nahrání dat první stanice přejděte na aqicn.org/data-feed/verification/ , kde nakonfigurujete své stanice a ověříte nahraná data.

Podporované softwarové platformy:

Poskytujeme software připravený k použití pro tyto 3 platformy:

  • Arduino : Pokud máte procesor Arduino, použijte připravený software dostupný na github.com na adrese aqicn/gaia-a08-arduino .
  • Python: Použijte níže uvedený fragment kódu
  • Příkazový řádek (CURL): Použijte níže uvedený fragment kódu

Pokud žádnou monitorovací stanici nemáte a chtěli byste si ji pořídit, podívejte se na naše monitorovací stanice GAIA Air Quality.

Pokud dáváte přednost DIY stanici, podívejte se na GAIA A08 .


--

Ukázkový kód (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) 

Ukázkový kód (vlna)

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

Ukázkový kód (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(); 
}

Možnosti API

Parameter Type Optional/Mandatory Explanations
token string mandatory

Získejte svůj vlastní token z aqicn.org/data-platform/token .

station
station.id string mandatory

Jedinečné ID stanice - můžete zvolit libovolný název s max. 128 znaky.
Tento název se pro vás používá pouze interně. Nikdo jiný toto ID neuvidí

station.name string optional

Název stanice – může to být například název vaší budovy, název ulice, název univerzity, kód vaší osobní meteostanice.
Tento název bude použit jako přípona adresy URL vaší stanice.

station.latitude float optional

Zeměpisná délka vaší stanice

station.longitude float optional

Zeměpisná délka vaší stanice

organization
org.website string optional

Pokud máte webovou stránku s více informacemi o vaší stanici/senzoru, přidáme tento odkaz na naši mapu, když ji použijete, podívejte se na vaši stanici

org.name string optional

Pokud zadáte webovou stránku, bude tento „název organizace“ spojen s webovou stránkou.

readings
readings[*].specie string mandatory

Název znečišťující látky, kterou hlásíte. Pro senzory plynu použijte: "pm2.5", "pm10", "pm1.0", ... Pro senzor plynu použijte: "co2", "no2", "o3", ... Pro senzor počasí, použití: "teplota", "vlhkost", "tlak", "rychlost větru", "poryv větru", "směr větru", ..
Vlastně můžete použít jakýkoli název druhu, který chcete. Když je vaše stanice ověřena, názvy budou v našem systému normalizovány.

readings[*].value float mandatory

Pokud váš senzor vytváří hodnoty každou sekundu a nahráváte pouze každou minutu, tato hodnota by měla být průměrem všech hodnot načtených během poslední minuty.

readings[*].unit string optional

Jednotka hodnoty. Např. "mg/m3" pro senzor prachu, ppb pro senzory plynu, C pro senzor teploty..

readings[*].time string optional

Datum a čas čtení ve formátu ISO 8601

readings[*].min float optional

Pokud jsou načtené hodnoty založeny na průměrování několika hodnot, pak to odpovídá minimální hodnotě všech hodnot použitých pro průměrování.

readings[*].max float optional

Pokud jsou načtené hodnoty založeny na zprůměrování několika hodnot, pak to odpovídá maximální hodnotě všech hodnot použitých pro průměrování.

readings[*].median float optional

Pokud jsou načtené hodnoty založeny na zprůměrování několika hodnot, pak to odpovídá střední hodnotě všech hodnot použitých pro zprůměrování.

readings[*].stddev float optional

Pokud jsou naměřené hodnoty založeny na zprůměrování několika hodnot, pak to odpovídá směrodatné odchylce všech hodnot použitých pro zprůměrování.

readings[*].averaging float optional

Pokud jsou výše uvedené hodnoty založeny na zprůměrování několika hodnot, pak to odpovídá době trvání průměrovací periody v sekundách.
Například použijte 60 pro minutový průměr dat a 3600 pro hodinový průměr.

Příklad 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-09-19T09:59:33+09:00","specie":"pm2.5", "value": 393.3, "unit":"mg/m3", "min":390.3, "max": 402.3, "stddev": 0.332},  
		{"time":"2024-09-19T09:59:33+09:00","specie":"pm10", "value": 109.3, "unit":"mg/m3"}, 
		{"time":"2024-09-19T09:59:33+09:00","specie":"co2", "value": 459.3, "unit":"ppb"}, 
		{"time":"2024-09-19T09:59:33+09:00","specie":"temp", "value": 26.8, "unit":"C"}, 
	] 
}

Příklad 2

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

Kompletní příklad kódu

Tento kód můžete použít pro nepřetržité čtení ze senzoru SDS a nahrávání každou minutu: (skript je také dostupný na 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) 
 

Znáte ve svém okolí nějakou stanici pro kvalitu ovzduší?
Zúčastněte se své vlastní monitorovací stanice kvality ovzduší

Naše monitory kvality vzduchu GAIA se velmi snadno nastavují: Potřebujete pouze přístupový bod WIFI a napájecí zdroj kompatibilní s USB.

Po připojení jsou vaše úrovně znečištění vzduchu v reálném čase okamžitě dostupné na mapách a prostřednictvím API.

Stanice je dodávána s 10metrovým vodotěsným napájecím kabelem, USB napájecím zdrojem, montážním vybavením a volitelným solárním panelem.

O měření kvality ovzduší a znečištění:

O úrovních kvality ovzduší

- Hodnoty indexu kvality ovzduší (AQI).Úrovně obav o zdraví
0 - 50 Dobrý Kvalita ovzduší je považována za uspokojivou a znečištění ovzduší představuje malé nebo žádné riziko
51 -100 Mírný Kvalita ovzduší je přijatelná; u některých znečišťujících látek však může existovat mírný zdravotní problém u velmi malého počtu lidí, kteří jsou neobvykle citliví na znečištění ovzduší.
101-150 Nezdravé pro citlivé skupiny Členové citlivých skupin mohou mít účinky na zdraví. Obecná veřejnost pravděpodobně nebude zasažena.
151-200 Nezdravý Každý může začít projevovat účinky na zdraví. členové citlivých skupin mohou mít vážnější účinky na zdraví
201-300 Velmi Nezdravé Zdravotní varování při havarijních podmínkách. Celá populace je pravděpodobněji postižena.
300+ Nebezpečný Zdravotní upozornění: každý může mít vážnější zdravotní účinky

Chcete-li se dozvědět více o kvalitě ovzduší a znečištění, podívejte se na téma Kvalita ovzduší na wikipedii nebo na airnow průvodce Kvalita ovzduší a vaše zdraví .

Velmi užitečné zdravotní rady pekingského lékaře Richarda Saint Cyr MD najdete na blogu www.myhealthbeijing.com .


Upozornění na použití: Veškeré údaje o kvalitě ovzduší jsou v době zveřejnění neplatné a vzhledem k zajištění kvality mohou být tyto údaje kdykoli změněny bez upozornění. Projekt Světový index kvality ovzduší vynaložil veškeré přiměřené schopnosti a péči při sestavování obsahu těchto informací a za žádných okolností Projektový tým Světového indexu kvality ovzduší nebo jeho zástupci nesou odpovědnost za smluvní, delikt nebo jinou odpovědnost za jakoukoliv ztrátu, zranění nebo škodu vzniklou přímo nebo nepřímo z poskytování těchto údajů.



Settings


Language Settings:


Temperature unit:
Celcius