Парсинг яндекс погоды

Парсинг яндекс погоды, для дальнейшего создания часов и прогноза погоды.
esp8266-yandex.ino



//    https://disk.yandex.ru/d/D8jSzEvkl9h3TA


// 15.04.2023 23-59
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>        //ver. - 6.20.0
#include "data_weather.h"       // структура ответа от yandex
#include "settings.h"           // настройки в файле settings.h
//------------------------------------------------
#define Serial_Print    // отладка для работы  - закоментить
//------------------------------------------------
weather_t weather;

unsigned long lastTime = 0;
StaticJsonDocument<8000> doc;
int wifi_signal = -120;

bool decode_json(String jsonStr);
bool getWeather();
String convert_unix_time(int unix_time);
String get_description_condition(String str);
String get_partName(String pName);
String getSeason(String season);


void setup() {
 Serial.begin(115200);
 WiFi.begin(ssid, password);
 Serial.println("Connecting");
 while(WiFi.status() != WL_CONNECTED) {
   delay(500);
   Serial.print(".");
  } //end while
 Serial.println("");
 Serial.print("WiFi подключен. IP: "); Serial.println(WiFi.localIP());
 wifi_signal = WiFi.RSSI();
 Serial.print("Уровень сигнала WiFi: "); Serial.println(wifi_signal);
 Serial.print("Обновление через: "); Serial.print(timerDelay); Serial.println(" минут.");  
} //end setup

void loop() {
 if ((millis() - lastTime) > timerDelay * 60*1000) {  
     getWeather(); 
//     Serial.print(convert_unix_time(weather.now));
     lastTime = millis();
} 
}//end loop

void printStr(String& s) {
  Serial.println(s);
}

String get_partName(String pName)
{
  if (pName == "night")
    return "Ночь";
  if (pName == "morning")
    return "Утро";
  if (pName == "day")
    return "День";
  if (pName == "evening")
    return "Вечер";
  return pName;
}

String get_description_condition(String str)
{
  String retStr = str;
  if (str == "clear")
    retStr = "Ясно";
  if (str == "partly-cloudy")
    retStr = "Малооблачно";
  if (str == "cloudy")
    retStr = "Облачно с прояснениями";
  if (str == "overcast")
    retStr = "Пасмурно";
  if (str == "drizzle")
    retStr = "Моросящий дождь";
  if (str == "light-rain")
    retStr = "Небольшой дождь";
  if (str == "rain")
    retStr = "Дождь";
  if (str == "moderate-rain")
    retStr = "Умеренно сильный дождь";
  if (str == "heavy-rain")
    retStr = "Сильный дождь";
  if (str == "continuous-heavy-rain")
    retStr = "Длительный сильный дождь";
  if (str == "showers")
    retStr = "Ливень";
  if (str == "wet-snow")
    retStr = "Дождь со снегом";
  if (str == "light-snow")
    retStr = "Небольшой снег";
  if (str == "snow")
    retStr = "Снег";
  if (str == "snow-showers")
    retStr = "Снегопад";
  if (str == "hail")
    retStr = "Град";
  if (str == "thunderstorm")
    retStr = "Гроза";
  if (str == "thunderstorm-with-rain")
    retStr = "Дождь с грозой";
  if (str == "thunderstorm-with-hail")
    retStr = "Гроза с градом";
  return retStr;
}

String getSeason(String season)
{
  if (season == "summer")
    return "Лето";
  if (season == "autumn")
    return "Осень";
  if (season == "winter")
    return "Зима";
  if (season == "spring")
    return "Весна";
  return season;
}

String convert_unix_time(int unix_time)
{
  time_t tm = unix_time;
  struct tm *now_tm = localtime(&tm);
  char output[40];
  strftime(output, sizeof(output), "%H:%M %d.%m.%y", now_tm);
  return output;
}

