Текущая погода и 2 последующих периода (ночь, утро, день или вечер).
Необходимо получить ключ yandex-погоды, тариф “Погода на вашем сайте”.
Подключение к WiFi через WiFiManager, IP - 192.168.4.1, сеть = “ESP8266-Clock”
Web-страница для настройки яркости дисплея, только до отключения питания.
После первого запуска настроить потом прописать в “settings.h” и перепрошить.
Скриншоты иконок и фото дисплея в архиве. (рис. IMG_NA пока не используется)
“settings.h”
Подключение дисплея к ESP8266.
Настройки яркости дисплея (день-ночь).
Два набора иконок однолинейные и полноцветные - на выбор.
Архив - clock_ntp_weather_ya.zip — Яндекс Диск
//* 27.04.2023
// ILI9341 with ESP8266 and Wemos D1
// Display SDO/MISO to NodeMCU pin D6
// Display LED to NodeMCU pin D2
// Display SCK to NodeMCU pin D5
// Display SDI/MOSI to NodeMCU pin D7
// Display DC (RS/AO)to NodeMCU pin D3
// Display RESET to NodeMCU pin D4
// Display CS to NodeMCU pin D8
// Display GND to NodeMCU pin GND (0V)
// Display VCC to NodeMCU 3.3V
//*/
/*--------------- libraries ----------------------*/
#include //version - 6.21.1
#include
#include
#include
#include
#include
#include
#include // version=2.5.23
#include
#include
#include
#include
#include
//*--------------- Project ----------------------*/
#include "Fonts_Img/ArialRoundedMTBold_36.h" // щрифты
#include "Fonts_Img/FreeSansBold6.h"
#include "Fonts_Img/FreeSansBold10.h"
#include "Fonts_Img/FreeSansBold14.h"
#include "settings.h" // Настройки - ввести свои данные!!!
#include "functions.h" // функции обработки
#include "Fonts_Img/html.h" // веб-страница
//*--------------- Image ----------------------*/
#ifdef theme //выбор иконок погоды
#include "Fonts_Img/weather_img2.h"
#else
#include "Fonts_Img/weather_img1.h"
#endif
#define ENABLE_OTA_UPDATE true // OTA обновление
//*--------------- Fonts ----------------------*/
#define AR36 &ArialRoundedMTBold_36 // шрифт температура сейчас
#define RU14 &FreeSansBold14pt8b // шрифт рус. дата
#define RU10 &FreeSansBold10pt8b // шрифт рус. температура период
#define RU6 &FreeSansBold6pt8b // шрифт рус. восход, закат
//*---- ILI9341 with ESP8266 and Wemos D1 -----*/
#define TFT_CS D8
#define TFT_DC D3
#define TFT_RST D4
#define TFT_MOSI D7
#define TFT_MISO D6
#define TFT_CLK D5
#define LED_PIN D2 // управление яркостью дисплея
#define Serial_Print // отладка для работы - закоментить
#define LED_BRIGHTNESS 30 // яркость дисплея при старте
WiFiUDP Udp;
TFT_eSPI tft = TFT_eSPI(); // Use hardware SPI
WiFiManager wifiManager;
ESP8266WebServer server_web(80);
weather_t weather;
StaticJsonDocument<8000> doc;
bool decode_json(String jsonStr);
bool get_YA_Weather();
String convert_unix_time(int unix_time);
String get_description_condition(String str);
String get_partName(String pName);
String getSeason(String season);
time_t prevDisplay = 0;
double temperature = 0.0;
double humidity = 0;
double pressure = 0;
//*------------------- print Img weather --------------------------*/
void print_Img(int x, int y, String condition, String daytime) {
int w, h;
w=60;h=60; // ширина, высота иконки
if ((condition == "clear") and (daytime == "d")) //Ясно день
tft.pushImage(x,y,w,h,img_100);
if ((condition == "clear") and (daytime == "n")) //Ясно ночь
tft.pushImage(x,y,w,h,img_150);
if ((condition == "partly-cloudy") and (daytime == "d")) //Малооблачно день
tft.pushImage(x,y,w,h,img_104);
if ((condition == "partly-cloudy") and (daytime == "n")) //Малооблачно ночь
tft.pushImage(x,y,w,h,img_154);
if ((condition == "cloudy") and (daytime == "d")) //Облачно день
tft.pushImage(x,y,w,h,img_104);
if ((condition == "cloudy") and (daytime == "n")) //Облачно ночь
tft.pushImage(x,y,w,h,img_154);
if (condition == "overcast") //Пасмурно
tft.pushImage(x,y,w,h,img_102);
if ((condition == "drizzle") or (condition == "light-rain") or (condition == "rain")) //Небольшой дождь, Дождь
tft.pushImage(x,y,w,h,img_306);
if ((condition == "moderate-rain") or (condition == "heavy-rain") or (condition == "continuous-heavy-rain") or (condition == "showers")) //Сильный дождь, Ливень
tft.pushImage(x,y,w,h,img_310);
if (condition == "wet-snow") //Дождь со снегом
tft.pushImage(x,y,w,h,img_404);
if ((condition == "light-snow") or (condition == "snow") or (condition == "snow-showers")) //Снег
tft.pushImage(x,y,w,h,img_403);
if (condition == "hail") //Град
tft.pushImage(x,y,w,h,img_313);
if ((condition == "thunderstorm") or (condition == "thunderstorm-with-rain") or (condition == "thunderstorm-with-hail")) //Дождь,гроза
tft.pushImage(x,y,w,h,img_303);
} // end print_Img
//*------------------- TFT weather --------------------------*/
void TFT_weather()
{
get_YA_Weather(); // запрос погоды с яндекс
tft.fillRect ( 2, 123, 316, 115, TFT_BLACK); //область погоды очищаем для перерисовки
print_Img(2, 124, weather.fact.condition, weather.fact.daytime); //рисуем картинку на TFT текущая погода
tft.setFreeFont(AR36);
tft.setTextColor(TFT_YELLOW, TFT_BLACK, true);
int xpos = 65; // координаты отрисовки температуры
if (weather.fact.temp > 0)
xpos += tft.drawString("+" + String(weather.fact.temp), xpos,130); // добавляем "+" к положительной текущей температуре
else
xpos += tft.drawString(String(weather.fact.temp), xpos,130); // текущая температура
tft.setTextFont(2);
xpos += tft.drawString(" o", xpos,130); // " °C" добавляем градус к температуре
tft.setFreeFont(AR36);
xpos += tft.drawString("C", xpos,130);
tft.setFreeFont(RU10);
tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
tft.drawString(utf8rus( get_description_condition(weather.fact.condition )), 5, 184); // текущая погода
tft.setTextColor(TFT_CYAN, TFT_BLACK, true);
tft.drawString(String(weather.fact.pressure_mm) + utf8rus(" мм.р.ст."), 65,165); // текущее давление
tft.setTextColor(TFT_DARKGREY, TFT_BLACK, true);
tft.drawString(utf8rus(get_partName(weather.forecast.parts[0].part_name)), 184, 185); // 1-й период погода
print_Img(184, 125, weather.forecast.parts[0].condition, weather.forecast.parts[0].daytime); //рисуем картинку на TFT 1-й период
tft.drawString(utf8rus(get_partName(weather.forecast.parts[1].part_name)), 254, 185); // 2-й период погода
print_Img(254, 125, weather.forecast.parts[1].condition, weather.forecast.parts[1].daytime); //рисуем картинку на TFT 2-й период
tft.setTextColor(TFT_YELLOW, TFT_BLACK, true);
xpos = 184; // 1-й период температура " °C"
if (weather.forecast.parts[0].temp_avg > 0)
xpos += tft.drawString("+" + String(weather.forecast.parts[0].temp_avg), xpos,210);
else
xpos += tft.drawString(String(weather.forecast.parts[0].temp_avg), xpos,210);
tft.setTextFont(0);
xpos += tft.drawString(" o", xpos,210); // " °C" добавляем градус к температуре
tft.setFreeFont(RU10);
xpos += tft.drawString("C", xpos,210);
xpos = 254; // 2-й период температура
if (weather.forecast.parts[1].temp_avg > 0)
xpos += tft.drawString("+" + String(weather.forecast.parts[1].temp_avg), xpos,210); // добавляем "+" к положительной температуре
else
xpos += tft.drawString(String(weather.forecast.parts[1].temp_avg), xpos,210);
tft.setTextFont(0);
xpos += tft.drawString(" o", xpos,210); // " °C" добавляем градус к температуре
tft.setFreeFont(RU10);
xpos += tft.drawString("C", xpos,210);
tft.setTextColor(TFT_GREENYELLOW, TFT_BLACK, true);
tft.setFreeFont(RU6);
xpos = tft.drawString(utf8rus("Восход:"), 5, 207);
tft.drawString(weather.forecast.sunrise, xpos+10, 207); // Восход
tft.drawString(utf8rus("Закат:"), 5, 223); // выравниваем время восхода и заката
tft.drawString(weather.forecast.sunset, xpos+10, 223); // Закат
tft.drawLine( 256, 40, 256, 115, TFT_GREENYELLOW ); //область секунд и дня недели 1
tft.drawLine( 256, 85, 316, 85, TFT_GREENYELLOW ); //область секунд и дня недели 2
tft.drawRect( 1, 1, 319, 122, TFT_NAVY ); //область часы и дата
tft.drawRect( 1, 122, 319, 118, TFT_NAVY ); //область погоды
tft.drawLine( 182, 122, 182, 240, TFT_NAVY ); //область периодов погоды
} // end TFT_weather
//*------------ TFT Clocktime -----------------------------*/
void draw_Clocktime()
{
String str;
int len;
uint8_t hh = hour(), mm = minute(), ss = second(); // Get H, M, S from compile time
if ((hh == 0) and (mm == 0) and (ss == 0))
{
tft.fillRect ( 5, 40, 53, 76, TFT_BLACK); // Очистить первый 0 в "00" в часах в 00:00:00 от остатка двойки 23:59:59
tft.fillRect ( 2, 2, 314, 40, TFT_BLACK); // Очистить дату
tft.fillRect ( 262, 89, 56, 30, TFT_BLACK); // Очистить день недели
}
if (( hh == 0 ) and ( mm == 0 ))
{
tft.setFreeFont(RU14);
tft.setTextColor(TFT_YELLOW, TFT_BLACK, true);
str = utf8rus( days[ weekday() ] );
tft.drawString( str, 265, 87 ); // день недели
str = utf8rus( String( day() ) + " " + months[ month() ] + " " + year() ); // день, месяц и год
tft.drawString( str, 160 - tft.textWidth(str) / 2, 2 );
tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
}
byte omm = 99, oss = 99;
byte xcolon = 0, xsecs = 0;
int xpos = 5; // // d:\arduino-1.8.19\...\libraries\TFT_eSPI\examples\320 x 240\TFT_Clock_Digital
int ypos = 40; // Верхний левый угол текста часов
int ysecs = ypos + 24;
if (omm != mm) { // Обновлять часы и минуты каждую минуту
omm = mm;
// рисуем часы и минуты
tft.setTextColor(TFT_BLACK, TFT_BLACK, true);
if (hh < 10) xpos += tft.drawChar('0', xpos, ypos, 8); // Добавить 0 в часы для 24-часового формата и сохранение позиции на дисплее.
tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
xpos += tft.drawNumber(hh, xpos, ypos, 8); // рисуем часы
xcolon = xpos; // Сохранение координат двоеточия, чтобы мигать позже
xpos += tft.drawChar(':', xpos, ypos - 8, 8);
if (mm < 10) xpos += tft.drawChar('0', xpos, ypos, 8); // Добавить 0 в минуты
xpos += tft.drawNumber(mm, xpos, ypos, 8); // рисуем минуты
xsecs = xpos; // Сохранение положения секунд «x» для последующих обновлений дисплея
}
if (oss != ss) { // Перерисовывать секунды каждую секунду
oss = ss;
xpos = xsecs;
if (ss % 2) { // Включить/выключить двоеточие
tft.setTextColor(TFT_BLACK, TFT_BLACK, true); // затемнить двоеточие
tft.drawChar(':', xcolon, ypos - 8, 8); // Час:минута двоеточие
tft.setTextColor(TFT_WHITE, TFT_BLACK, true); // Вернуть цвет
}
else {
tft.drawChar(':', xcolon, ypos - 8, 8); // Час:минута двоеточие
}
//рисуем секунды
if (ss < 10) xpos += tft.drawChar('0', xpos+8, ypos-3, 6); // Добавить 0
tft.drawNumber(ss, xpos+8, ypos-3, 6); // рисуем секунды
}
} // end TFT Clocktime
void refresh_display()
{
draw_Clocktime();
if ( ( minute() == 59 ) && ( second() == 59 ) ) //обновление погоды 1 раз в 59 мин 59 секунд
{
TFT_weather();
serial_digitalClockDisplay();
Serial.println("Get weather");
}
} // end refresh_display
//*------------------ setup -----------------------------------*/
void setup()
{
pinMode(LED_PIN, OUTPUT);
analogWriteFreq(32768);
analogWrite(LED_PIN, LED_BRIGHTNESS); // первоначальная яркость дисплея
Serial.begin(115200);
delay(250);
// Раскомментировать и запустить один раз, если надо стереть всю сохраненную информацию о WiFi в памяти ESP8266
//wifiManager.resetSettings();
tft.begin();
tft.setSwapBytes(true); //Используется 16-битным pushImage() для изменения порядка байтов в цветах.
tft.setRotation(1);
tft.setTextSize(2);
tft.fillScreen(TFT_BLACK);
tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
tft.setCursor(0, 26);
tft.println("Connecting");
Serial.println("");
Serial.println("NTP Clock");
Serial.print("Connecting to ");
Serial.println(WiFi.SSID());
initWiFi();
tft.println("");
tft.println(WiFi.SSID());
tft.print("IP: ");
tft.println(WiFi.localIP());
tft.println("Starting UDP");
Udp.begin(localPort);
tft.print("Local port ");
tft.println(Udp.localPort());
tft.println("Time sync");
setSyncProvider(getNtpTime); //Функция setSyncProvider(getTimeFunction) настраивает время
setSyncInterval(3600); // Функция setSyncInterval(interval) задает количество секунд между синхронизациями
tft.println("Weather request");
display_brightness();
delay(2500); // читаем что вывели на дисплей
if ( ENABLE_OTA_UPDATE )
{
tft.println("Begin OTA handler Esp8266_Clock");
initOTA(); // обновление по WiFi
}
tft.setTextSize(1);
tft.fillScreen(TFT_BLACK);
String str;
tft.setFreeFont(RU14);
tft.setTextColor(TFT_YELLOW, TFT_BLACK, true);
str = utf8rus( days[ weekday() ] ); // день недели
tft.drawString( str, 265, 87 );
str = utf8rus( String( day() ) + " " + months[ month() ] + " " + year() ); // день, месяц и год
tft.drawString( str, 160 - tft.textWidth(str) / 2, 2 );
tft.setTextColor(TFT_WHITE, TFT_BLACK, true);
server_web.on("/", handle_OnConnect);
server_web.on("/update", handle_update);
server_web.onNotFound(handle_NotFound); //любой URL, отличный от указанного в server.on() = ответить HTTP-статусом 404 (Not Found)
server_web.begin();//запустить сервер
draw_Clocktime();
TFT_weather(); // отрисовка погоды
}//end setup
//*------------------ loop -----------------------------------*/
void loop()
{
if ( ENABLE_OTA_UPDATE )
{
ArduinoOTA.handle();
}
if (timeStatus() != timeNotSet)
{
// обновляем дисплей только если время поменялось
if (now() != prevDisplay) //Функция now() считывает время, прошедшее с 1 января 1970 года (в секундах).
{
prevDisplay = now(); //Конструкция time_t t = now() сохраняет текущее время в переменную t.
display_brightness();
refresh_display();
}
}
if ((millis() > 60*1000) and (year() == 1970) and (WiFi.status() == WL_CONNECTED)) //при старте время не было задано
{
restart();
}
server_web.handleClient();
} //end loop
//*------------------ web-html -----------------------------------*/
void handle_OnConnect() {
Serial.println("Web started");
server_web.send(200, "text/html", index_html);
} // end handle_OnConnect
void handle_update() {
server_web.send(200, "text/html", index_html);
slider_day = server_web.arg("brightness_day").toInt();
day_ = server_web.arg("hour_day").toInt();
slider_night = server_web.arg("brightness_night").toInt();
night_ = server_web.arg("hour_night").toInt();
Serial.println(slider_day);
Serial.println(day_);
Serial.println(slider_night);
Serial.println(night_);
} // end handle_update
void handle_NotFound(){
server_web.send(404, "text/plain", "Not found");
} // end handle_NotFound
// перезапуск ESP8266
void restart()
{
Serial.println("Restart ESP...");
ESP.restart();
} // end restart
void display_brightness() // яркость дисплея
{
if ( ( hour() >= day_ ) and ( hour() < night_ ) )
{
analogWrite(LED_PIN, slider_day);
}
else
{
analogWrite(LED_PIN, slider_night);
}
} // end display_brightness
//*------------------ WiFi -----------------------------------*/
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin();//переключиться в режим станции и подключиться к последней точке доступа на основе данных, сохраненных во flash-памяти.
// WiFi.begin(ssid, pass);
//Если persistent - false,то SSID и пароль будут записаны на flash-память только если новые значения не будут соответствовать тем, что хранятся во flash-памяти.
WiFi.persistent(false);
WiFi.setAutoReconnect(true);// true, модуль сделает попытку повторного подключения к точке доступа, а если false, то нет.
Serial.println("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED && millis()<15*1000) {
delay(500);
Serial.print(".");
}
if(WiFi.status() == WL_CONNECTED){
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
else {
Serial.println("WiFi not connected, starting WiFiManager");
tft.println("WiFi not connected...");
tft.println("Starting WiFiManager");
tft.println("SSID: ESP8266-Clock");
tft.print("IP address: ");
tft.println("192.168.4.1");
wifiManager.autoConnect("ESP8266-Clock");
delay(2000);
}
} // end initWiFi
//*------------------ json -----------------------------------*/
bool decode_json(String jsonStr) // https://github.com/discover1977/YWInformer
{
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();
weather.fact.condition = doc_YA["fact"]["condition"].as(); // парсинг данных из JsonObject
weather.fact.daytime = doc_YA["fact"]["daytime"].as();
weather.fact.feels_like = doc_YA["fact"]["feels_like"].as();
weather.fact.humidity = doc_YA["fact"]["humidity"].as();
weather.fact.icon = doc_YA["fact"]["icon"].as();
weather.fact.obs_time = doc_YA["fact"]["obs_time"].as();
weather.fact.polar = doc_YA["fact"]["polar"].as();
weather.fact.pressure_mm = doc_YA["fact"]["pressure_mm"].as();
weather.fact.pressure_pa = doc_YA["fact"]["pressure_pa"].as();
weather.fact.season = doc_YA["fact"]["season"].as();
weather.fact.temp = doc_YA["fact"]["temp"].as();
weather.fact.temp_water = doc_YA["fact"]["temp_water"].as();
weather.fact.wind_dir = doc_YA["fact"]["wind_dir"].as();
weather.fact.wind_gust = doc_YA["fact"]["wind_gust"].as();
weather.fact.wind_speed = doc_YA["fact"]["wind_speed"].as();
weather.forecast.date = doc_YA["forecast"]["date"].as();
weather.forecast.date_ts = doc_YA["forecast"]["date_ts"].as();
weather.forecast.moon_code = doc_YA["forecast"]["moon_code"].as();
weather.forecast.moon_text = doc_YA["forecast"]["moon_text"].as();
for (uint8_t i = 0; i < 2; i++)
{
weather.forecast.parts[i].condition = doc_YA["forecast"]["parts"][i]["condition"].as();
weather.forecast.parts[i].daytime = doc_YA["forecast"]["parts"][i]["daytime"].as();
weather.forecast.parts[i].feels_like = doc_YA["forecast"]["parts"][i]["feels_like"].as();
weather.forecast.parts[i].humidity = doc_YA["forecast"]["parts"][i]["humidity"].as();
weather.forecast.parts[i].icon = doc_YA["forecast"]["parts"][i]["icon"].as();
weather.forecast.parts[i].part_name = doc_YA["forecast"]["parts"][i]["part_name"].as();
weather.forecast.parts[i].polar = doc_YA["forecast"]["parts"][i]["polar"].as();
weather.forecast.parts[i].prec_mm = doc_YA["forecast"]["parts"][i]["prec_mm"].as();
weather.forecast.parts[i].prec_period = doc_YA["forecast"]["parts"][i]["prec_period"].as();
weather.forecast.parts[i].prec_prob = doc_YA["forecast"]["parts"][i]["prec_prob"].as();
weather.forecast.parts[i].pressure_mm = doc_YA["forecast"]["parts"][i]["pressure_mm"].as();
weather.forecast.parts[i].pressure_pa = doc_YA["forecast"]["parts"][i]["pressure_pa"].as();
weather.forecast.parts[i].temp_avg = doc_YA["forecast"]["parts"][i]["temp_avg"].as();
weather.forecast.parts[i].temp_max = doc_YA["forecast"]["parts"][i]["temp_max"].as();
weather.forecast.parts[i].temp_min = doc_YA["forecast"]["parts"][i]["temp_min"].as();
weather.forecast.parts[i].temp_water = doc_YA["forecast"]["parts"][i]["temp_water"].as();
weather.forecast.parts[i].wind_dir = doc_YA["forecast"]["parts"][i]["wind_dir"].as();
weather.forecast.parts[i].wind_gust = doc_YA["forecast"]["parts"][i]["wind_gust"].as();
weather.forecast.parts[i].wind_speed = doc_YA["forecast"]["parts"][i]["wind_speed"].as();
}
weather.forecast.sunrise = doc_YA["forecast"]["sunrise"].as();
weather.forecast.sunset = doc_YA["forecast"]["sunset"].as();
weather.forecast.week = doc_YA["forecast"]["week"].as();
weather.info.lat = doc_YA["info"]["lat"].as();
weather.info.lon = doc_YA["info"]["lon"].as();
weather.info.url = doc_YA["info"]["url"].as();
weather.now = doc_YA["now"].as();
weather.now_dt = doc_YA["now_dt"].as();
return true;
}} // end decode_json
//*-------------- Weather code -------------------------*/
bool get_YA_Weather() // запрос погоды с яндекс
{
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(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(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(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(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(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(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;
}
}} // end getWeather
//*-------------- NTP code -------------------------*/ // https://wikihandbk.com/wiki/Arduino:%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B/TimeNTP_ESP8266WiFi
const int NTP_PACKET_SIZE = 48; // NTP-время – в первых 48 байтах сообщения
byte packetBuffer[NTP_PACKET_SIZE]; // буфер для хранения входящих и исходящих пакетов
// отправляем NTP-запрос серверу времени по указанному адресу:
void sendNTPpacket(IPAddress &address)
{
// задаем все байты в буфере на «0»:
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// инициализируем значения для создания NTP-запроса (подробнее о пакетах смотрите по ссылке выше)
packetBuffer[0] = 0b11100011; // LI (от «leap indicator», т.е. «индикатор перехода»), версия, режим работы
packetBuffer[1] = 0; // слой (или тип часов)
packetBuffer[2] = 6; // интервал запросов
packetBuffer[3] = 0xEC; // точность
// 8 байтов с нулями, обозначающие базовую задержку и базовую дисперсию:
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// После заполнения всех указанных полей можно отправлять пакет с запросом о временной метке:
Udp.beginPacket(address, 123); // NTP-запросы к порту 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
} // end sendNTPpacket
time_t getNtpTime()
{
IPAddress ntpServerIP; // IP-адрес NTP-сервера
while (Udp.parsePacket() > 0) ; // отбраковываем все пакеты, полученные ранее
Serial.println("Transmit NTP Request"); // "Передача NTP-запроса"
WiFi.hostByName(ntpServerName, ntpServerIP); // подключаемся к случайному серверу из списка:
Serial.print(ntpServerName);
Serial.print(": ");
Serial.println(ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
Serial.println("Receive NTP Response"); // "Получение NTP-ответа"
Udp.read(packetBuffer, NTP_PACKET_SIZE); // считываем пакет в буфер
unsigned long secsSince1900;
//конвертируем 4 байта (начиная с позиции 40) в длинное целое число:
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
Serial.println("No NTP Response :-("); // "Нет NTP-ответа :("
return 0; // если время получить не удалось, возвращаем «0»
} // end getNtpTime
Библиотеки, Почему в коде не отображаются - не знаю. В окне редактирования видны.
//--------------- libraries ----------------------/
#include <ArduinoJson.h> //version - 6.21.1
#include <ESP8266WiFi.h>
#include <SPI.h>
#include <TimeLib.h>
#include <ArduinoOTA.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <TFT_eSPI.h> // version=2.5.23
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
Иконки: