Nodemcu + yandex
- Войдите на сайт для отправки комментариев
Ср, 29/07/2020 - 13:49
Здравствуйте, подскажите пожалуйста. Хочу парсить погоду и время с сайта яндекс. Скетч выводит в сериал время, а вот температуру не хочет. Подскажите пожалуйста,если не сложно
#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,"-"); // Выделяем очередную часть } }
а вы в исходнике страницы яндекса посмотрите - есть ли там погода? Я очень сомневаюсь, что она там прям в явном виде, все новостные сайты давно вместо прямой вставки текста про погоду вставляют в исходник запрос на яваскрипте, который прямо в броузере клиента создает соответвующий контент.
Практически все подобные сайты погоду отдают только на платной основе. А если б погода была прям так в доступе - никто бы не парился с платными сайтами типа WorldWeatherMap , распарсили страничку яндекса и дело в шляпе :)
Не сложно.
Слона нужно есть по частям - весь в рот не поместится.
Вам надо после строки №101 вывести переменную icon в Serial.
Затем отложить в сторону этот скетч и написать новый в котором эта строка (которую Вы выводили) вбита как константа и она разбирается. В скетче нет НИЧЕГО больше, только разбор готовой строки. Когда Вы отладите разбор и он будет нормально работать, только тогда вставляете его в этот скетч.
Сейчас же Вы ДАЖЕ не печатаете ни icon, ни получившийся после строки №102 out. Т.е. Вы завязали себе глаза и пытаетесь угадать что там не так. Нельзя отлаживаться с закрытыми глазами. Выделите разбор в отдельный скетч (чтобы отсечь весь остальной бред), всё печатайте (каждый шаг) и отлаживайте. А то сейчас у Вас в скетче столько мути, что чёрт ногу сломит.
Тем более, похоже, враги украли с Вашей клавиатуры клавишу Ctrl или клавишу Т (или обе вместе), и потому Ваш код отформатирован так, что без поллитры не поймёшь что в какой функции.
извиняюсь, я не знал про Ctrl + T. Я как понял, после 102 идет текущая пода(что предоставил яндекс), а мне она не нужна, как получится, вывести текущее время и температуру, начну скетч скопированный кромсать(закат, рассвет убирать и тп).
Я как понял, после 102 идет текущая пода(что предоставил яндекс), а мне она не нужна, как получится, вывести текущее время и температуру, начну скетч скопированный кромсать(закат, рассвет убирать и тп).
Ничего не понял, но, надеюсь, Вы поняли, что я сказал. Выделите строку и напишите её разбор в отдельном скетче без всего остального бреда.
Думаю, что для парсинга формата JSON, лучше не изобретать велосипед, а использовать библиотеку. В ИДЕ, поиском, их выдаёт с десяток. Пример.
Думаю так понятнее будет:
https://yandex.ru/dev/weather/