本人小白,第一次写这个,有什么不满的,请您见谅。
基于esp32通过和风天气获得天气数据,由于和风天气对Web API v7中强制使用Gzip压缩,不再支持返回未经压缩的数据。我们需要对gzip数据进行解析。
和风公告连接:
需要到github 上下载这个库,记得改名字
记得改自己的WiFi和api key 。 location看这里
git clone https://github.com/qwd/LocationList.githttps://dev.qweather.com/docs/resource/location-list/
wm.addAP("xx", "xx");
wm.addAP("xx", "xx");
const char *url = "https://devapi.qweather.com/v7/weather/now?lang=en&location=101010100&key=your_key";
上代码(arduinoZlib库示例改写)
#include <Arduino.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#define USE_SERIAL Serial
WiFiMulti wm;
String payload = "";
#include "ArduinoZlib.h"
const char *url = "https://devapi.qweather.com/v7/weather/now?lang=en&location=101010100&key=your_key";
DynamicJsonDocument doc(1024);
void error(String msg) {
USE_SERIAL.print("!!!ERROR:");
USE_SERIAL.println(msg);
}
// 此变量占用内存过大,请勿放入loop()中
// uint8_t outbuf[10240] = { 0 };
uint8_t *outbuf;
void httpRequest() {
// wait for WiFi connection
if ((wm.run() == WL_CONNECTED)) {
delay(3000);
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
// configure server and url
// http.begin("http://192.168.2.144:8082/test");
http.begin(url);
// 接受Gzip
http.addHeader("Accept-Encoding", "gzip");
USE_SERIAL.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
USE_SERIAL.println(httpCode);
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK) {
USE_SERIAL.println("Code Ok");
// get lenght of document (is -1 when Server sends no Content-Length header)
int len = http.getSize();
USE_SERIAL.printf("len=%d\n", len);
// create buffer for read
uint8_t buff[4096] = { 0 };
// get tcp stream
WiFiClient *stream = http.getStreamPtr();
USE_SERIAL.println("stream Ok");
// read all data from server
while (http.connected() && (len > 0 || len == -1)) {
// get available data size
size_t size = stream->available(); // 还剩下多少数据没有读完?
// USE_SERIAL.print("avail size=");
USE_SERIAL.println(size);
if (size) {
// read up to 128 byte
size_t realsize = ((size > sizeof(buff)) ? sizeof(buff) : size);
// USE_SERIAL.println(realsize);
size_t readBytesSize = stream->readBytes(buff, realsize);
// write it to USE_SERIAL
// USE_SERIAL.write(buff,readBytesSize);
if (len > 0) {
len -= readBytesSize;
}
outbuf = (uint8_t *)malloc(sizeof(uint8_t) * 20480);
uint32_t outprintsize = 0;
int result = ArduinoZlib::libmpq__decompress_zlib(buff, readBytesSize, outbuf, 20480, outprintsize);
USE_SERIAL.write(outbuf, outprintsize);
USE_SERIAL.println(' ');
for (int i = 0; i < outprintsize; i++) {
payload += (char)outbuf[i];
}
free(outbuf);
} else {
USE_SERIAL.println("no avali size");
}
delay(1);
}
USE_SERIAL.println();
USE_SERIAL.print("[HTTP] connection closed or file end.\n");
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
}
delay(3000);
}
void getWeather(String payload) {
deserializeJson(doc, payload);
JsonObject now = doc["now"];
String _response_code = doc["code"].as<String>(); // API状态码
USE_SERIAL.println(_response_code);
String _last_update_str = doc["updateTime"].as<String>(); // 当前API最近更新时间
USE_SERIAL.println(_last_update_str);
int _now_temp_int = now["temp"].as<int>(); // 实况温度
USE_SERIAL.println(_now_temp_int);
int _now_feelsLike_int = now["feelsLike"].as<int>(); // 实况体感温度
USE_SERIAL.println(_now_feelsLike_int);
int _now_icon_int = now["icon"].as<int>(); // 当前天气状况和图标的代码
USE_SERIAL.println(_now_icon_int);
String _now_text_str = now["text"].as<String>(); // 实况天气状况的文字描述
USE_SERIAL.println(_now_text_str);
String _now_windDir_str = now["windDir"].as<String>(); // 实况风向
USE_SERIAL.println(_now_windDir_str);
int _now_windScale_int = now["windScale"].as<int>(); // 实况风力等级
USE_SERIAL.println(_now_windScale_int);
float _now_humidity_float = now["humidity"].as<float>(); // 实况相对湿度百分比数值
USE_SERIAL.println(_now_humidity_float);
float _now_precip_float = now["precip"].as<float>(); // 实况降水量,毫米
USE_SERIAL.println(_now_precip_float);
}
void setup() {
USE_SERIAL.begin(115200);
USE_SERIAL.println();
USE_SERIAL.println();
USE_SERIAL.println();
for (uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
wm.addAP("xx", "xx");
wm.addAP("xx", "xx");
httpRequest();
}
void loop() {
getWeather(payload);
delay(5000);
}
outbuf[]存的是ascll码,需要转类型
for (int i = 0; i < outprintsize; i++) {
payload += (char)outbuf[i];
}