API การอัปโหลดข้อมูลและสคริปต์ตัวอย่าง

ขั้นตอนแรกคือการรับโทเค็นจาก หน้า data-platform

เมื่อคุณมีโทเค็นของคุณเองแล้ว คุณสามารถใช้สคริปต์ต่อไปนี้เพื่ออัปโหลดข้อมูลของคุณได้ หลังจากที่คุณอัปโหลดข้อมูลสถานีแรกของคุณแล้ว ให้ไปที่ aqicn.org/data-feed/verification/ เพื่อกำหนดค่าสถานีของคุณและยืนยันข้อมูลที่อัปโหลด

แพลตฟอร์มซอฟต์แวร์ที่รองรับ:

เราจัดเตรียมซอฟต์แวร์พร้อมใช้งานสำหรับแพลตฟอร์มทั้ง 3 นี้:

  • Arduino : หากคุณมี CPU Arduino ให้ใช้ซอฟต์แวร์พร้อมใช้งานบน github.com ที่ aqicn/gaia-a08-arduino
  • Python: ใช้โค้ดตัวอย่างด้านล่างนี้
  • บรรทัดคำสั่ง (CURL): ใช้โค้ดสั้นๆ ด้านล่างนี้

หากคุณไม่มีสถานีตรวจสอบและต้องการมีสถานีดังกล่าว โปรดดูสถานีตรวจสอบคุณภาพอากาศ GAIA ของเรา

หากคุณชอบสถานีแบบ DIY ลองดู 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}]\
}'

โค้ดตัวอย่าง (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

Parameter Type Optional/Mandatory Explanations
token string mandatory

รับโทเค็นของคุณเองจาก aqicn.org/data-platform/token

station
station.id string mandatory

รหัสสถานีที่ไม่ซ้ำกัน - คุณสามารถเลือกชื่อใดก็ได้โดยสามารถมีตัวอักษรได้สูงสุด 128 ตัวอักษร
ชื่อนี้ใช้ภายในสำหรับคุณเท่านั้น ไม่มีใครจะเห็น ID นี้

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

หน่วยของค่า เช่น "mg/m3" สำหรับเซ็นเซอร์ฝุ่น 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 สำหรับข้อมูลค่าเฉลี่ยหนึ่งนาทีและ 3,600 สำหรับค่าเฉลี่ยรายชั่วโมง

ตัวอย่างที่ 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-02-19T12:45:16+09:00","specie":"pm2.5", "value": 393.3, "unit":"mg/m3", "min":390.3, "max": 402.3, "stddev": 0.332},
{"time":"2025-02-19T12:45:16+09:00","specie":"pm10", "value": 109.3, "unit":"mg/m3"},
{"time":"2025-02-19T12:45:16+09:00","specie":"co2", "value": 459.3, "unit":"ppb"},
{"time":"2025-02-19T12:45:16+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 ของเราติดตั้งง่ายมาก: คุณเพียงแค่ต้องมีจุดเข้าใช้งาน WiFi และแหล่งจ่ายไฟที่รองรับ USB เท่านั้น

เมื่อเชื่อมต่อแล้ว ระดับมลพิษทางอากาศแบบเรียลไทม์จะแสดงบนแผนที่และผ่าน API ทันที

สถานีดังกล่าวมาพร้อมกับสายไฟกันน้ำความยาว 10 เมตร แหล่งจ่ายไฟ USB อุปกรณ์ติดตั้ง และแผงโซลาร์เซลล์ที่เป็นอุปกรณ์เสริม

เกี่ยวกับการตรวจวัดคุณภาพอากาศและมลพิษ:

เกี่ยวกับระดับคุณภาพอากาศ

- ค่าดัชนีคุณภาพอากาศ (AQI)ระดับความกังวลเรื่องสุขภาพ
0 - 50 ดี คุณภาพอากาศถือว่าเป็นที่น่าพอใจและมลพิษทางอากาศทำให้เกิดความเสี่ยงเพียงเล็กน้อยหรือไม่มีเลย
51 -100 ปานกลาง คุณภาพอากาศเป็นที่ยอมรับได้ อย่างไรก็ตามสำหรับสารมลพิษบางอย่างอาจต้องระวังในกลุ่มผู้ที่แพ้ฝุ่นละอองและสารเคมีได้ง่าย
101-150 ไม่ดีต่อสุขภาพ สำหรับ กลุ่มที่ไวต่อมลพิษทางอากาศ หรือกลุ่มที่แพ้อากาศง่าย อาจมีผลกระทบต่อสุขภาพของประชาชนกลุ่มเสี่ยง ส่วนประชาชนทั่วไปอาจไม่ได้รับผลกระทบ
151-200 มีผลกระทบต่อสุขภาพ เราทุกคนอาจเริ่มรู้สึกถึงผลกระทบต่อสุขภาพ กลุ่มคนที่มีความเสี่ยงสูงอาจได้รับผลกระทบด้านสุขภาพที่รุนแรงขึ้น
201-300 อันตรายต่อสุขภาพเป็นอย่างมาก คำเตือนด้านสุขภาพในภาวะฉุกเฉิน ประชากรทั้งหมดมีแนวโน้มที่จะได้รับผลกระทบมากขึ้น
300+ เสี่ยงอันตราย การแจ้งเตือนด้านสุขภาพ: ทุกคนอาจได้รับผลกระทบด้านสุขภาพที่รุนแรงขึ้น

หากต้องการทราบข้อมูลเพิ่มเติมเกี่ยวกับคุณภาพอากาศและมลพิษ โปรดดู หัวข้อคุณภาพอากาศในวิกิพีเดีย หรือ คู่มือ airnow เกี่ยวกับคุณภาพอากาศและสุขภาพของคุณ

หากต้องการคำแนะนำด้านสุขภาพที่เป็นประโยชน์มากของแพทย์ปักกิ่ง Richard Saint Cyr MD โปรดดูบล็อกที่ www.myhealthbeijing.com


ประกาศเกี่ยวกับการใช้งาน: ข้อมูลคุณภาพอากาศทั้งหมดอาจจะยังไม่ได้รับการตรวจสอบในขณะที่มีการเผยแพร่และเนื่องจากการตรวจสอบข้อมูลเหล่านี้อาจได้รับการแก้ไขโดยไม่ต้องแจ้งให้ทราบได้ตลอดเวลา โครงการ World Air Quality Index ได้ระมัดระวังเรื่องความเหมาะสมในการรวบรวมเนื้อหาของข้อมูลนี้และภายใต้การควบคุมของทีมงานโครงการWorld Air Quality Indexหรือตัวแทนของโครงการจะรับผิดชอบต่อการทำสัญญาละเมิดหรืออื่น ๆ สำหรับการสูญเสียการบาดเจ็บหรือความเสียหายที่เกิดขึ้นโดยตรงหรือโดยอ้อมจากการจัดหาข้อมูลนี้



Settings


Language Settings:


Temperature unit:
Celcius