arduino esp32 和风天气api gzip数据解析

本人小白,第一次写这个,有什么不满的,请您见谅。

基于esp32通过和风天气获得天气数据,由于和风天气对Web API v7中强制使用Gzip压缩,不再支持返回未经压缩的数据。我们需要对gzip数据进行解析。

和风公告连接:

https://blog.qweather.com/announce/gzip-is-required-in-apiicon-default.png?t=N7T8https://blog.qweather.com/announce/gzip-is-required-in-api

需要到github 上下载这个库,记得改名字

GitHub - tignioj/ArduinoZlib: zlib库移植到Arduino,用于解压服务端传输的gzip文件。icon-default.png?t=N7T8https://github.com/tignioj/ArduinoZlib

 记得改自己的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];
            }

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值