Nodemcu + yandex

fanat.arduino
Offline
Зарегистрирован: 10.11.2019

Здравствуйте, подскажите пожалуйста. Хочу парсить погоду и время с сайта яндекс. Скетч выводит в сериал время, а вот температуру не хочет. Подскажите пожалуйста,если не сложно

#include <ESP8266WiFi.h>                  // Библиотека для создания Wi-Fi подключения (клиент или точка доступа)
#include <WiFiClient.h>                   // Библиотека для связи с сетевыми хостами (локальными и интернет)
#include <TimeLib.h>                      // Библиотека для работы с временем
//#include <ArduinoJson.h>                  // Библиотека для разбора JSON
const char* ssid = "Pixel";            // Указываем имя WiFi-сети, к которой будет подключаться ESP8266 для доступа в Интернет
const char* password = "qwertyuiop";    // Указываем пароль для подключения к WiFi-сети
String regionID = "35";                  // Код региона по Yandex для выбора часового пояса <a href="<a href="https://tech.yandex.ru/xml/doc/dg/reference/regions-docpage/" rel="nofollow">https://tech.yandex.ru/xml/doc/dg/reference/regions-docpage/</a>" title="<a href="https://tech.yandex.ru/xml/doc/dg/reference/regions-docpage/" rel="nofollow">https://tech.yandex.ru/xml/doc/dg/reference/regions-docpage/</a>" rel="nofollow"><a href="https://tech.yandex.ru/xml/doc/dg/reference/regions-docpage/" rel="nofollow">https://tech.yandex.ru/xml/doc/dg/reference/regions-docpage/</a></a>
String SunriseTime, SunsetTime, Temperature;
char icon[20];
WiFiClient client;                        // Создаём объект для работы с удалёнными хостами
void setup() {
Serial.begin(115200);                                         // Инициализируем вывод данных на серийный порт со скоростью 9600 бод
Serial.println("\n\n");
WiFi.begin(ssid, password);                                 // Соединяемся с WiFi-сетью
 while (WiFi.status() != WL_CONNECTED)                       // Пока соединение не установено
delay(500);                                               //  делаем задержку в пол секунды, пока соединение не установится
while (!TimeAndWeather())                                   // Синхронизируем время микроконтроллера с реальным временем и получаем информацию о погоде
delay(500);
Serial.print("Tekuschie data i vremya: ");
digitalClockDisplay();                                      // Выводим дату и время
Serial.println();
//Serial.println("Voshod v " + SunriseTime);                  // Выводим время восхода
//Serial.println("Zakat v " + SunsetTime);                    // Выводим время восхода
Serial.println();
Serial.println("Temperatura: " + Temperature + " C");       // Выводим время восхода
WeatherDisplay();                                           // Выводим информацию о погоде
}
void loop() {}
bool TimeAndWeather () {                                                    // Функция синхронизации времени работы программы с реальным временем и получения информации о погоде
if (client.connect("yandex.com",443)) {                                   // Если удаётся установить соединение с указанным хостом (Порт 443 для https)
client.println("GET /time/sync.json?geo=" + regionID + " HTTP/1.1\r\nHost: yandex.com\r\nConnection: close\r\n\r\n"); // Отправляем параметры запроса
delay(300);                                                             // Даём серверу время, чтобы обработать запрос
char endOfHeaders[] = "\r\n\r\n";                                       // Системные заголовки ответа сервера отделяются от остального содержимого двойным переводом строки
 if (!client.find(endOfHeaders)) {                                       // Отбрасываем системные заголовки ответа сервера
 Serial.println("Invalid response");                                   // Если ответ сервера не содержит системных заголовков, значит что-то пошло не так
return false;                                                         // и пора прекращать всё это дело
}
Serial.println("chitaem dannie"); 
String line2;
while ( client.available() )
 {
char c = client.read();
line2 += c;
}
Serial.print("line2= ");
Serial.println(line2);
String StringCurrentTime = line2.substring(8,18);
 int n_offset=line2.indexOf("offset");
int  k_offset = line2.indexOf(',',n_offset);
String StringOffset= line2.substring(n_offset+8,k_offset); //18000000
int n_sunrise=line2.indexOf("sunrise");
int  k_sunrise = line2.indexOf(',',n_sunrise);
SunriseTime= line2.substring(n_sunrise+9,k_sunrise); //18000000
int n_sunset=line2.indexOf("sunset");
int  k_sunset = line2.indexOf(',',n_sunset);
 SunsetTime= line2.substring(n_sunset+8,k_sunset); //18000000
int n_temp=line2.indexOf("temp");
int  k_temp = line2.indexOf(',',n_temp);
Temperature= line2.substring(n_temp+6,k_temp); //18000000
int n_icon=line2.indexOf("icon");
int  k_icon = line2.indexOf(',',n_icon);
String Stringicon= line2.substring(n_icon+6,k_icon); //18000000
client.stop();                                                          // Разрываем соединение с сервером
strcpy(icon,Stringicon.c_str());       // Достаём иконку - Четвёртый уровень вложенности пары ключ/значение clocks -> значение RegionID -> weather -> icon
unsigned long CurrentTime = StringToULong(StringCurrentTime);           // Переводим значение реального времени в секундах, считанное с Яндекса, из String в unsigned long
 unsigned long Offset = StringToULong(StringOffset) / 1000;              // Переводим значение смещения времени по часовому поясу, считанное с Яндекса, из String в unsigned long и переводим его в секунды
setTime(CurrentTime + Offset);                                          // Синхронизируем время
return true;
}
}
unsigned long StringToULong(String Str) {                     // Эта функция преобразует String в unsigned long
unsigned long ULong = 0;
for (int i = 0; i < Str.length(); i++) {                    // В цикле посимвольно переводим строку в unsigned long
char c = Str.charAt(i);
if (c < '0' || c > '9') break;
ULong *= 10;
ULong += (c - '0');
}
return ULong;
}
void digitalClockDisplay(){                                   // Эта функция выводит дату и время на монитор серийного порта
//Serial.print(leadNull(day()));
//Serial.print(".");
//Serial.print(leadNull(month()));
//Serial.print(".");
 //Serial.print(year());
//Serial.print(" ");
Serial.print(leadNull(hour()));
//Serial.print(":");
Serial.print(leadNull(minute()));
//Serial.print(":");
//Serial.print(leadNull(second()));
Serial.println();
}
String leadNull(int digits){                                    // Функция добавляет ведущий ноль
String out = "";
 if(digits < 10)
out += "0";                                              
return out + String(digits);
}
void WeatherDisplay(){ 
char * out = strtok(icon,"-");        // Выделяем первую часть из строки до символа '-'
while (out != NULL) {                 // Выделяем последующие части строки в цикле, пока значение out не станет нулевым (пустым)
if (String(out) == "skc")         // Перебираем в условиях все возможные варианты, зашифрованные в названии иконки
 Serial.println("Yasno");
 else if (String(out) == "ovc")
Serial.println("Pasmurno");
else if (String(out) == "bkn")
Serial.println("Oblachno");
else if (String(out) == "ra")
 Serial.println("Dozhd'");
else if (String(out) == "ts")
Serial.println("Groza");
 else if (String(out) == "sn")
Serial.println("Sneg");
 else if (String(out) == "bl")
Serial.println("Metel'");
 else if (String(out) == "fg")
Serial.println("Tuman");
else if (String(out) == "n")
Serial.println("\nTemnoe vremya sutok");
 else if (String(out) == "d")
Serial.println("\nSvetloe vremya sutok");
 out = strtok(NULL,"-");              // Выделяем очередную часть
}
}

 

