Veri Yükleme API'si ve Örnek komut dosyaları

İlk adım data-platform sayfasından bir token almaktır.

Kendi token'ınız olduğunda, verilerinizi yüklemek için aşağıdaki betiği kullanabilirsiniz. İlk istasyon verilerinizi yükledikten sonra, istasyonlarınızı yapılandırmak ve yüklenen verileri doğrulamak için aqicn.org/data-feed/verification/ adresine gidin.

Desteklenen Yazılım Platformları:

Bu 3 platform için kullanıma hazır yazılımlar sağlıyoruz:

  • Arduino : Eğer bir Arduino CPU'nuz varsa, github.com'da aqicn/gaia-a08-arduino adresinde bulunan hazır yazılımı kullanın.
  • Python: Aşağıdaki kod parçacığını kullanın
  • Komut satırı (CURL): Aşağıdaki kod parçacığını kullanın

Eğer bir izleme istasyonunuz yoksa ve bir tane edinmek istiyorsanız, GAIA Hava Kalitesi izleme istasyonlarımızı inceleyin.

Eğer kendin yap (DIY) istasyonunu tercih ediyorsanız GAIA A08'i inceleyin.


--

Örnek kod (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) 

Örnek kod (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}]\ 
}'

Örnek kod (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 Seçenekleri

Parameter Type Optional/Mandatory Explanations
token string mandatory

aqicn.org/data-platform/token adresinden kendi tokeninizi alın.

station
station.id string mandatory

Benzersiz istasyon kimliği - En fazla 128 karakter uzunluğunda herhangi bir isim seçebilirsiniz.
Bu isim sadece sizin için dahili olarak kullanılır. Başka hiç kimse bu kimliği görmeyecektir

station.name string optional

İstasyonun adı - örneğin binanızın adı, bir sokağın adı, bir üniversite bölümünün adı, kişisel hava istasyonunuzun kodu olabilir.
Bu isim istasyon URL'nizin eki olarak kullanılacaktır.

station.latitude float optional

İstasyonunuzun boylamı

station.longitude float optional

İstasyonunuzun boylamı

organization
org.website string optional

İstasyonunuz/sensörünüz hakkında daha fazla bilgi içeren bir web siteniz varsa, istasyonunuzu görmek için kullanıldığında bu bağlantıyı haritamıza ekleyeceğiz

org.name string optional

Bir web sitesi belirtirseniz, bu "kuruluş adı" web sitesiyle ilişkilendirilecektir.

readings
readings[*].specie string mandatory

Bildirdiğiniz kirleticinin adı. Gaz sensörleri için şunu kullanın: "pm2.5", "pm10", "pm1.0", ... Gaz sensörü için şunu kullanın: "co2", "no2", "o3", ... Hava sensörü için şunu kullanın: "sıcaklık", "nem", "basınç", "rüzgar hızı", "rüzgar esintisi", "rüzgar yönü", ..
Aslında istediğiniz herhangi bir tür adını kullanabilirsiniz. İstasyonunuz doğrulandığında, adlar sistemimizde normalleştirilecektir.

readings[*].value float mandatory

Sensörünüz her saniye değer üretiyorsa ve siz sadece her dakika yükleme yapıyorsanız, bu değer geçen dakika içerisinde okunan tüm değerlerin ortalaması olmalıdır.

readings[*].unit string optional

Değerin birimi. Örn. toz sensörü için "mg/m3", gaz sensörü için ppb, sıcaklık sensörü için C..

readings[*].time string optional

ISO 8601 formatında okumanın tarihi ve saati

readings[*].min float optional

Eğer okuma değerleri birden fazla değerin ortalamasına dayanıyorsa bu, ortalama için kullanılan tüm değerlerin en küçük değerine karşılık gelir.

readings[*].max float optional

Eğer okuma değerleri birden fazla değerin ortalamasına dayanıyorsa, bu ortalamanın alınmasında kullanılan tüm değerlerin en büyüğüne karşılık gelir.

readings[*].median float optional

Eğer okuma değerleri birden fazla değerin ortalamasına dayanıyorsa bu, ortalama almada kullanılan tüm değerlerin medyan değerine karşılık gelir.

readings[*].stddev float optional

Eğer okuma değerleri birden fazla değerin ortalamasına dayanıyorsa bu, ortalamanın alınmasında kullanılan tüm değerlerin standart sapmasına karşılık gelir.

readings[*].averaging float optional

Yukarıdaki değerler birden fazla değerin ortalamasına dayanıyorsa bu, ortalama periyodunun saniye cinsinden süresine karşılık gelir.
Örneğin, dakikalık ortalama veriler için 60, saatlik ortalama veriler için 3600 kullanın.

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

Örnek 2

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

Tam Kod örneği

Bu kodu bir SDS sensöründen sürekli okumak ve her dakika yüklemek için kullanabilirsiniz: (komut dosyası ayrıca https://github.com/aqicn/sds-sensor-reader adresinden de edinilebilir).

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) 
 

Bölgenizde Hava Kalitesi istasyonları biliyor musunuz?
Neden kendi hava kalitesi istasyonunuzla haritaya katılmıyorsunuz?

GAIA hava kalitesi monitörlerimizin kurulumu çok kolaydır: Yalnızca bir WIFI erişim noktasına ve USB uyumlu bir güç kaynağına ihtiyacınız vardır.

Bağlandıktan sonra gerçek zamanlı hava kirliliği seviyeleriniz haritalarda ve API aracılığıyla anında görüntülenir.

İstasyon, 10 metrelik su geçirmez bir güç kablosu, bir USB güç kaynağı, montaj ekipmanı ve isteğe bağlı bir güneş paneli ile birlikte gelir.

Hava Kalitesi ve Kirlilik Ölçümü Hakkında:

Hava Kalitesi Seviyeleri Hakkında

- Hava Kalitesi İndeksi (AQI) DeğerleriSağlık Endişesinin Düzeyleri
0 - 50 İyi Hava kalitesi tatmin edici kabul edilmekte ve hava kirliliği çok az veya hiç risk oluşturmamakta.
51 -100 Orta Hava kalitesi kabul edilebilir; ancak bazı kirleticiler hava kirliliğine karşı alışılmadık derecede hassas olan çok az sayıda insan için orta derecede sağlık sorunu oluşturabilir.
101-150 Sağlıksız hassas gruplar için Hassas gruplar sağlık sorunları yaşayabilir. Genel halkın etkilenmesi olası değildir.
151-200 Sağlıksız Herkesin sağlığı etkilenmeye başlayabilir; hassas gruptakiler daha ciddi sağlık etkileri yaşayabilir
201-300 Çok sağlıksız Acil durum sağlık uyarıları. Tüm nüfusun etkilenmesi daha olasıdır.
300+ Tehlikeli Sağlık uyarısı: Herkes daha ciddi sağlık etkileri yaşayabilir

Hava Kalitesi ve Kirlilik hakkında daha fazla bilgi edinmek için Wikipedia Hava Kalitesi konusuna veya Airnow Hava Kalitesi ve Sağlığınız kılavuzuna bakın.

Pekin Doktoru Richard Saint Cyr MD'nin çok faydalı sağlık tavsiyeleri için www.myhealthbeijing.com bloguna bakın.


Kullanım Uyarısı: Hava Kalitesi verileri yayınlandıkları esnada doğrulanmamıştır ve kalite güvencesi nedeniyle bu veriler herhangi bir zamanda haber verilmeksizin değiştirilebilir. Dünya Hava Kalitesi Endeksi projesi, bu bilgilerin içeriğinin derlenmesinde tüm makul beceriyi ve özeni göstermiştir ve hiçbir koşulda Dünya Hava Kalitesi İndeksi proje ekibi veya temsilcileri, bu verilerin temininden doğrudan veya dolaylı olarak doğan herhangi bir kayıp, yaralanma veya hasar için taahhüt, tazmin veya başka bir şekilde sorumlu tutulamaz.



Settings


Language Settings:


Temperature unit:
Celcius