Data Upload API i uzorci skripti

Prvi korak je da dobijete token sa stranice platforme podataka .

Nakon što imate vlastiti token, možete koristiti sljedeću skriptu za učitavanje podataka. Nakon što učitate svoje prve podatke o stanici, idite na aqicn.org/data-feed/verification/ da konfigurišete svoje stanice i potvrdite učitane podatke.

Podržane softverske platforme:

Nudimo softver spreman za korištenje za ove 3 platforme:

  • Arduino : Ako imate Arduino CPU, koristite softver spreman za korištenje dostupan na github.com na aqicn/gaia-a08-arduino .
  • Python: Koristite isječak koda ispod
  • Komandna linija (CURL): Koristite isječak koda ispod

Ako nemate nijednu stanicu za praćenje, a želite je nabaviti, provjerite naše GAIA stanice za praćenje kvaliteta zraka.

Ako više volite DIY stanicu, provjerite GAIA A08 .


--

Primjer koda (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)

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

Primjer koda (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 opcije

Parameter Type Optional/Mandatory Explanations
token string mandatory

Nabavite vlastiti token sa aqicn.org/data-platform/token .

station
station.id string mandatory

Jedinstveni ID stanice - možete odabrati bilo koje ime sa maksimalno 128 karaktera.
Ovo ime se koristi samo interno za vas. Niko drugi neće vidjeti ovaj ID

station.name string optional

Naziv stanice - može biti na primjer naziv vaše zgrade, naziv ulice, naziv univerzitetskog odsjeka, šifra vaše lične meteorološke stanice.
Ovo ime će se koristiti kao sufiks za URL vaše stanice.

station.latitude float optional

Geografska dužina vaše stanice

station.longitude float optional

Geografska dužina vaše stanice

organization
org.website string optional

Ako imate web stranicu s više informacija o vašoj stanici/senzoru, mi ćemo dodati ovu vezu na našu kartu kada se koristi pogledajte vašu stanicu

org.name string optional

Ako navedete web stranicu, ovaj "naziv organizacije" će biti povezan s web lokacijom.

readings
readings[*].specie string mandatory

Naziv zagađivača koji prijavljujete. Za senzore gasa koristite: "pm2.5", "pm10", "pm1.0", ... Za senzor gasa koristite: "co2", "no2", "o3", ... Za vremenske senzore, koristiti: "temperatura", "vlažnost", "pritisak", "brzina vjetra", "nalet vjetra", "smjer vjetra", ..
Zapravo možete koristiti bilo koje ime vrste koje želite. Kada vaša stanica bude potvrđena, imena će biti normalizovana u našem sistemu.

readings[*].value float mandatory

Ako vaš senzor proizvodi vrijednosti svake sekunde, a prenosite samo svake minute, ova vrijednost bi trebala biti prosjek svih vrijednosti očitanih tokom protekle minute.

readings[*].unit string optional

Jedinica vrijednosti. Npr. "mg/m3" za senzor prašine, ppb za senzore gasa, C za senzor temperature..

readings[*].time string optional

Datum i vrijeme očitavanja u ISO 8601 formatu

readings[*].min float optional

Ako se očitane vrijednosti zasnivaju na usrednjavanju nekoliko vrijednosti, onda to odgovara minimalnoj vrijednosti svih vrijednosti koje se koriste za usrednjavanje.

readings[*].max float optional

Ako se očitane vrijednosti zasnivaju na usrednjavanju nekoliko vrijednosti, onda to odgovara maksimalnoj vrijednosti svih vrijednosti koje se koriste za usrednjavanje.

readings[*].median float optional

Ako se očitane vrijednosti zasnivaju na usrednjavanju nekoliko vrijednosti, onda to odgovara srednjoj vrijednosti svih vrijednosti koje se koriste za prosječenje.

readings[*].stddev float optional

Ako se očitane vrijednosti zasnivaju na usrednjavanju nekoliko vrijednosti, onda to odgovara standardnoj devijaciji svih vrijednosti koje se koriste za usrednjavanje.

readings[*].averaging float optional

Ako se gornje vrijednosti zasnivaju na usrednjavanju nekoliko vrijednosti, onda to odgovara trajanju, u sekundama, perioda usrednjavanja.
Na primjer, koristite 60 za prosječne podatke u minuti i 3600 za prosjek po satu.

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

Primjer 2

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

Kompletan primjer koda

Možete koristiti ovaj kod za neprekidno čitanje sa SDS senzora i otpremanje svake minute: (skripta je dostupna i 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)

Znate li za neke stanice za kvalitet zraka u vašem području?
zašto ne biste učestvovali na karti sa svojom stanicom za kvalitet zraka?

Naši GAIA monitori kvaliteta zraka se vrlo lako postavljaju: potrebna vam je samo WIFI pristupna tačka i USB kompatibilno napajanje.

Jednom kada se povežete, vaši nivoi zagađenja vazduha u realnom vremenu su trenutno dostupni na kartama i preko API-ja.

Stanica dolazi sa vodootpornim kablom za napajanje od 10 metara, USB napajanjem, opremom za montažu i opcionim solarnim panelom.

O mjerenju kvalitete zraka i zagađenja:

O razinama kvalitete zraka

- Vrijednosti indeksa kvalitete zraka (AQI).Nivoi zdravstvene brige
0 - 50 Dobro Kvalitet vazduha se smatra zadovoljavajućim, a zagađenje vazduha predstavlja mali ili nikakav rizik
51 -100 Umereno Kvalitet zraka je prihvatljiv; Međutim, neki zagađivači mogu imati umjereno zabrinjavajući utjecaj na zdravstveno stanje malog broja ljudi koji su veoma osjetljivi na zagađenje zraka.
101-150 Nezdravo za osetljive grupe Može prouzrokovati zdravstvene poteškoće kod članova osjetljivih grupa. Većina verovatno neće biti pogođena.
151-200 Nezdravi Svako može početi osjećati posljedice na zdravlje; članovi osjetljivih grupa mogu imati ozbiljnije zdravstvene posljedice
201-300 Veoma nezdravim Upozorenja o hitnim slučajevima. Čitava populacija će biti pogođena.
300+ Opasno Zdravstveno upozorenje: svako može osjetiti ozbiljnije posljedice na zdravlje

Da biste saznali više o kvaliteti zraka i zagađenju, provjerite temu wikipedije o kvaliteti zraka ili airnow vodiču za kvalitet zraka i vaše zdravlje .

Za vrlo korisne zdravstvene savjete pekinškog doktora Richarda Saint Cyr MD, posjetite blog www.myhealthbeijing.com .


Upotreba: Svi podaci o kvalitetu vazduha su neverifikovani u vrijeme objavljivanja, a zbog osiguranja kvaliteta ovi podaci mogu biti izmjenjeni i dopunjeni u bilo kom trenutku. Projekat Svjetskog indeksa kvaliteta vazduha obratio je veliku pažnju prilikom sastavljanja ovih informacija i ni pod kakvim okolnostima neće biti Svjetski indeks kvaliteta vazduha projektni tim ili njegovi agenti odgovorni za ugovor, štetu ili bilo kakav gubitak, povredu ili štetu nastalu direktno ili indirektno iz snabdevanja ovim podacima.



Settings


Language Settings:


Temperature unit:
Celcius