Как прочитать вторую строку ответа от сервера OpenWeatherMap

Mihay
Offline
Зарегистрирован: 07.08.2020

Помогите правильно написать код для парсинга погоды с сайта 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;
  }
}
 
Mihay
Offline
Зарегистрирован: 07.08.2020

Конечно я оплачу в разумных пределах

hamann
Offline
Зарегистрирован: 17.08.2015

"Разумный предел" это сколько? 

rst
Offline
Зарегистрирован: 25.06.2018

Mihay пишет:
Это +IPD,792:HTTP/1.1. Я так понимаю что длина сообщения, которое содержит данные о погоде и находится во второй строке - 792. А вот как получить правильно вторую строку

После "792:" начинается HTTP-заголовок, который заканчивается 2-мя пустыми строками. Спросить "что такое HTTP?" и про его формат можно у гугла. После заголовка идёт JSON. Для JSON-а никакие строки не важны - это просто поток символов. Спросить "что такое JSON?" и про его формат можно там же, где и про HTTP.

После "792:" читаем поток символов, парсим его на лету в HTTP-заголовок (пока он не исчерпается (по 2-м пустым строкам)); потом также парсим JSON пока не исчерпается весь объём в 792 байта.