Tập lệnh mẫu và API tải lên dữ liệu

Bước đầu tiên là nhận mã thông báo từ trang nền tảng dữ liệu.

Sau khi có mã thông báo của riêng mình, bạn có thể sử dụng tập lệnh sau để tải dữ liệu của mình lên. Sau khi bạn tải lên dữ liệu trạm đầu tiên của mình, hãy truy cập aqicn.org/data-feed/verification/ để định cấu hình các trạm của bạn và xác minh dữ liệu đã tải lên.

Nền tảng phần mềm được hỗ trợ:

Chúng tôi cung cấp phần mềm sẵn sàng để sử dụng cho 3 nền tảng đó:

  • Arduino: Nếu bạn có CPU Arduino, hãy sử dụng phần mềm sẵn sàng sử dụng có sẵn trên github.com tại aqicn/gaia-a08-arduino.
  • Python: Sử dụng đoạn mã bên dưới
  • Dòng lệnh (CURL): Sử dụng đoạn mã bên dưới

Nếu bạn không có trạm giám sát nào và muốn có một trạm, hãy kiểm tra các trạm giám sát Chất lượng Không khí GAIA của chúng tôi.

Nếu bạn thích trạm tự làm, hãy kiểm tra GAIA A08.


--

Mã mẫu (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) 

Mã mẫu (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}]\ 
}'

Mã mẫu (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(); 
}

Tùy chọn API

Parameter Type Optional/Mandatory Explanations
token string mandatory

Nhận mã thông báo của riêng bạn từ aqicn.org/data-platform/token.

station
station.id string mandatory

ID trạm duy nhất - bạn có thể chọn bất kỳ tên nào có tối đa 128 ký tự.
Tên này chỉ được sử dụng nội bộ cho bạn. Sẽ không có ai khác nhìn thấy ID này

station.name string optional

Tên của trạm - ví dụ có thể là tên tòa nhà của bạn, tên đường phố, tên khoa của trường đại học, mã trạm thời tiết cá nhân của bạn.
Tên này sẽ được sử dụng làm hậu tố cho URL đài của bạn.

station.latitude float optional

Kinh độ của trạm của bạn

station.longitude float optional

Kinh độ của trạm của bạn

organization
org.website string optional

Nếu bạn có một trang web có thêm thông tin về trạm/cảm biến của mình, chúng tôi sẽ thêm liên kết này trên bản đồ của chúng tôi khi sử dụng để xem trạm của bạn

org.name string optional

Nếu bạn chỉ định một trang web, "tên tổ chức" này sẽ được liên kết với trang web đó.

readings
readings[*].specie string mandatory

Tên chất gây ô nhiễm mà bạn đang báo cáo. Đối với cảm biến khí sử dụng: "pm2.5", "pm10", "pm1.0", ... Đối với cảm biến gaz sử dụng: "co2", "no2", "o3", ... Đối với cảm biến thời tiết, sử dụng: "nhiệt độ", "độ ẩm", "áp suất", "tốc độ gió", "gió giật", "hướng gió", ..
Bạn thực sự có thể sử dụng bất kỳ tên loài nào bạn muốn. Khi trạm của bạn được xác thực, tên sẽ được chuẩn hóa trong hệ thống của chúng tôi.

readings[*].value float mandatory

Nếu cảm biến của bạn tạo ra các giá trị mỗi giây và bạn chỉ tải lên mỗi phút thì giá trị này sẽ là giá trị trung bình của tất cả các giá trị được đọc trong phút vừa qua.

readings[*].unit string optional

Đơn vị của giá trị Ví dụ: "mg/m3" cho cảm biến bụi, ppb cho cảm biến khí, C cho cảm biến nhiệt độ..

readings[*].time string optional

Ngày và giờ đọc ở định dạng ISO 8601

readings[*].min float optional

Nếu các giá trị đọc được dựa trên việc lấy trung bình của một số giá trị thì giá trị này tương ứng với giá trị nhỏ nhất của tất cả các giá trị được sử dụng để lấy trung bình.

readings[*].max float optional

Nếu các giá trị đọc được dựa trên việc lấy trung bình của một số giá trị thì giá trị này tương ứng với giá trị tối đa của tất cả các giá trị được sử dụng để lấy trung bình.

readings[*].median float optional

