Forget the past and surpass yourself
- Blog homepage Microcontroller rookie brother, a wild non-professional hardware IOT enthusiast
- Creation record of this article 2023-10-21
- Update record of this article 2023-10-21
- Welcome to follow Like Collection Leave a message
- This blog is written by the blogger alone and is not operated by any commercial team. If you find any errors, please leave a message! Correct in time! Thanks for the support!
- The Arduino ESP8266 tutorial has helped more than 10,000 students get started learning hardware network programming. They have been selected for elective courses and have been published in radio magazines. From getting started to being familiar with the Arduino platform, developing ESP8266 will also involve network programming knowledge. There are more than 60 column articles in total, divided into basic articles, network articles, application articles, and advanced articles, covering most of the ESP8266 development techniques.
Quick Navigation
Microcontroller novice’s blog quick index (quickly find what you want)
If you find it useful, please like and save it. Your support is the motivation for the blogger’s creation.
Article directory
-
- 1 Introduction
- 2. Related code
1. Preface
When getting weather information from Zephyr Weather, since Zephyr Weather uses Gzip compression to return the data stream, the returned data needs to be decompressed.
By default, the Zephyr Weather Free Key has been applied for
https://dev.qweather.com/docs/api/weather/weather-now/
And there happens to be an Arduino library for this function,
https://github.com/tignioj/ArduinoUZlib
2. Related code
Zefeng Weather API uses HTTPS to obtain relevant weather data, and the returned data uses GZIP compression.
After obtaining the data, use the int result=ArduinoUZlib::decompress(inbuff, size, outbuf,outsize);
function in the UZlib library to decompress it.
HeFeng.h code
#pragma once #include <ArduinoJson.h> typedef struct HeFengCurrentData {<!-- --> String cond_txt; String fl; String tmp; String hum; String wind_sc; String iconMeteCon; } HeFengCurrentData; typedef struct HeFengForeData {<!-- --> String dateStr; String tmp_min; String tmp_max; String iconMeteCon; } HeFengForeData; class HeFeng {<!-- --> private: String getMeteConIcon(String cond_code); bool fetchBuffer(const char* url); static uint8_t _buffer[1024 * 3]; //gzip stream maximum buffer static size_t _bufferSize; public: HeFeng(); void doUpdateCurr(HeFengCurrentData *data, String key, String location); void doUpdateFore(HeFengForeData *data, String key, String location); }; </code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">
HeFeng.cpp code
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClientSecureBearSSL.h> #include "ArduinoUZlib.h" // gzip library #include "HeFeng.h" uint8_t HeFeng::_buffer[1024 * 3]; size_t HeFeng::_bufferSize = 0; HeFeng::HeFeng() {<!-- --> } bool HeFeng::fetchBuffer(const char *url) {<!-- --> _bufferSize = 0; std::unique_ptr<WiFiClientSecure> client(new WiFiClientSecure); client->setInsecure(); HTTPClient https; Serial.print("[HTTPS] begin...now\\ "); if (https.begin(*client, url)) {<!-- --> https.addHeader("Accept-Encoding", "gzip"); https.setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/115.0"); int httpCode = https.GET(); if (httpCode > 0) {<!-- --> if (httpCode == HTTP_CODE_OK) {<!-- --> int len = https.getSize(); // get length of document (is -1 when Server sends no Content-Length header) static uint8_t buff[128 * 1] = {<!-- -->0}; // create buffer for read int offset = 0; // read all data from server while (https.connected() & amp; & amp; (len > 0 || len == -1)) {<!-- --> size_t size = client->available(); // get available data size if(size) {<!-- --> int c = client->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size)); memcpy(_buffer + offset, buff, sizeof(uint8_t) * c); offset + = c; if (len > 0) {<!-- --> len -= c; } } delay(1); } _bufferSize = offset; } } else {<!-- --> Serial.printf("[HTTPS] GET... failed, error: %s\\ ", https.errorToString(httpCode).c_str()); } https.end(); }else{<!-- --> Serial.printf("Unable to connect\\ "); } Serial.print("[HTTPS] end...now\\ "); return _bufferSize > 0; } void HeFeng::doUpdateCurr(HeFengCurrentData *data, String key, String location) {<!-- --> //Get the weather String url = "https://devapi.qweather.com/v7/weather/now?lang=en & amp;gzip=n & amp;location=" + location + " & amp;key=" + key; Serial.print("[HTTPS] begin...now\\ "); fetchBuffer(url.c_str()); // HTTPS gets the data stream if (_bufferSize){<!-- --> Serial.print("bufferSize:"); Serial.println(_bufferSize, DEC); uint8_t *outBuf=NULL; size_t outLen = 0; ArduinoUZlib::decompress(_buffer, _bufferSize, outBuf, outLen); // GZIP decompression // Output the decrypted data to the console. Serial.write(outBuf,outLen); if(outBuf & amp; & amp; outLen){<!-- --> DynamicJsonDocument jsonBuffer(2048); deserializeJson(jsonBuffer, (char*)outBuf,outLen); JsonObject root = jsonBuffer.as<JsonObject>(); String tmp = root["now"]["temp"];//Temperature data->tmp = tmp; String fl = root["now"]["feelsLike"];//Feeling temperature data->fl = fl; String hum = root["now"]["humidity"];//Humidity data->hum = hum; String wind_sc = root["now"]["windScale"];//wind power data->wind_sc = wind_sc; String cond_code = root["now"]["icon"];//Weather icon String meteConIcon = getMeteConIcon(cond_code); String cond_txt = root["now"]["text"];//Weather data->cond_txt = cond_txt; data->iconMeteCon = meteConIcon; jsonBuffer.clear(); } else {<!-- --> Serial.println("doUpdateCurr failed"); data->tmp = "-1"; data->fl = "-1"; data->hum = "-1"; data->wind_sc = "-1"; data->cond_txt = "no network"; data->iconMeteCon = ")"; } //Be sure to remember to release memory if(outBuf != NULL) {<!-- --> free(outBuf); outBuf=NULL; } _bufferSize = 0; } } void HeFeng::doUpdateFore(HeFengForeData *data, String key, String location) {<!-- --> //Get the forecast String url = "https://devapi.qweather.com/v7/weather/3d?lang=en & amp;gzip=n & amp;location=" + location + " & amp;key=" + key; Serial.print("[HTTPS] begin...forecast\\ "); fetchBuffer(url.c_str()); // HTTPS gets the data stream if (_bufferSize){<!-- --> Serial.print("bufferSize:"); Serial.println(_bufferSize, DEC); uint8_t *outBuf=NULL; size_t outLen = 0; ArduinoUZlib::decompress(_buffer, _bufferSize, outBuf, outLen); // GZIP decompression // Output the decrypted data to the console. Serial.write(outBuf,outLen); if(outBuf & amp; & amp; outLen){<!-- --> DynamicJsonDocument jsonBuffer(2048); deserializeJson(jsonBuffer, (char*)outBuf,outLen); JsonObject root = jsonBuffer.as<JsonObject>(); int i; for (i = 0; i < 3; i + + ) {<!-- --> String dateStr = root["daily"][i]["fxDate"]; data[i].dateStr = dateStr.substring(5, dateStr.length()); String tmp_min = root["daily"][i]["tempMin"]; data[i].tmp_min = tmp_min; String tmp_max = root["daily"][i]["tempMax"]; data[i].tmp_max = tmp_max; String cond_code = root["daily"][i]["iconDay"]; String meteConIcon = getMeteConIcon(cond_code); data[i].iconMeteCon = meteConIcon; } jsonBuffer.clear(); } else {<!-- --> int i; for (i = 0; i < 3; i + + ) {<!-- --> data[i].tmp_min = "-1"; data[i].tmp_max = "-1"; data[i].dateStr = "N/A"; data[i].iconMeteCon = ")"; } } //Be sure to remember to release memory if(outBuf != NULL) {<!-- --> free(outBuf); outBuf=NULL; } _bufferSize = 0; } } String HeFeng::getMeteConIcon(String cond_code) {<!-- --> //Get the weather icon. See https://dev.qweather.com/docs/start/icons/ if (cond_code == "100" || cond_code == "150" || cond_code == "9006") {<!-- -->//clear Sunny/Clear return "B"; } if (cond_code == "101") {<!-- -->//Cloudy Cloudy return "Y"; } if (cond_code == "102") {<!-- -->//Shaoyun Few Clouds return "N"; } if (cond_code == "103" || cond_code == "153") {<!-- -->//Partly Cloudy/ return "H"; } if (cond_code == "104" || cond_code == "154") {<!-- -->//Yin Overcast return "D"; } if (cond_code == "300" || cond_code == "301") {<!-- -->//Shower Rain 301-Heavy Shower Rain return "T"; } if (cond_code == "302" || cond_code == "303") {<!-- -->//302-Thundershower Thundershower / 303-Strong Thundershower return "P"; } if (cond_code == "304" || cond_code == "313" || cond_code == "404" || cond_code == "405" || cond_code == "406" ) {<!-- --> //304-Thundershowers with hail Freezing Rain //313-Freezing Rain Freezing Rain //404-Sleet Sleet //405-Rain And Snow Rain And Snow //406- Shower Snow return "X"; } if (cond_code == "305" || cond_code == "308" || cond_code == "309" || cond_code == "314" || cond_code == "399" ) {<!-- --> //305-小雨Light Rain //308-Extreme Rain Extreme Rain //309-Drizzle/Drizzle Drizzle Rain //314-Light to moderate rain Light to moderate rain //399-Rain Light to moderate rain return "Q"; } if (cond_code == "306" || cond_code == "307" || cond_code == "310" || cond_code == "311" || cond_code == "312" || cond_code == "315" || cond_code == "316" || cond_code == "317" || cond_code == "318") {<!-- --> //306-Moderate Rain Moderate Rain //307-Heavy Rain Heavy Rain //310-Heavy rainstorm //311-Heavy Storm Heavy Storm //312-Severe Storm //315-Moderate to heavy rain Moderate to heavy rain //316-Heavy rain to storm //317-Storm to heavy storm Storm to heavy storm //318-Heavy to severe storm Heavy to severe storm return "R"; } if (cond_code == "400" || cond_code == "408") {<!-- --> //400-Light Snow //408-Light to moderate snow Light to moderate snow return "U"; } if (cond_code == "401" || cond_code == "402" || cond_code == "403" || cond_code == "409" || cond_code == "410" ) {<!-- --> //401-Moderate Snow //402-Heavy Snow Heavy Snow //403-Blizzard Snowstorm //409-Moderate to heavy snow Moderate to heavy snow //410-Heavy snow to snowstorm return "W"; } if (cond_code == "407") {<!-- --> //407-Snow Flurry return "V"; } if (cond_code == "499" || cond_code == "901") {<!-- --> //499-Snow Snow //901-Cold Cold return "G"; } if (cond_code == "500") {<!-- --> //500-Mist Mist return "E"; } if (cond_code == "501" || cond_code == "509" || cond_code == "510" || cond_code == "514" || cond_code == "515" ) {<!-- --> //501-Foggy return "M"; } if (cond_code == "502" || cond_code == "511" || cond_code == "512" || cond_code == "513") {<!-- --> //502-Haze Haze return "L"; } if (cond_code == "503" || cond_code == "504" || cond_code == "507" || cond_code == "508") {<!-- --> //503-Sand return "F"; } if (cond_code == "999") {<!-- -->//Unknown return ")"; } if (cond_code == "213") {<!-- --> return "O"; } if (cond_code == "200" || cond_code == "201" || cond_code == "202" || cond_code == "203" || cond_code == "204" || cond_code == "205" || cond_code == "206" || cond_code == "207" || cond_code == "208" || cond_code == "209" || cond_code == "210" || cond_code == "211" || cond_code == "212") {<!-- --> return "S"; } return ")"; } </code><img class="look-more-preCode contentImg-no-view" src="//i2.wp.com/csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreBlack. png" alt="" title="">