API Unggah Data & Skrip Sampel

Langkah pertama adalah mendapatkan token dari halaman platform data .

Setelah Anda memiliki token sendiri, Anda dapat menggunakan skrip berikut untuk mengunggah data Anda. Setelah Anda mengunggah data stasiun pertama Anda, kunjungi aqicn.org/data-feed/verification/ untuk mengonfigurasi stasiun Anda dan memverifikasi data yang diunggah.

Platform Perangkat Lunak yang Didukung:

Kami menyediakan software siap pakai untuk 3 platform tersebut:

  • Arduino : Jika Anda memiliki CPU Arduino, gunakan perangkat lunak siap pakai yang tersedia di github.com di aqicn/gaia-a08-arduino .
  • Python: Gunakan cuplikan kode di bawah ini
  • Baris perintah (CURL): Gunakan cuplikan kode di bawah ini

Jika Anda tidak memiliki stasiun pemantauan apa pun, dan ingin memilikinya, periksa stasiun pemantauan Kualitas Udara GAIA kami.

Jika Anda lebih menyukai stasiun DIY, periksa GAIA A08 .


--

Kode contoh (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) 

Contoh kode (ikal)

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

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

Opsi API

Parameter Type Optional/Mandatory Explanations
token string mandatory

Dapatkan token Anda sendiri dari aqicn.org/data-platform/token .

station
station.id string mandatory

ID stasiun unik - Anda dapat memilih nama apa pun dengan maksimal 128 karakter.
Nama ini hanya digunakan secara internal untuk Anda. Tidak ada orang lain yang akan melihat ID ini

station.name string optional

Nama stasiun - misalnya nama gedung Anda, nama jalan, nama jurusan universitas, kode stasiun cuaca pribadi Anda.
Nama ini akan digunakan sebagai akhiran untuk URL stasiun Anda.

station.latitude float optional

Bujur stasiun Anda

station.longitude float optional

Bujur stasiun Anda

organization
org.website string optional

Jika Anda memiliki situs web dengan informasi lebih lanjut tentang stasiun/sensor Anda, kami akan menambahkan tautan ini di peta kami saat digunakan untuk melihat stasiun Anda

org.name string optional

Jika Anda menentukan situs web, "nama organisasi" ini akan dikaitkan dengan situs web tersebut.

readings
readings[*].specie string mandatory

Nama polutan yang Anda laporkan. Untuk sensor gas, gunakan: "pm2.5", "pm10", "pm1.0", ... Untuk sensor gaz, gunakan: "co2", "no2", "o3", ... Untuk sensor cuaca, gunakan: "suhu", "kelembaban", "tekanan", "kecepatan angin", "hembusan angin", "arah angin", ..
Anda sebenarnya dapat menggunakan nama spesies apa pun yang Anda inginkan. Ketika stasiun Anda divalidasi, nama-nama tersebut akan dinormalisasi di sistem kami.

readings[*].value float mandatory

Jika sensor Anda menghasilkan nilai setiap detik, dan Anda hanya mengunggah setiap menit, nilai ini harus menjadi rata-rata dari semua nilai yang dibaca selama satu menit terakhir.

readings[*].unit string optional

Satuan nilai. Misal "mg/m3" untuk sensor debu, ppb untuk sensor gas, C untuk sensor suhu..

readings[*].time string optional

Tanggal dan Waktu pembacaan dalam format ISO 8601

readings[*].min float optional

Jika nilai pembacaan didasarkan pada rata-rata beberapa nilai, maka ini sesuai dengan nilai min dari semua nilai yang digunakan untuk rata-rata.

readings[*].max float optional

Jika pembacaan nilai didasarkan pada rata-rata beberapa nilai, maka ini sesuai dengan nilai maksimal dari semua nilai yang digunakan untuk rata-rata.

readings[*].median float optional

Jika pembacaan nilai didasarkan pada rata-rata beberapa nilai, maka nilai tersebut sesuai dengan nilai median dari semua nilai yang digunakan untuk rata-rata.

readings[*].stddev float optional

Jika pembacaan nilai didasarkan pada rata-rata beberapa nilai, maka ini sesuai dengan simpangan baku semua nilai yang digunakan untuk rata-rata.

readings[*].averaging float optional

Jika nilai-nilai di atas didasarkan pada rata-rata beberapa nilai, maka ini sesuai dengan durasi, dalam detik, dari periode rata-rata.
Misalnya, gunakan 60 untuk data rata-rata satu menit dan 3600 untuk rata-rata per jam.

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

Contoh 2

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

Contoh Kode Lengkap

Anda dapat menggunakan kode ini untuk terus membaca dari sensor SDS, dan mengunggah setiap menit: (skrip juga tersedia dari 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) 
 

Tahukah Anda stasiun Kualitas Udara di daerah Anda?
mengapa tidak berpartisipasi dalam peta dengan stasiun kualitas udara Anda sendiri?

Monitor kualitas udara GAIA kami sangat mudah diatur: Anda hanya memerlukan titik akses WIFI dan catu daya yang kompatibel dengan USB.

Setelah terhubung, tingkat polusi udara real-time Anda langsung tersedia di peta dan melalui API.

Stasiun ini dilengkapi dengan kabel listrik tahan air sepanjang 10 meter, catu daya USB, peralatan pemasangan, dan panel surya opsional.

Tentang Pengukuran Kualitas dan Polusi Udara:

Tentang Tingkat Kualitas Udara

- Nilai Indeks Kualitas Udara (AQI).Tingkat Kekhawatiran Kesehatan
0 - 50 Baik Kualitas udara dianggap memuaskan, dan polusi udara menimbulkan sedikit atau tanpa risiko
51 -100 Moderat Kualitas udara dapat diterima; Namun, untuk beberapa polutan mungkin ada kekhawatiran kesehatan yang moderat untuk sejumlah kecil orang yang sangat sensitif terhadap polusi udara.
101-150 Tidak Sehat untuk kelompok orang yang sensitif Anggota kelompok sensitif dapat mengalami efek kesehatan. Masyarakat umum tidak mungkin terpengaruh.
151-200 Tidak sehat Setiap orang mungkin mulai mengalami efek kesehatan; anggota kelompok sensitif dapat mengalami efek kesehatan yang lebih serius
201-300 Sangat Tidak Sehat Peringatan kesehatan untuk kondisi darurat. Seluruh penduduk lebih mungkin terpengaruh.
300+ Berbahaya Peringatan kesehatan: semua orang mungkin mengalami efek kesehatan yang lebih serius

Untuk mengetahui lebih banyak tentang Kualitas dan Polusi Udara, lihat topik Kualitas Udara di wikipedia atau panduan airnow tentang Kualitas Udara dan Kesehatan Anda .

Untuk nasihat kesehatan yang sangat berguna dari Dokter Beijing Richard Saint Cyr MD, periksa blog www.myhealthbeijing.com .


Pemberitahuan Penggunaan: Semua data Kualitas Udara tidak divalidasi pada saat publikasi, dan demi jaminan kualitas maka data ini dapat diubah, tanpa pemberitahuan, kapan saja. Proyek Indeks Kualitas Udara Dunia telah menerapkan semua kemampuan dan kepedulian yang cukup dalam mengumpulkan isi informasi ini dan dalam keadaan apa pun World Air Quality Index tim proyek atau agennya bertanggung jawab dalam kontrak, gugatan atau jika ada kerugian, cedera atau kerusakan yang timbul secara langsung atau tidak langsung dari pasokan data ini.



Settings


Language Settings:


Temperature unit:
Celcius