АПИ за отпремање података и узорци скрипти

Први корак је да добијете токен са странице платформе података .

Када будете имали сопствени токен, можете користити следећу скрипту да отпремите своје податке. Након што отпремите своје прве податке станице, идите на акицн.орг/ дата-феед/верифицатион/ да бисте конфигурисали своје станице и верификовали отпремљене податке.

Подржане софтверске платформе:

Пружамо софтвер спреман за употребу за те 3 платформе:

  • Ардуино : Ако имате Ардуино ЦПУ, користите софтвер спреман за употребу доступан на гитхуб.цом на акицн/гаиа-а08-ардуино .
  • Питхон: Користите исечак кода испод
  • Командна линија (ЦУРЛ): Користите исечак кода испод

Ако немате ниједну станицу за надзор, а желите да је набавите, проверите наше ГАИА станице за праћење квалитета ваздуха.

Ако више волите „уради сам“ станицу, проверите ГАИА А08 .


--

Пример кода (питхон)

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)

Пример кода (цурл)

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

Пример кода (ардуино)

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

АПИ опције

Parameter Type Optional/Mandatory Explanations
token string mandatory

Набавите сопствени токен са акицн.орг/дата-платформ/токен .

station
station.id string mandatory

Јединствени ИД станице - можете изабрати било које име са највише 128 карактера.
Ово име се користи само интерно за вас. Нико други неће видети овај ИД

station.name string optional

Назив станице - може бити на пример назив ваше зграде, назив улице, назив универзитетског одељења, шифра ваше личне метеоролошке станице.
Ово име ће се користити као суфикс за УРЛ ваше станице.

station.latitude float optional

Географска дужина ваше станице

station.longitude float optional

Географска дужина ваше станице

organization
org.website string optional

Ако имате веб локацију са више информација о вашој станици/сензору, додаћемо ову везу на нашу мапу када се користи погледајте вашу станицу

org.name string optional

Ако наведете веб локацију, ово „име организације“ ће бити повезано са веб локацијом.

readings
readings[*].specie string mandatory

Назив загађивача који пријављујете. За сензоре гаса користите: "пм2.5", "пм10", "пм1.0", ... За сензор гаса користите: "цо2", "но2", "о3", ... За временске сензоре, користите: "температура", "влажност", "притисак", "брзина ветра", "налет ветра", "смер ветра", ..
Заправо можете користити било које име врсте које желите. Када ваша станица буде валидирана, имена ће бити нормализована у нашем систему.

readings[*].value float mandatory

Ако ваш сензор производи вредности сваке секунде, а отпремате само сваког минута, ова вредност би требало да буде просек свих вредности очитаних током протеклог минута.

readings[*].unit string optional

Јединица вредности. Нпр. "мг/м3" за сензор прашине, ппб за сензоре гаса, Ц за сензор температуре..

readings[*].time string optional

Датум и време очитавања у ИСО 8601 формату

readings[*].min float optional

Ако се вредности очитавања заснивају на усредњавању неколико вредности, онда ово одговара минималној вредности свих вредности које се користе за усредњавање.

readings[*].max float optional

Ако се вредности очитавања заснивају на усредњавању неколико вредности, онда ово одговара максималној вредности свих вредности које се користе за усредњавање.

readings[*].median float optional

Ако се вредности очитавања заснивају на усредњавању неколико вредности, онда ово одговара средњој вредности свих вредности које се користе за усредњавање.

readings[*].stddev float optional

Ако се вредности очитавања заснивају на усредњавању неколико вредности, онда то одговара стандардној девијацији свих вредности које се користе за усредњавање.

readings[*].averaging float optional

Ако су горње вредности засноване на усредњавању неколико вредности, онда то одговара трајању периода усредњавања у секундама.
На пример, користите 60 за просечне податке за минут и 3600 за просек по сату.

Пример 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-29T14:20:26+09:00","specie":"pm2.5", "value": 393.3, "unit":"mg/m3", "min":390.3, "max": 402.3, "stddev": 0.332},
{"time":"2025-04-29T14:20:26+09:00","specie":"pm10", "value": 109.3, "unit":"mg/m3"},
{"time":"2025-04-29T14:20:26+09:00","specie":"co2", "value": 459.3, "unit":"ppb"},
{"time":"2025-04-29T14:20:26+09:00","specie":"temp", "value": 26.8, "unit":"C"},
]
}

Пример 2

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

Комплетан пример кода

Можете користити овај код за непрекидно читање са СДС сензора и отпремање сваког минута: (скрипта је такође доступна са хттпс: //гитхуб.цом/акицн/сдс-сенсор-реадер ).

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)

Да ли знате за неке станице за квалитет ваздуха у вашем крају?
зашто не бисте учествовали на мапи са својом станицом за квалитет ваздуха?

Наши ГАИА монитори квалитета ваздуха се веома лако подешавају: потребна вам је само ВИФИ приступна тачка и УСБ компатибилно напајање.

Када се повежете, ваши нивои загађења ваздуха у реалном времену су тренутно доступни на мапама и преко АПИ-ја.

Станица долази са водоотпорним каблом за напајање од 10 метара, УСБ напајањем, опремом за монтажу и опционим соларним панелом.

О мерењу квалитета ваздуха и загађења:

О нивоима квалитета ваздуха

- Вредности индекса квалитета ваздуха (АКИ).Нивои здравствене бриге
0 - 50 Добро Квалитет ваздуха се сматра задовољавајућим, а загађење ваздуха представља мали или никакав ризик
51 -100 Умерено Квалитет ваздуха је прихватљив; Међутим, за неке загађиваче може бити умерено забрињавајуће здравствено стање за врло мали број људи који су необично осетљиви на загађење ваздуха.
101-150 Нездраво за осетљиве групе Чланови осетљивих група могу имати здравствене последице. Општа популација вероватно неће бити погођена.
151-200 Нездрави Свако може почети да осећа здравствене тегобе; чланови осетљивих група могу имати озбиљније здравствене последице
201-300 Веома нездравим Здравствена упозорења о хитним условима. Читава популација ће бити погођена.
300+ Опасно Здравствено упозорење: свако може доживети озбиљније здравствене ефекте

Да бисте сазнали више о квалитету ваздуха и загађењу, погледајте тему на википедији о квалитету ваздуха или Аирнов водичу за квалитет ваздуха и ваше здравље .

За веома корисне здравствене савете пекиншког доктора Рицхарда Саинт Цир МД, погледајте блог ввв.михеалтхбеијинг.цом .


Употреба обавештења: Сви подаци о квалитету ваздуха су неважећи у време објављивања, а због обезбеђивања квалитета ови подаци могу бити без измењени у било ком тренутку, без обавештења. Пројектни тим "Светског индекса квалитета ваздуха" је уложио разуман напор и бригу приликом састављања садржаја ових информација и пројектни тим или његови агенти, ни под каквим околностима неће бити одговорни због било каквог губитка, повреде или оштећења која настају директно или индиректно из коришћења ових података.



Settings


Language Settings:


Temperature unit:
Celcius