W tym poście chciałbym opisać sposób pobrania danych z serwisu Airly.
[Źródło: http://paulobrien.co.nz/2017/03/16/esp32-programming-with-arduino-on-windows/]
Przygotowanie:
Na samym początku należy założyć konto oraz wygenerować klucz API na stronie Airly w części dla programistów (https://developer.airly.eu/).
Po zalogowaniu należy odczytać API key:
Następnym krokiem jest określenie szerokości i długości geograficznej. Te dane należy w celu wysłania żądania odczytania danych z serwisu. Tutaj można się posłużyć stroną www.wspolrzedne-gps.pl
Gdy już posiadamy lokalizację oraz klucz to należy przygotować ciąg znaków z jakiego pobierane będą dane za pomocą żądania http.
- https://airapi.airly.eu/v2/installations/nearest?lat=50.0918091&lng=19.8998826&maxDistanceKM=5&maxResults=4&apikey=API_KEY
Powyższy string pozwoli na odczytanie ID oraz danych najbliższych czujników w okolicy podanej lokalizacji.
Jako parametry należy wprowadzić:
Następnie w celu uzyskania danych z konkretnego czujnika należy posiadać jego ID. Po identyfikacji czujnika należy odczytać dane w następujący sposób:
- https://airapi.airly.eu/v2/measurements/installation?installationId=2903&apikey=API_KEY
W odpowiedzi otrzymujemy dane aktualne, historyczne oraz prognozy na najbliższy czas. Całość prezentuje się następująco:
- {
- "current":{
- "fromDateTime":"2020-01-13T07:03:06.902Z",
- "tillDateTime":"2020-01-13T08:03:06.902Z",
- "values":[
- {"name":"PM1","value":18.87},
- {"name":"PM25","value":28.93},
- {"name":"PM10","value":57.27},
- {"name":"PRESSURE","value":1024.01},
- {"name":"HUMIDITY","value":85.63},
- {"name":"TEMPERATURE","value":0.58}
- ],
- "indexes":[
- {
- "name":"AIRLY_CAQI",
- "value":54.54,
- "level":"MEDIUM",
- "description":"Bywało lepiej...",
- "advice":"Lepiej ogranicz dzisiaj swoją aktywność fizyczną na powietrzu.",
- "color":"#EFBB0F"
- }
- ],
- "standards":[
- {
- "name":"WHO",
- "pollutant":"PM25",
- "limit":25.0,
- "percent":115.71
- },
- {
- "name":"WHO",
- "pollutant":"PM10",
- "limit":50.0,
- "percent":114.53}
- ]
- },
- "history":[ ..... ],
- "forecast":[ ..... ]
- }
W celu pobrania danych w postaci załączonej powyżej można skorzystać z następującego programu:
- #include <WiFi.h>
- #include <HTTPClient.h>
- const char* ssid = "WIFI_SSID";
- const char* password = "WIFI_PASSWORD";
- const String ENDPOINT_STRING = "https://airapi.airly.eu/v2/measurements/installation?installationId=2903";
- const String API_KEY = "&apikey=API_KEY";
- const String SENSOR_ID = "installationId=2903";
- void setup() {
- Serial.begin(115200);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(1000);
- Serial.print("Connection with WIFI Network....");
- }
- Serial.println("Connected!");
- }
- void loop() {
- if ((WiFi.status() == WL_CONNECTED))
- {
- HTTPClient http;
- http.begin(ENDPOINT_STRING + SENSOR_ID + API_KEY); //Specify the URL
- int httpResponseCode = http.GET(); //Make the request
- if (httpResponseCode > 0)
- {
- String readedData = http.getString();
- Serial.println(httpResponseCode);
- Serial.println(readedData);
- }
- else
- {
- Serial.println("Http Request Error");
- }
- http.end();
- }
- delay(100000);
- }
W powyższym kodzie po połączeniu się z Wifi następuje pobranie i wyświetlenie nie obrobionych danych:
Poniższy drugi program wyciągnie wszystkie aktualne dane z czytnika:
- #include <ArduinoJson.h>
- #include <WiFi.h>
- #include <HTTPClient.h>
- #define JSON_BUFF_DIMENSION 30000
- const char* ssid = "WIFI_SSID";
- const char* password = "WIFI_PASSWORD";
- const String ENDPOINT_STRING = "https://airapi.airly.eu/v2/measurements/installation?";
- const String API_KEY = "&apikey=API_KEY";
- const String SENSOR_ID = "installationId=2903";
- String jsonStringText;
- void setup() {
- Serial.begin(115200);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(1000);
- Serial.print("Connection with WIFI Network....");
- }
- Serial.println("Connected!");
- jsonStringText.reserve(JSON_BUFF_DIMENSION);
- }
- void loop() {
- if ((WiFi.status() == WL_CONNECTED))
- {
- HTTPClient http;
- http.begin(ENDPOINT_STRING + SENSOR_ID + API_KEY); //Specify the URL
- int httpResponseCode = http.GET(); //Make the request
- if (httpResponseCode > 0)
- {
- jsonStringText = http.getString();
- Serial.println(httpResponseCode);
- parseJsonData(jsonStringText.c_str());
- }
- else
- {
- Serial.println("Http Request Error");
- }
- http.end();
- }
- delay(100000);
- }
- void parseJsonData(const char * jsonString)
- {
- DynamicJsonDocument jsonBuffer(100000);
- auto error = deserializeJson(jsonBuffer, jsonString);
- if (error) {
- Serial.println("Deserialize error");
- Serial.println(error.c_str());
- return;
- }
- else
- {
- Serial.println("Deserialize OK!");
- }
- size_t len = measureJson(jsonBuffer);
- Serial.println(len);
- JsonArray list = jsonBuffer["current"];
- String fromDateTime = jsonBuffer["current"]["fromDateTime"];
- String tillDateTime = jsonBuffer["current"]["tillDateTime"];
- //----------------------------------------------------------------
- String namePM1 = jsonBuffer["current"]["values"][0]["name"];
- String valuePM1 = jsonBuffer["current"]["values"][0]["value"];
- String namePM25 = jsonBuffer["current"]["values"][1]["name"];
- String valuePM25 = jsonBuffer["current"]["values"][1]["value"];
- String namePM10 = jsonBuffer["current"]["values"][2]["name"];
- String valuePM10 = jsonBuffer["current"]["values"][2]["value"];
- String namePressure = jsonBuffer["current"]["values"][3]["name"];
- String valuePressure = jsonBuffer["current"]["values"][3]["value"];
- String nameHumidity = jsonBuffer["current"]["values"][4]["name"];
- String valueHumidity = jsonBuffer["current"]["values"][4]["value"];
- String nameTemperature= jsonBuffer["current"]["values"][5]["name"];
- String valueTemperature = jsonBuffer["current"]["values"][5]["value"];
- //----------------------------------------------------------------
- String indexesName = jsonBuffer["current"]["indexes"][0]["name"];
- String indexesValue = jsonBuffer["current"]["indexes"][0]["value"];
- String indexesLevel = jsonBuffer["current"]["indexes"][0]["level"];
- String indexesDescription = jsonBuffer["current"]["indexes"][0]["description"];
- String indexesAdvice = jsonBuffer["current"]["indexes"][0]["advice"];
- String indexesColor = jsonBuffer["current"]["indexes"][0]["color"];
- //----------------------------------------------------------------
- String standardsPM25Name = jsonBuffer["current"]["standards"][0]["name"];
- String standardsPM25Pollutant = jsonBuffer["current"]["standards"][0]["pollutant"];
- String standardsPM25Limit = jsonBuffer["current"]["standards"][0]["limit"];
- String standardsPM25Percent = jsonBuffer["current"]["standards"][0]["percent"];
- //----------------------------------------------------------------
- String standardsPM10Name = jsonBuffer["current"]["standards"][1]["name"];
- String standardsPM10Pollutant = jsonBuffer["current"]["standards"][1]["pollutant"];
- String standardsPM10Limit = jsonBuffer["current"]["standards"][1]["limit"];
- String standardsPM10Percent = jsonBuffer["current"]["standards"][1]["percent"];
- Serial.println("----------------------------");
- /*Current fromDateTime display */
- Serial.println("fromDateTime: " + fromDateTime);
- /*Current tillDateTime display */
- Serial.println("tillDateTime: " + tillDateTime);
- /*Current values display */
- Serial.println("*****************");
- Serial.println(namePM1 + " - " + valuePM1);
- Serial.println(namePM25 + " - " + valuePM25);
- Serial.println(namePM10 + " - " + valuePM10);
- Serial.println(namePressure + " - " + valuePressure);
- Serial.println(nameHumidity + " - " + valueHumidity);
- Serial.println(nameTemperature + " - " + valueTemperature);
- /*Current indexes display */
- Serial.println("*****************");
- Serial.println("Indexes name: - " + indexesName);
- Serial.println("Indexes value: - " + indexesValue);
- Serial.println("Indexes level: - " + indexesLevel);
- Serial.println("Indexes description: - " + indexesDescription);
- Serial.println("Indexes advice: - " + indexesAdvice);
- Serial.println("Indexes color: - " + indexesColor);
- /*Current standards display */
- Serial.println("*****************");
- Serial.println("Standards name: - " + standardsPM25Name);
- Serial.println("Standards pollutant: - " + standardsPM25Pollutant);
- Serial.println("Limit level: - " + standardsPM25Limit);
- Serial.println("Percent description: - " + standardsPM25Percent);
- Serial.println("*****************");
- Serial.println("Standards name: - " + standardsPM10Name);
- Serial.println("Standards pollutant: - " + standardsPM10Pollutant);
- Serial.println("Limit level: - " + standardsPM10Limit);
- Serial.println("Percent description: - " + standardsPM10Percent);
- Serial.println("----------------------------");
- }
Odczytane w ten sposób dane prezentują się w następujący sposób:
W powyższym programie korzystam z biblioteki ArduinoJson. Dzięki niej można w łatwy sposób wyciągnąć dane z obiektu JSON. Aktualnie dostępna jest biblioteka w wersji 6. Natomiast dużo przykładów zastosowania jej na internecie opisuje wersję 5. Dlatego w poniższym linku opisane jest w jaki sposób przejść na wyższą wersję (https://arduinojson.org/v6/doc/upgrade/).
W powyższym programie korzystam z biblioteki ArduinoJson. Dzięki niej można w łatwy sposób wyciągnąć dane z obiektu JSON. Aktualnie dostępna jest biblioteka w wersji 6. Natomiast dużo przykładów zastosowania jej na internecie opisuje wersję 5. Dlatego w poniższym linku opisane jest w jaki sposób przejść na wyższą wersję (https://arduinojson.org/v6/doc/upgrade/).