===== Эксперимент 69. Получение данных с интернет-сервиса =====
Устройства интернета-вещей не только отправляют данные в интернет, но и получают их оттуда. В интернете есть ресурсы, предназначенные для получения информации человеком — обычные сайты. Но кроме того, есть интернет-ресурсы для получения данных другими программами — веб-сервисы. Их главное отличие от обычного сайта в том, что они предоставляют данные в удобном для программ виде, без излишеств. Без визуального оформления, только чистые данные в определенном формате. Форматы предоставления данных могут быть разными.
Попробуем поработать с веб-сервисом. Для получения погодных данных хорошо подходит веб-сервис weatherbit.io. Основные данные о погоде данный сервис предоставляет бесплатно до 500 запросов в сутки, но необходимо пройти простую процедуру регистрации.
Регистрация происходит на странице [[https://www.weatherbit.io/account/create]]
{{ :products:esp-iot:2020-06-15_15-37-57.png?direct&600 |}}
Вводим в поле **Username** логин, например pinlab. В поле **Password** пароль, который нужно придумать. Например 123456789. В поле **Re-Enter Password for Verification** вводим тот же пароль еще раз. В поле **E-mail** вводим адрес электронной почты.
Устанавливаем галочку **I accept the Terms and Conditions and the Privacy Policy**, которой мы подтверждаем согласие с условиями предоставления сервиса. По желанию можно убрать галочку **Send me updates via email**, чтобы не получать писем от этого сервиса.
Ставим галочку **Я не робот** и нажимаем на кнопку **Submit**.
Если выводится сообщение **Signup blocked due to suspected spam. If you are a human, please use another VPN / IP address.** нужно попробовать включить VPN.
Если форма заполнена правильно, то увидим сообщение **Thank you for registering! You may now login to your account, and access your API Key!**, которое сообщает нам, что регистрация пройдена. На этой странице вводим логин и пароль чтобы авторизоваться в сервисе.
{{ :products:esp-iot:2020-06-15_15-44-36.png?direct&600 |}}
После авторизации в сервисе мы попадаем на страницу, где необходимо предоставить немного дополнительной информации. Заполнить ее можно согласно картинке ниже.
{{ :products:esp-iot:2020-06-15_15-46-34.png?direct&600 |}}
* Company Name/Organization — название организации, можно не заполнять или поставить минус
* First Name*, Last Name* — имя и фамилия, можно вписать любые
* Country — страна, можно не заполнять или выбрать RU - Russian Federation
* API Tier* — тарифный план сервиса, обязательно нужно выбрать Free (бесплатный)
* API Usage Purpose* — для чего мы будем использовать сервис, нужно выбрать Personal Use (для собственного использования)
После заполнения формы нажимаем на кнопку Proceed to Dashboard. После этого открывается страница с ключом доступа
{{ :products:esp-iot:2020-06-15_15-51-57.png?direct&600 |}}
В нашем случае наш ключ доступа это 341182dee74d4049a0dc5470919e39fa, он будет другим. Этот ключ самое важное, то для чего мы проходили регистрацию. Этот ключ нужно будет использовать в каждом запросе к сервису.
==== Схема эксперимента ====
Схема отсутствует.
==== Программный код эксперимента ====
#include
#include
#include
#include
#define WIFI_NAME "WiFi_name"
#define WIFI_PASSWORD "WiFi_pass"
String httpGet(String url) {
WiFiClient client;
HTTPClient http;
String data = "";
if (http.begin(client, url)) {
Serial.println("[HTTP] GET");
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("[HTTP] GET code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK) {
data = http.getString();
} else {
Serial.printf("[HTTP] GET failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
} else {
Serial.println("[HTTP] Unable to connect");
}
}
return data;
}
void setup() {
Serial.begin(9600);
Serial.println();
Serial.print("Connecting to WiFi");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
String API_key = "YourApiKey";
String city_name = "Moscow";
String json_data = httpGet("http://api.weatherbit.io/v2.0/current?city=" + city_name + "&key=" + API_key);
Serial.println(json_data);
JsonDocument json_doc;
deserializeJson(json_doc, json_data);
float temp = json_doc["data"][0]["temp"];
Serial.println(temp, 1);
}
void loop() {
}
В коде необходимо заменить
* WiFi_name нужно заменить на имя WifI сети
* WiFi_pass нужно заменить на пароль от нее
* YourApiKey нужно заменить на ключ доступа, который мы получили в сервисе weatherbit.io после регистрации
Нужно заменить имя сети и пароль на свои
wlan_id = "WiFi_name"
wlan_pass = "WiFi_pass"
Создаем объект сетевого интерфейса, активируем его, подключаемся к беспроводной сети и ждем соединения секунду.
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(wlan_id, wlan_pass)
time.sleep(1)
Функция httpGet предназначена для формирования запроса к веб-серверу. В качестве параметров она принимает адрес веб страницы (url) и порт (по умолчанию 80, стандартный для веб-страниц). Функция возвращает данные, полученные от веб сервиса.
Здесь необходимо ввести свой ключ доступа к сервису weatherbit.io, который был получен после регистрации. Moscow - это название города, по которому мы хотим получить погодные данные. В нашем случае это Москва. Названия для других городов можно получить на сайте сервиса [[https://www.weatherbit.io/api]]
String API_key = "YourApiKey";
String city_name = "Moscow";
Отправляем запрос сервису на предоставления данный о текущей погоде
String json_data = httpGet("http://api.weatherbit.io/v2.0/current?city=" + city_name + "&key=" + API_key);
Запрос отправляется на сервер сервиса, и он высылает ответ, который мы получаем в переменной ''json_data''. Ответ от этого сервиса приходит в формате JSON.
[[https://ru.wikipedia.org/wiki/JSON|Подробнее о JSON]]
Выведем полученную строку.
Serial.println(json_data);
В твоем случае данные будут другими так как запрос будет сделан в другое время и будет другая погода). В них много различных параметров, даже больше, чем нам будет нужно.
{'count': 1, 'data': [{'wind_cdir_full': 'south', 'weather': {'code': '804', 'icon': 'c04d', 'description': 'Overcast clouds'}, 'datetime': '2020-06-15:13', 'temp': 23.9, 'station': 'E8051', 'elev_angle': 39.93, 'app_temp': 23.4, 'state_code': '48', 'wind_dir': 183, 'last_ob_time': '2020-06-15T12:46:00', 'solar_rad': 125, 'sunrise': '00:43', 'slp': 1006.8, 'pod': 'd', 'vis': 5, 'pres': 992.6, 'wind_cdir': 'S', 'wind_spd': 1.34, 'ghi': 625.24, 'ts': 1592225160, 'snow': 0, 'uv': 6.73402, 'clouds': 100, 'city_name': 'Moscow', 'precip': 0, 'timezone': 'Europe/Moscow', 'country_code': 'RU', 'dni': 824.53, 'dhi': 102.47, 'sunset': '18:15', 'ob_time': '2020-06-15 12:46', 'h_angle': 40, 'dewpt': 8.7, 'aqi': 42, 'lat': 55.7522, 'rh': 38, 'lon': 37.6156}]}
В переменной ''json_data'' мы получили просто текстовую строку в формате JSON в которой находится информация. Чтобы мы могли работать с ней как с данными нам необходимо преобразовать ее в объект типа ''JsonDocument''. Для работы с JSON мы установили и подключили библиотеку "ArduinoJson".
#include
В следующих строках мы создаем объект (структуру данных) ''json_doc'' и с помощью функции ''deserializeJson'' сохраняем в него данные строки "json_data".
JsonDocument json_doc;
deserializeJson(json_doc, json_data);
Теперь в переменной ''json_doc'' находится структура данных к которой мы можем обращаться. Попробуем выбрать данных температуру и вывести ее в терминал
float temp = json_doc["data"][0]["temp"];
Serial.println(temp, 1);
В нашем случае выводится 23.9
Таким образом мы только что запросили данные о текущей погоде в городе Москва у интернет-сервиса weatherbit.io
Подробное описание данных, которые возвращает сервис можно почитать на [[https://www.weatherbit.io/api/weather-current|странице документации]]