Nếu các giá trị đọc được dựa trên việc lấy trung bình của một số giá trị thì giá trị này tương ứng với giá trị trung bình của tất cả các giá trị được sử dụng để lấy trung bình.

readings[*].stddev float optional

Nếu các giá trị đọc được dựa trên việc lấy trung bình của một số giá trị thì giá trị này tương ứng với độ lệch chuẩn của tất cả các giá trị được sử dụng để lấy trung bình.

readings[*].averaging float optional

Nếu các giá trị trên dựa trên việc lấy trung bình của một số giá trị thì giá trị này tương ứng với khoảng thời gian tính bằng giây của khoảng thời gian lấy trung bình.
Ví dụ: sử dụng 60 cho dữ liệu trung bình một phút và 3600 cho dữ liệu trung bình hàng giờ.

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

Ví dụ 2

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

Ví dụ về mã hoàn chỉnh

Bạn có thể sử dụng mã này để đọc liên tục từ cảm biến SDS và tải lên mỗi phút: (tập lệnh cũng có sẵn từ 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) 
 

Bạn có biết bất kỳ trạm đo chất lượng không khí nào ở khu vực của bạn không?
Tại sao không tham gia vào bản đồ với trạm chất lượng không khí của riêng bạn?

Thiết bị giám sát chất lượng không khí GAIA của chúng tôi rất dễ cài đặt: Bạn chỉ cần điểm truy cập WIFI và nguồn điện tương thích USB.

Sau khi kết nối, mức độ ô nhiễm không khí theo thời gian thực của bạn sẽ hiển thị ngay lập tức trên bản đồ và thông qua API.

Trạm đi kèm với cáp nguồn chống nước dài 10 mét, nguồn điện USB, thiết bị lắp đặt và bảng điều khiển năng lượng mặt trời tùy chọn.

Về phương pháp đo chất lượng không khí và mức độ ô nhiễm:

Về các thang đo chất lượng không khí

- Giá trị chỉ số chất lượng không khí (AQI)Mức độ ảnh hưởng sức khỏe
0 - 50 Tốt Chất lượng không khí được xem là đạt tiêu chuẩn, và ô nhiễm không khí coi như không hoặc gây rất ít nguy hiểm
51 -100 Trung bình Chất lượng không khí ở mức chấp nhận được; tuy nhiên, một số chất gây ô nhiễm có thể ảnh hưởng tới sức khỏe của một số ít những người nhạy cảm với không khí bị ô nhiễm.
101-150 Không tốt cho người nhạy cảm Nhóm người nhạy cảm có thể chịu ảnh hưởng sức khỏe. Số đông không có nguy cơ bị tác động.
151-200 Có hại cho sức khỏe Mỗi người đều có thể sẽ chịu tác động đến sức khỏe; nhóm người nhạy cảm có thể bị ảnh hưởng nghiêm trọng hơn.
201-300 Rất có hại cho sức khỏe Cảnh báo nguy hại sức khỏe nghiêm trọng. Đa số mọi người đều bị ảnh hưởng.
300+ Nguy hiểm Cảnh báo sức khỏe: tất cả mọi người có thể chịu tác động nghiêm trọng đến sức khỏe

Để biết thêm về ô nhiễm và chất lượng không khí , xem wikipedia chất lượng không khí đang đề hoặc hướng dẫn về chất lượng không khí và sức khỏe của bạn .

Để biết những lời khuyên về sức khỏe rất hữu ích của bác sĩ y khoa Richard Saint Cyr ở Bắc Kinh, xem www.myhealthbeijing.com blog.


Thông báo sử dụng: Tất cả dữ liệu chất lượng không khí không được xác thực tại thời điểm công bố. Nhằm đảm bảo chất lượng, những dữ liệu này có thể được cập nhập mà không cần thông báo trước. Nhóm dự án Chỉ số chất lượng không khí toàn cầu đã thực hiện tất cả yêu cầu cần thiết trong việc biên soạn các thông tin này. Nhóm dự án hoặc các bên liên quan sẽ không chịu trách nhiệm về bất kỳ tổn thất, thương tích hoặc thiệt hại nào phát sinh trực tiếp hoặc gián tiếp từ việc cung cấp những dữ liệu này trong bất kỳ trường hợp nào.



Cài đặt


Cài đặt ngôn ngữ:


Temperature unit:
Celcius