bool decode_json(String jsonStr)
{
 DeserializationError error = deserializeJson(doc, jsonStr); // преобразовать строку JSON в структуру
 if (error) {    // Проверяем успешность парсинга.
      String errorStr = error.c_str();
      Serial.println("errorStr: ");  Serial.print(errorStr);
      return false;	  
 }else{
      Serial.println("deserializeJson() без ошибок.");
      JsonObject doc_YA = doc.as<JsonObject>();	
      weather.fact.condition = doc_YA["fact"]["condition"].as<const char *>(); // парсинг данных из JsonObject
      weather.fact.daytime = doc_YA["fact"]["daytime"].as<const char *>();
      weather.fact.feels_like = doc_YA["fact"]["feels_like"].as<int8_t>();
      weather.fact.humidity = doc_YA["fact"]["humidity"].as<uint8_t>();
      weather.fact.icon = doc_YA["fact"]["icon"].as<const char *>();
      weather.fact.obs_time = doc_YA["fact"]["obs_time"].as<int>();
      weather.fact.polar = doc_YA["fact"]["polar"].as<bool>();
      weather.fact.pressure_mm = doc_YA["fact"]["pressure_mm"].as<uint16_t>();
      weather.fact.pressure_pa = doc_YA["fact"]["pressure_pa"].as<uint16_t>();
      weather.fact.season = doc_YA["fact"]["season"].as<const char *>();
      weather.fact.temp = doc_YA["fact"]["temp"].as<int8_t>();
      weather.fact.temp_water = doc_YA["fact"]["temp_water"].as<int8_t>();
      weather.fact.wind_dir = doc_YA["fact"]["wind_dir"].as<const char *>();
      weather.fact.wind_gust = doc_YA["fact"]["wind_gust"].as<float>();
      weather.fact.wind_speed = doc_YA["fact"]["wind_speed"].as<float>();
      weather.forecast.date = doc_YA["forecast"]["date"].as<String>();
      weather.forecast.date_ts = doc_YA["forecast"]["date_ts"].as<int>();
      weather.forecast.moon_code = doc_YA["forecast"]["moon_code"].as<uint8_t>();
      weather.forecast.moon_text = doc_YA["forecast"]["moon_text"].as<const char *>();
      for (uint8_t i = 0; i < 2; i++)
      {
        weather.forecast.parts[i].condition = doc_YA["forecast"]["parts"][i]["condition"].as<const char *>();
        weather.forecast.parts[i].daytime = doc_YA["forecast"]["parts"][i]["daytime"].as<const char *>();
        weather.forecast.parts[i].feels_like = doc_YA["forecast"]["parts"][i]["feels_like"].as<int8_t>();
        weather.forecast.parts[i].humidity = doc_YA["forecast"]["parts"][i]["humidity"].as<uint8_t>();
        weather.forecast.parts[i].icon = doc_YA["forecast"]["parts"][i]["icon"].as<const char *>();
        weather.forecast.parts[i].part_name = doc_YA["forecast"]["parts"][i]["part_name"].as<const char *>();
        weather.forecast.parts[i].polar = doc_YA["forecast"]["parts"][i]["polar"].as<bool>();
        weather.forecast.parts[i].prec_mm = doc_YA["forecast"]["parts"][i]["prec_mm"].as<float>();
        weather.forecast.parts[i].prec_period = doc_YA["forecast"]["parts"][i]["prec_period"].as<uint16_t>();
        weather.forecast.parts[i].prec_prob = doc_YA["forecast"]["parts"][i]["prec_prob"].as<uint8_t>();
        weather.forecast.parts[i].pressure_mm = doc_YA["forecast"]["parts"][i]["pressure_mm"].as<uint16_t>();
        weather.forecast.parts[i].pressure_pa = doc_YA["forecast"]["parts"][i]["pressure_pa"].as<uint16_t>();
        weather.forecast.parts[i].temp_avg = doc_YA["forecast"]["parts"][i]["temp_avg"].as<int8_t>();
        weather.forecast.parts[i].temp_max = doc_YA["forecast"]["parts"][i]["temp_max"].as<int8_t>();
        weather.forecast.parts[i].temp_min = doc_YA["forecast"]["parts"][i]["temp_min"].as<int8_t>();
        weather.forecast.parts[i].temp_water = doc_YA["forecast"]["parts"][i]["temp_water"].as<uint8_t>();
        weather.forecast.parts[i].wind_dir = doc_YA["forecast"]["parts"][i]["wind_dir"].as<const char *>();
        weather.forecast.parts[i].wind_gust = doc_YA["forecast"]["parts"][i]["wind_gust"].as<float>();
        weather.forecast.parts[i].wind_speed = doc_YA["forecast"]["parts"][i]["wind_speed"].as<float>();
      }
     weather.forecast.sunrise = doc_YA["forecast"]["sunrise"].as<const char *>();
     weather.forecast.sunset = doc_YA["forecast"]["sunset"].as<const char *>();
     weather.forecast.week = doc_YA["forecast"]["week"].as<uint8_t>();
     weather.info.lat = doc_YA["info"]["lat"].as<float>();
     weather.info.lon = doc_YA["info"]["lon"].as<float>();
     weather.info.url = doc_YA["info"]["url"].as<const char *>();
     weather.now = doc_YA["now"].as<int>();
     weather.now_dt = doc_YA["now_dt"].as<const char *>();
	 return true;
}}

