Как прочитать вторую строку ответа от сервера OpenWeatherMap
- Войдите на сайт для отправки комментариев
Чт, 13/08/2020 - 21:24
Помогите правильно написать код для парсинга погоды с сайта OpenWeatherMap.
Суть проекта проста: К Arduino Uno подключен модуль ESP-01. Подключаемся по WI-FI, делаем запрос на сайт. Приходит ответ. Но разобрать я могу только 1-ую строку. Это +IPD,792:HTTP/1.1. Я так понимаю что длина сообщения, которое содержит данные о погоде и находится во второй строке - 792. А вот как получить правильно вторую строку в цикле while(dbgSerial.available()), я не понимаю. Все облазил в интернете - ничего похожего не нашел. Может надо вообще по другому получать данные. Вот код, который у меня - Он довольно простой:
#include <ArduinoJson.h> #include <SoftwareSerial.h> #define SSID "DFCT" // введите ваш SSID #define PASS "Dp#qTR82" // введите ваш пароль #define LOCATIONID "2925533" // id местоположения //#define DST_IP "188.226.224.148" //api.openweathermap.org #define DST_IP "api.openweathermap.org" const char* api = "d90c71098446021e66e71a6aaf4dd69c"; //Мой API ключ (Он ложный - Изменил для конспирации) const char* city = "518970"; //ID моего города String line; String line2; bool pr = false; SoftwareSerial dbgSerial(3, 4); // RX, TX для отладки StaticJsonDocument<500> root; void setup() { Serial.begin(115200); Serial.setTimeout(5000); dbgSerial.begin(115200); // для отладки Serial.println("Init"); dbgSerial.println("AT+RST"); // сброс и проверка, если модуль готов delay(6000); // try to connect to wifi boolean connected=false; for(int i=0;i<5;i++){ if(connectWiFi()){ connected = true; Serial.println("Connected to WiFi..."); break; } delay(1000); } if (!connected){ Serial.println("Coudn't connect to WiFi."); while(1); } delay(5000); dbgSerial.println("AT+CIPMUX=0"); // установка в режим одиночного соединения } void loop() { String cmd = "AT+CIPSTART=\"TCP\",\""; cmd += DST_IP; cmd += "\",80"; dbgSerial.println(cmd); Serial.println(cmd); if(dbgSerial.find("Error")) return; cmd = "GET /data/2.5/weather?id=" + String(city) + "&appid=" + String(api); cmd += " HTTP/1.0\r\nHost: api.openweathermap.org\r\n\r\n"; dbgSerial.print("AT+CIPSEND="); dbgSerial.println(cmd.length()); if(dbgSerial.find(">")){ Serial.print(">"); } else { dbgSerial.println("AT+CIPCLOSE"); Serial.println("connection timeout"); delay(1000); return; } Serial.println(cmd); dbgSerial.println(cmd); delay(3000); if(dbgSerial.find("SEND OK")) { Serial.println("Request send"); //delay(5000); } Serial.println("Begin JSON"); while(dbgSerial.available()){ //Если получили ответ от сервера... line = dbgSerial.readStringUntil('\n'); // +IPD,792:HTTP/1.1 } Serial.println(line); DeserializationError error = deserializeJson(root, line); // Test if parsing succeeds. if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.c_str()); delay(5000); //return; } double temp = root["temp"]; double pressure = root["pressure"]; double humidity = root["humidity"]; temp -= 273.15; // Перевод градусов кельвины-цельсии Serial.println(temp); Serial.println(pressure); Serial.println(humidity); Serial.println("===="); delay(600000); } boolean connectWiFi() { dbgSerial.println("AT+CWMODE=1"); String cmd="AT+CWJAP=\""; cmd+=SSID; cmd+="\",\""; cmd+=PASS; cmd+="\""; Serial.println(cmd); dbgSerial.println(cmd); delay(2000); if(dbgSerial.find("OK")){ Serial.println("OK, Connected to WiFi."); return true; }else{ Serial.println("Can not connect to the WiFi."); return false; } }
Конечно я оплачу в разумных пределах
"Разумный предел" это сколько?
После "792:" начинается HTTP-заголовок, который заканчивается 2-мя пустыми строками. Спросить "что такое HTTP?" и про его формат можно у гугла. После заголовка идёт JSON. Для JSON-а никакие строки не важны - это просто поток символов. Спросить "что такое JSON?" и про его формат можно там же, где и про HTTP.
После "792:" читаем поток символов, парсим его на лету в HTTP-заголовок (пока он не исчерпается (по 2-м пустым строкам)); потом также парсим JSON пока не исчерпается весь объём в 792 байта.