Μεταφόρτωση δεδομένων API & Δείγματα σεναρίων

Το πρώτο βήμα είναι να λάβετε ένα διακριτικό από τη σελίδα πλατφόρμας δεδομένων.

Αφού αποκτήσετε το δικό σας διακριτικό, μπορείτε να χρησιμοποιήσετε το παρακάτω σενάριο για να ανεβάσετε τα δεδομένα σας. Αφού ανεβάσετε τα δεδομένα του πρώτου σας σταθμού, μεταβείτε στη διεύθυνση 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 -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 χαρακτήρες.
Αυτό το όνομα χρησιμοποιείται μόνο εσωτερικά για εσάς. Κανείς άλλος δεν θα δει αυτό το αναγνωριστικό

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 για ένα λεπτό μέσο όρο δεδομένων και 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-12-21T21:05:28+09:00","specie":"pm2.5", "value": 393.3, "unit":"mg/m3", "min":390.3, "max": 402.3, "stddev": 0.332},  
		{"time":"2024-12-21T21:05:28+09:00","specie":"pm10", "value": 109.3, "unit":"mg/m3"}, 
		{"time":"2024-12-21T21:05:28+09:00","specie":"co2", "value": 459.3, "unit":"ppb"}, 
		{"time":"2024-12-21T21:05:28+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) 
 

Γνωρίζετε σταθμούς Air Quality στην περιοχή σας;
γιατί να μην συμμετέχετε στον χάρτη με τον δικό σας σταθμό ποιότητας αέρα;

Οι οθόνες ποιότητας αέρα GAIA ρυθμίζονται πολύ εύκολα: Χρειάζεστε μόνο ένα σημείο πρόσβασης WIFI και ένα τροφοδοτικό συμβατό με USB.

Μόλις συνδεθείτε, τα επίπεδα ατμοσφαιρικής ρύπανσης σε πραγματικό χρόνο είναι άμεσα διαθέσιμα στους χάρτες και μέσω του API.

Ο σταθμός διαθέτει ένα αδιάβροχο καλώδιο τροφοδοσίας 10 μέτρων, τροφοδοτικό USB, εξοπλισμό τοποθέτησης και προαιρετικό ηλιακό πάνελ.

Σχετικά με τη μέτρηση της ποιότητας του αέρα και της ρύπανσης:

Σχετικά με τα επίπεδα ποιότητας αέρα

- Τιμές του δείκτη ποιότητας αέρα (AQI).Επίπεδα ανησυχίας για την υγεία
0 - 50 Καλός Η ποιότητα του αέρα θεωρείται ικανοποιητική και η ατμοσφαιρική ρύπανση παρουσιάζει μικρό ή καθόλου κίνδυνο
51 -100 Μέτριος Η ποιότητα του αέρα είναι αποδεκτή. Ωστόσο, για ορισμένους ρύπους μπορεί να υπάρχει μέτρια ανησυχία για την υγεία για ένα πολύ μικρό αριθμό ατόμων που είναι ασυνήθιστα ευαίσθητα στην ατμοσφαιρική ρύπανση.
101-150 Ανθυγιεινό για ευαίσθητες ομάδες Τα μέλη ευαίσθητων ομάδων ενδέχεται να έχουν επιπτώσεις στην υγεία. Το ευρύ κοινό δεν είναι πιθανό να επηρεαστεί.
151-200 Ανθυγιεινός Ο καθένας μπορεί να αρχίσει να αντιμετωπίζει τις επιπτώσεις στην υγεία. τα μέλη ευαίσθητων ομάδων ενδέχεται να έχουν πιο σοβαρές επιπτώσεις στην υγεία
201-300 Πολύ Ανθυγιεινό Προειδοποιήσεις για την υγεία σε συνθήκες έκτακτης ανάγκης. Όλος ο πληθυσμός είναι πολύ πιθανόν να επηρεαστεί.
300+ Επικίνδυνος Προειδοποίηση για την υγεία: Όλοι μπορεί να έχουν πιο σοβαρές επιπτώσεις στην υγεία

Για να μάθετε περισσότερα σχετικά με την ποιότητα του αέρα και τη ρύπανση, ανατρέξτε στο θέμα της wikipedia για την ποιότητα του αέρα ή στον οδηγό airnow για την ποιότητα του αέρα και την υγεία σας .

Για πολύ χρήσιμες συμβουλές υγείας του γιατρού του Πεκίνου Richard Saint Cyr MD, ανατρέξτε στο ιστολόγιο www.myhealthbeijing.com .


Ειδοποίηση χρήσης: Όλα τα δεδομένα για την ποιότητα του αέρα δεν έχουν εγκριθεί κατά τη στιγμή της δημοσίευσης και, λόγω της διασφάλισης της ποιότητας, τα δεδομένα αυτά μπορούν να τροποποιηθούν χωρίς προειδοποίηση ανά πάσα στιγμή. Το έργο Παγκόσμιο Δείκτη Ποιότητας του Αερίου έχει ασκήσει όλες τις εύλογες δεξιότητες και φροντίδα κατά την κατάρτιση του περιεχομένου αυτών των πληροφοριών και σε καμία περίπτωση το Ομάδα Παγκόσμιας Ποιότητας Αέριας Ποιότητας ή οι αντιπρόσωποί της είναι υπεύθυνοι για συμβόλαιο, αδικοπραξία ή άλλως για τυχόν απώλειες, τραυματισμούς ή ζημίες που προκύπτουν άμεσα ή έμμεσα από την παροχή αυτών των δεδομένων.



Settings


Language Settings:


Temperature unit:
Celcius