ទិន្នន័យផ្ទុកឡើង API & ស្គ្រីបគំរូ

ជំហានដំបូងគឺដើម្បីទទួលបានសញ្ញាសម្ងាត់ពី ទំព័រទិន្នន័យវេទិកា

នៅពេលដែលអ្នកមានសញ្ញាសម្ងាត់ផ្ទាល់ខ្លួនរបស់អ្នក អ្នកអាចប្រើស្គ្រីបខាងក្រោមដើម្បីផ្ទុកទិន្នន័យរបស់អ្នក។ បន្ទាប់ពីអ្នកបង្ហោះទិន្នន័យស្ថានីយ៍ដំបូងរបស់អ្នក សូមចូលទៅកាន់ aqicn.org/data-feed/verification/ ដើម្បីកំណត់រចនាសម្ព័ន្ធស្ថានីយ៍របស់អ្នក និងផ្ទៀងផ្ទាត់ទិន្នន័យដែលបានផ្ទុកឡើង។

វេទិកាកម្មវិធីដែលគាំទ្រ៖

យើងផ្តល់ជូននូវកម្មវិធីដែលត្រៀមរួចជាស្រេចក្នុងការប្រើប្រាស់សម្រាប់វេទិកាទាំង 3 នោះ៖

  • Arduino ៖ ប្រសិនបើអ្នកមានស៊ីភីយូ Arduino សូមប្រើកម្មវិធីដែលត្រៀមរួចជាស្រេចក្នុងការប្រើប្រាស់ដែលមាននៅលើ github.com នៅ aqicn/gaia-a08-arduino
  • Python៖ ប្រើកូដ-snippet ខាងក្រោម
  • បន្ទាត់ពាក្យបញ្ជា (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", ... សម្រាប់ឧបករណ៍ចាប់សញ្ញា gaz ប្រើ៖ "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 សម្រាប់មធ្យមម៉ោង។

ឧទាហរណ៍ ១

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

ឧទាហរណ៍ ២

{
"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)Levels of Health Concern
0 - 50 ល្អ គុណភាពខ្យល់ត្រូវបានចាត់ទុកថាពេញចិត្តហើយការបំពុលបរិយាកាសបង្កឱ្យមានហានិភ័យតិចតួចឬគ្មាន
51 -100 មធ្យម គុណភាពខ្យល់អាចទទួលយកបាន។ ទោះជាយ៉ាងណាក៏ដោយចំពោះការបំពុលមួយចំនួនវាអាចមានការព្រួយបារម្ភខាងសុខភាពក្នុងកម្រិតតិចតួចចំពោះមនុស្សតិចតួចដែលងាយទទួលរងការបំពុលខ្យល់។
101-150 Unhealthy
for sensitive groups
សមាជិកនៃក្រុមរសើបអាចជួបប្រទះផលប៉ះពាល់សុខភាព។ សាធារណជន​ទូទៅ​មិន​ទំនង​ជា​រង​ផល​ប៉ះពាល់​ទេ។
151-200 មិនល្អ មនុស្សគ្រប់រូបអាចចាប់ផ្តើមមានផលប៉ះពាល់ដល់សុខភាព។ សមាជិកនៃក្រុមដែលប្រកាន់អក្សរតូចធំអាចមានផលប៉ះពាល់សុខភាពធ្ងន់ធ្ងរបន្ថែមទៀត
201-300 មិនល្អខ្លាំង ការព្រមានអំពីសុខភាពនៃស្ថានភាពគ្រាអាសន្ន។ ប្រជាជនទាំងមូលទំនងជារងផលប៉ះពាល់។
300+ គ្រោះថ្នាក់ ការប្រុងប្រយ័ត្នផ្នែកសុខភាព: មនុស្សគ្រប់រូបអាចមានផលប៉ះពាល់ធ្ងន់ធ្ងរលើសុខភាព

ដើម្បីដឹងបន្ថែមអំពីគុណភាពខ្យល់ និងការបំពុល សូមពិនិត្យមើល ប្រធានបទគុណភាពខ្យល់ wikipediaមគ្គុទ្ទេសក៍ airnow អំពីគុណភាពខ្យល់ និងសុខភាពរបស់អ្នក

សម្រាប់ដំបូន្មានសុខភាពដ៏មានប្រយោជន៍របស់វេជ្ជបណ្ឌិតទីក្រុងប៉េកាំង Richard Saint Cyr MD សូមពិនិត្យមើលប្លក់ www.myhealthbeijing.com


សេចក្តីជូនដំណឹងអំពីការប្រើប្រាស់: ទិន្នន័យគុណភាពខ្យល់ទាំងអស់មិនត្រូវបានគេប៉ាន់ស្មាននៅពេលបោះពុម្ភផ្សាយនោះទេហើយដោយសារតែការធានាគុណភាពនេះទិន្នន័យទាំងនេះអាចត្រូវបានកែប្រែដោយគ្មានការជូនដំណឹងគ្រប់ពេលវេលា។ គម្រោងសន្ទស្សន៍គុណភាពខ្យល់អាកាសពិភពលោកបានអនុវត្តនូវជំនាញនិងការថែទាំដែលសមស្របទាំងអស់ក្នុងការចងក្រងមាតិកានៃព័ត៌មាននេះហើយក្នុងករណីណាក៏ដោយក្រុមការងារគម្រោងសន្ទស្សន៍គុណភាពខ្យល់អាកាសពិភពលោកឬភ្នាក់ងាររបស់វាត្រូវទទួលខុសត្រូវលើកិច្ចសន្យាខូចខាតឬបើមិនដូច្នោះទេសម្រាប់ការបាត់បង់របួសឬខូចខាត ដែលកើតឡើងដោយផ្ទាល់ឬដោយប្រយោលពីការផ្គត់ផ្គង់ទិន្នន័យនេះ។



Settings


Language Settings:


Temperature unit:
Celcius