bool getWeather()
{
 if(WiFi.status()== WL_CONNECTED){   // проверяем соединение WiFi
    HTTPClient http;                 // Отправляем HTTP GET запрос
    String _host = "api.weather.yandex.ru";
	String _uri = "/v2/informers?lat=" + String(lat, 6) + "&lon=" + String(lon, 6);
    WiFiClient client;
    client.stop();
    http.begin(client, _host, 80, _uri, true);
	http.addHeader("X-Yandex-API-Key", api_key);
    int httpCode = http.GET();

 if (httpCode > 0) { 
  String response = http.getString();
  Serial.println("  ");
  printStr(response);       //выводим ответ yandex 
  decode_json(response); // парсинг данных из JsonObject

#ifdef  Serial_Print  //  отладка      
	  Serial.println(" - - fact - - ");
//      Serial.println(weather.fact.condition);
	  Serial.println(get_description_condition(weather.fact.condition));
      Serial.println(weather.fact.daytime);	  
      Serial.println(weather.fact.feels_like);	  
      Serial.println(weather.fact.humidity);
      Serial.println(weather.fact.icon);
//      Serial.println(weather.fact.obs_time);
	  Serial.println(convert_unix_time(weather.fact.obs_time));
      Serial.println(weather.fact.polar);
      Serial.println(weather.fact.pressure_mm);
      Serial.println(weather.fact.pressure_pa);
//      Serial.println(weather.fact.season);
	  Serial.println(getSeason(weather.fact.season));
      Serial.println(weather.fact.temp);
      Serial.println(weather.fact.temp_water);
      Serial.println(weather.fact.wind_dir);
      Serial.println(weather.fact.wind_gust);
      Serial.println(weather.fact.wind_speed);
	  Serial.println(" - - forecast - - ");
	  Serial.println(weather.forecast.date);
//	  Serial.println(weather.forecast.date_ts);
	  Serial.println(convert_unix_time(weather.forecast.date_ts));
	  Serial.println(weather.forecast.moon_code);
	  Serial.println(weather.forecast.moon_text);
    for (uint8_t i = 0; i < 2; i++)
    {
        Serial.print(" - - part: = "); Serial.println(i);
//    	Serial.println(weather.forecast.parts[i].condition);
		Serial.println(get_description_condition(weather.forecast.parts[i].condition));
    	Serial.println(weather.forecast.parts[i].daytime);
        Serial.println(weather.forecast.parts[i].feels_like);
        Serial.println(weather.forecast.parts[i].humidity);
        Serial.println(weather.forecast.parts[i].icon);
//        Serial.println(weather.forecast.parts[i].part_name); 
		Serial.println(get_partName(weather.forecast.parts[i].part_name));
        Serial.println(weather.forecast.parts[i].polar);
        Serial.println(weather.forecast.parts[i].prec_mm);
        Serial.println(weather.forecast.parts[i].prec_period);
        Serial.println(weather.forecast.parts[i].prec_prob);
        Serial.println(weather.forecast.parts[i].pressure_mm);
        Serial.println(weather.forecast.parts[i].pressure_pa);
        Serial.println(weather.forecast.parts[i].temp_avg);
        Serial.println(weather.forecast.parts[i].temp_max);
        Serial.println(weather.forecast.parts[i].temp_min);
        Serial.println(weather.forecast.parts[i].temp_water);
        Serial.println(weather.forecast.parts[i].wind_dir);
        Serial.println(weather.forecast.parts[i].wind_gust);
        Serial.println(weather.forecast.parts[i].wind_speed);
    } //for	  
	  Serial.println(" - - forecast - - ");
	  Serial.println(weather.forecast.sunrise);
	  Serial.println(weather.forecast.sunset);
	  Serial.println(weather.forecast.week);
	  Serial.println(" - - info - - ");
	  Serial.println(weather.info.lat, 6);
	  Serial.println(weather.info.lon, 6);
	  Serial.println(weather.info.url);
	  Serial.println(" - - now - - ");
//	  Serial.println(weather.now);
	  Serial.println(convert_unix_time(weather.now));
	  Serial.println(weather.now_dt);
#endif
      client.stop();
      http.end();
      return true;
    }
    else
    {
      Serial.println("Connection failed");
      client.stop();
      http.end();
      return false;
    }
}} 

введите или вставьте сюда код

И где код парсинга?

А также, хотелось бы понять зачем её парсить, если яндекс предоставляет погодное API бесплатно (если запросов не более 50 в сутки)

1 лайк

Эй полегче. Так Ваша тема в мусор улетит. Вставляйте код как положено на это форуме (а как положено написано в пустом окне сообщения специально для Вас, но Вы так торопились, что не прочитали)

Я вставляю в первый раз и рабочий код.

Этот тариф бесплатный но ключ надо получить от яндекс для прогноза.

Если улетит в мусор мне от этого пофиг, это работает.

Блин пытаюсь и так и этак но вторая тема не получается

Это тест на IQ. Вы его проваливаете

без проблем Вы выше в этом ваши проблемы

Я давно заметил что кто ничего не может сам … только высказывает критические замечания и это в пееервых рядах
Но этот сайт не даёт хоть убейся встатвить две темы для новичка в один денью

Мы рады за вас. Но проблема у вас, а не у нас. И вы не в состоянии даже код вставить по правилам. Даже не знаю, чем вас утешить :wink:

Вставь нормально код. Сам. Если можешь

ответил ВСЕМ

Отредактировал первое сообщение.
Топикастер пытался, но почему-то вместо трех обратных апострофов `, ставил три запятых

Не тупуе Вас Сайт не дал

И Вам важнее код или оформление

Ну вот, на немецкий перешли 00

там есть кнопочка сверху, если не получается с апострофами
Выделить код и нажать ее можно

Сколько любителей орфографики

В чужой монастырь со своим уставом не ходят. На любом программистском форуме вам будут пенять на вставленный не по правилам код. И везде это рассматривается как неуважение к сообществу.