API загрузки данных и примеры сценариев

Первый шаг — получить токен на странице платформы данных.

Если у вас есть собственный токен, вы можете использовать следующий скрипт для загрузки своих данных. После загрузки данных первой станции перейдите на сайт aqicn.org/data-feed/verification/, чтобы настроить станции и проверить загруженные данные.

Поддерживаемые программные платформы:

Мы предоставляем готовое к использованию программное обеспечение для этих трех платформ:

  • Arduino. Если у вас есть процессор Arduino, используйте готовое к использованию программное обеспечение, доступное на github.com по адресу aqicn/gaia-a08-arduino.
  • Python: используйте приведенный ниже фрагмент кода.
  • Командная строка (CURL): используйте приведенный ниже фрагмент кода.

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

Если вы предпочитаете станцию, сделанную своими руками, обратите внимание на GAIA A08.


--

Пример кода (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) 

Пример кода (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}]\ 
}'

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

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

Parameter Type Optional/Mandatory Explanations
token string mandatory

Получите свой собственный токен на сайте aqicn.org/data-platform/token.

station
station.id string mandatory

Уникальный идентификатор станции – вы можете выбрать любое имя длиной не более 128 символов.
Это имя используется только для вашего внутреннего использования. Никто больше не увидит этот идентификатор

station.name string optional

Название станции - это может быть, например, название вашего здания, название улицы, название факультета университета, код вашей личной метеостанции.
Это имя будет использоваться в качестве суффикса URL-адреса вашей станции.

station.latitude float optional

Долгота вашей станции

station.longitude float optional

Долгота вашей станции

organization
org.website string optional

Если у вас есть веб-сайт с дополнительной информацией о вашей станции/датчике, мы добавим эту ссылку на нашу карту, когда она будет использоваться для просмотра вашей станции.

org.name string optional

Если вы укажете веб-сайт, это «название организации» будет связано с веб-сайтом.

readings
readings[*].specie string mandatory

Название загрязнителя, о котором вы сообщаете. Для датчиков газа используйте: «pm2.5», «pm10», «pm1.0», ... Для датчика газа используйте: «co2», «no2», «o3», ... Для датчика погоды используйте: «температура», «влажность», «давление», «скорость ветра», «порыв ветра», «направление ветра», ..
На самом деле вы можете использовать любое название вида, какое захотите. Когда ваша станция будет проверена, имена будут нормализованы в нашей системе.

readings[*].value float mandatory

Если ваш датчик выдает значения каждую секунду, а вы загружаете данные только каждую минуту, это значение должно быть средним из всех значений, считанных за последнюю минуту.

readings[*].unit string optional

Единица стоимости. Например, «мг/м3» для датчика пыли, ppb для датчиков газа, C для датчика температуры.

readings[*].time string optional

Дата и время считывания в формате ISO 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":"2024-04-28T19:29:13+09:00","specie":"pm2.5", "value": 393.3, "unit":"mg/m3", "min":390.3, "max": 402.3, "stddev": 0.332},  
		{"time":"2024-04-28T19:29:13+09:00","specie":"pm10", "value": 109.3, "unit":"mg/m3"}, 
		{"time":"2024-04-28T19:29:13+09:00","specie":"co2", "value": 459.3, "unit":"ppb"}, 
		{"time":"2024-04-28T19:29:13+09:00","specie":"temp", "value": 26.8, "unit":"C"}, 
	] 
}

Пример 2

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

Полный пример кода

Вы можете использовать этот код для непрерывного считывания с датчика SDS и загрузки каждую минуту: (сценарий также доступен по адресу 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) 
 

Измерьте качество воздуха в вашем районе
Участвуйте с собственной станцией мониторинга качества воздуха

Монитор качества воздуха GAIA использует лазерные датчики частиц для измерения в режиме реального времени загрязнения частицами PM2,5 и PM10, которые являются одними из наиболее вредных загрязнителей воздуха.

Его очень легко настроить: требуется только точка доступа WIFI и источник питания, совместимый с USB. После подключения ваши уровни загрязнения воздуха в реальном времени мгновенно отображаются на наших картах.

В комплект поставки станции входят 10-метровые водонепроницаемые силовые кабели, источник питания, монтажное оборудование и дополнительная солнечная панель.

О качестве воздуха и измерениях загрязнения:

О уровнях качества воздуха

- Индекс качества воздуха (ИКВ = AQI) ЗначенияУровни концерна здравоохранения
0 - 50 хорошо Качество воздуха считается удовлетворительным, и загрязнение воздуха представляется незначительным в пределах нормы.
51 -100 удовлетворительное Качество воздуха является приемлемым; однако некоторые загрязнители могут представлять опасность для людей, являющихся особо чувствительным к загрязнению воздуха.
101-150 Нездоровый для чувствительных групп Может оказывать эффект на особо чувствительную группу лиц. На среднего представителя не оказывает видимого воздействия.
151-200 нездоровый Каждый может начать испытывать последствия для своего здоровья; особо чувствительные люди могут испытывать более серьезные последствия.
201-300 Очень Нездоровый Опасность для здоровья от чрезвычайных условий. Это отразится, вероятно, на всем населении.
300+ опасный Опасность для здоровья: каждый человек может испытывать более серьезные последствия для здоровья

To know more about Air Quality and Pollution, check the wikipedia Air Quality topic or the airnow guide to Air Quality and Your Health.

For very useful health advices of Beijing Doctor Richard Saint Cyr MD, check www.myhealthbeijing.com blog.


Уведомление об использовании: Все данные о качестве воздуха не подтверждены на момент публикации, и ввиду гарантии качества эти данные могут быть изменены в любое время без предварительного уведомления. Всемирный индекс качества воздуха реализовал все разумные навыки и заботу в составлении содержания этой информации и ни при каких обстоятельствах проектная группа World Air Quality Index или ее агенты не несут ответственность по контракту, деликту или иным образом за любые убытки, травмы или ущерб, возникшие прямо или косвенно от предоставления этих данных.



Настройки


Настройка языка:


Temperature unit:
Celcius