ডেটা আপলোড API এবং নমুনা স্ক্রিপ্ট

প্রথম ধাপ হল ডেটা-প্ল্যাটফর্ম পৃষ্ঠা থেকে একটি টোকেন পাওয়া।

একবার আপনার নিজের টোকেন হয়ে গেলে, আপনি আপনার ডেটা আপলোড করতে নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করতে পারেন। আপনি আপনার প্রথম স্টেশন ডেটা আপলোড করার পরে, আপনার স্টেশনগুলি কনফিগার করতে এবং আপলোড করা ডেটা যাচাই করতে aqicn.org/data-feed/verification/ এ যান৷

সমর্থিত সফ্টওয়্যার প্ল্যাটফর্ম:

আমরা সেই 3টি প্ল্যাটফর্মের জন্য সফ্টওয়্যার ব্যবহারের জন্য প্রস্তুত প্রদান করি:

  • Arduino : আপনার যদি একটি Arduino CPU থাকে, তাহলে ব্যবহার করার জন্য প্রস্তুত সফ্টওয়্যারটি ব্যবহার করুন github.com-এ aqicn/gaia-a08-arduino এ উপলব্ধ।
  • Python: নিচের কোড-স্নিপেট ব্যবহার করুন
  • কমান্ড লাইন (CURL): নীচের কোড-স্নিপেট ব্যবহার করুন

আপনার যদি কোনো মনিটরিং স্টেশন না থাকে, এবং একটি পেতে চান, আমাদের GAIA এয়ার কোয়ালিটি মনিটরিং স্টেশনগুলি দেখুন।

আপনি যদি একটি DIY স্টেশন পছন্দ করেন, GAIA A08 চেক করুন।


--

নমুনা কোড (পাইথন)

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}]\
}'

নমুনা কোড (আরডুইনো)

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 ব্যবহার করুন।

উদাহরণ 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-23T02:43:43+09:00","specie":"pm2.5", "value": 393.3, "unit":"mg/m3", "min":390.3, "max": 402.3, "stddev": 0.332},
{"time":"2025-02-23T02:43:43+09:00","specie":"pm10", "value": 109.3, "unit":"mg/m3"},
{"time":"2025-02-23T02:43:43+09:00","specie":"co2", "value": 459.3, "unit":"ppb"},
{"time":"2025-02-23T02:43:43+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+ বিপজ্জনক স্বাস্থ্য সতর্কতা: প্রত্যেকেরই আরও গুরুতর স্বাস্থ্যের প্রভাব পড়তে পারে

বায়ুর গুণমান এবং দূষণ সম্পর্কে আরও জানতে, উইকিপিডিয়া এয়ার কোয়ালিটি বিষয় বা বায়ুর গুণমান এবং আপনার স্বাস্থ্যের জন্য এয়ারনাউ গাইড দেখুন।

বেইজিং ডাক্তার রিচার্ড সেন্ট সাইর এমডির খুব দরকারী স্বাস্থ্য পরামর্শের জন্য, www.myhealthbeijing.com ব্লগ দেখুন।


ব্যবহারের নোটিশ: প্রকাশনার সময় সমস্ত বায়ু গুণমান তথ্য অ-বৈধ হয় এবং গুণমান নিশ্চিতকরণের কারণে এই তথ্যটি যে কোনও সময়ে নোটিশ ছাড়াই সংশোধন করা যেতে পারে। ওয়ার্ল্ড এয়ার কোয়ালিটি ইনডেক্স প্রকল্পটি এই তথ্যগুলির সামগ্রীর মধ্যে কম্পাইল করার জন্য সমস্ত যুক্তিসঙ্গত দক্ষতা ও যত্ন ব্যবহার করেছে এবং কোনও পরিস্থিতিতে এটি ওয়ার্ল্ড এয়ার কোয়ালিটি ইনডেক্স প্রকল্প দল বা তার এজেন্টগুলি এই তথ্য সরবরাহ থেকে সরাসরি বা পরোক্ষভাবে উদ্ভূত কোন ক্ষতি, আঘাত বা ক্ষতির জন্য চুক্তি, নির্যাতন বা অন্যথায় দায়বদ্ধ।



Settings


Language Settings:


Temperature unit:
Celcius