b707
Offline
Зарегистрирован: 26.05.2017

а вы в исходнике страницы яндекса посмотрите - есть ли там погода? Я очень сомневаюсь, что она там прям в явном виде, все новостные сайты давно вместо прямой вставки текста про погоду вставляют в исходник запрос на яваскрипте, который прямо в броузере клиента создает соответвующий контент.

Практически все подобные сайты погоду отдают только на платной основе. А если б погода была прям так в доступе - никто бы не парился с платными сайтами типа WorldWeatherMap , распарсили страничку яндекса и дело в шляпе :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

fanat.arduino пишет:
Подскажите пожалуйста,если не сложно

Не сложно.

Слона нужно есть по частям - весь в рот не поместится.

Вам надо после строки №101 вывести переменную icon в Serial.

Затем отложить в сторону этот скетч и написать новый в котором эта строка (которую Вы выводили) вбита как константа и она разбирается. В скетче нет НИЧЕГО больше, только разбор готовой строки. Когда Вы отладите разбор и он будет нормально работать, только тогда вставляете его в этот скетч.

Сейчас же Вы ДАЖЕ не печатаете ни icon, ни получившийся после строки №102 out. Т.е. Вы завязали себе глаза и пытаетесь угадать что там не так. Нельзя отлаживаться с закрытыми глазами. Выделите разбор в отдельный скетч (чтобы отсечь весь остальной бред), всё печатайте (каждый шаг) и отлаживайте. А то сейчас у Вас в скетче столько мути, что чёрт ногу сломит. 

Тем более, похоже, враги украли с Вашей клавиатуры клавишу Ctrl или клавишу Т (или обе вместе), и потому Ваш код отформатирован так, что без поллитры не поймёшь что в какой функции.

fanat.arduino
Offline
Зарегистрирован: 10.11.2019


{"time":1596021624431,"clocks":{"35":{"id":35,"name":"Краснодар","offset":10800000,"offsetString":"UTC+3:00","showSunriseSunset":true,"sunrise":"05:06","sunset":"19:54","isNight":false,"skyColor":"#62bdfa","weather":{"temp":29,"icon":"bkn-d","link":"https://yandex.ru/pogoda/krasnodar"},"parents":[{"id":10995,"name":"Краснодарский край"},{"id":225,"name":"Россия"}]}}}
"temp":29, - это разве не температура,мне погода не сильна нужна.
fanat.arduino
Offline
Зарегистрирован: 10.11.2019

извиняюсь, я не знал про Ctrl + T. Я как понял, после 102 идет текущая пода(что предоставил яндекс), а мне она не нужна, как получится, вывести текущее время и температуру, начну скетч скопированный кромсать(закат, рассвет убирать и тп).

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

fanat.arduino пишет:

Я как понял, после 102 идет текущая пода(что предоставил яндекс), а мне она не нужна, как получится, вывести текущее время и температуру, начну скетч скопированный кромсать(закат, рассвет убирать и тп).

Ничего не понял, но, надеюсь, Вы поняли, что я сказал. Выделите строку и напишите её разбор в отдельном скетче без всего остального бреда.

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Думаю, что для парсинга формата JSON, лучше не изобретать велосипед, а использовать библиотеку. В ИДЕ, поиском, их выдаёт с десяток. Пример.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Думаю так понятнее будет:

https://yandex.ru/dev/weather/