最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

基于Arduino和ESP8266的JSON数据获取与解压之和风天气-全球快讯

来源:博客园

基于Arduino和ESP8266的JSON数据获取与解压之和风天气

摘要

  • 简要比较了几个免费天气数据接口;介绍了通过HTTP和HTTPS获取数据,以及Gzip压缩格式数据的获取;解压Gzip格式数据的方法;介绍了获取网络数据时的注意事项,包括数据完整性、数据存储、内存分配、数据有效性检查。推荐了一个获取并解析和风天气数据的第三方库。

背景说明

  • 起因:点灯科技气象数据接口暂停使用,寻找替代方案。

  • 免费天气数据接口比较


    (资料图片)

    数据来源网络协议内容编码数据格式接口限制更新频率
    点灯科技HTTPSNoneJSON30次/天2小时
    和风天气HTTPSGzipJSON1000次/天10分钟
    高德天气HTTPSNoneJSON300000/天多次/时

操作实践

获取数据

  • 通过 HTTP 获取数据

    HTTPClient httpclient;WiFiClient wificlient;if(httpclient.begin(wificlient, URL)){    httpCode = httpclient.GET();    if(httpCode == HTTP_CODE_OK)         String payload = httpclient.getString();    else        Serial.printf("[HTTP] GET... failed, error: %s\n", httpclient.errorToString(httpCode).c_str());    httpclient.end();}
  • 通过 HTTPS 获取数据

    HTTPClient httpsclient;BearSSL::WiFiClientSecure wificlient;wificlient.setInsecure();if(httpsclient.begin(wificlient, URL)){    httpCode = httpsclient.GET();    if(httpCode == HTTP_CODE_OK)         String payload = httpsclient.getString();    else        Serial.printf("[HTTP] GET... failed, error: %s\n", httpsclient.errorToString(httpCode).c_str());    httpsclient.end();}
  • 通过 HTTPS 获取压缩格式数据

    HTTPClient httpsclient;BearSSL::WiFiClientSecure wificlient;wificlient.setInsecure();if(httpsclient.begin(wificlient, URL)){    httpCode = httpsclient.GET();          if(httpCode == HTTP_CODE_OK)     {        content_len = httpsclient.getSize(); // get length of document (is -1 when Server sends no Content-Length header)        content_encoding = httpsclient.header("content-encoding");        if((httpsclient.hasHeader("content-encoding")) && (content_encoding.equals("gzip")))         {            while((httpsclient.connected()) && ((content_len > 0) || (content_len == -1)))             {                available_size = wificlient.available(); // !返回值最大只有245.                if(available_size)                 {                    realsize = (available_size > payload_buffer_size) ? payload_buffer_size : available_size;                    readBytesSize = wificlient.readBytes(payload_buffer+offset, realsize);                     offset += readBytesSize;                    if(content_len > 0)                        content_len -= readBytesSize;                }            }            *payload_size = offset;      }    }}

解压数据

  • 采用tignioj/ArduinoZlib库对gzip格式的数据进行解压。ArduinoZlib封装了zlib库的解压缩功能。

  • zlib库支持对gzip和Zip格式的数据进行解压和压缩。

注意事项

  • 数据完整性:函数wificlient.available()返回的等待读取的数据字节数似乎有限制(245),需要多次读取才能获得完整的数据,因此应增加数据完整性检查。

  • 数据存储:在进行 HTTP/HTTPS 访问时使用大数组会导致网络访问出错,使用malloc()手动分配堆可以解决这个问题。

  • 内存分配:使用malloc()分配堆时需要切换内存管理方案为16KB cache + 48KB IRAM and 2nd Heap (shared),此时才支持标准的malloc()API。具体信息可参见调整ICACHE与IRAM的比率。

  • 数据检查:返回的天气数据不一定是正确的,可以使用String.indexOf()查找返回的字符串数据中是否有指定的关键字。

  • 和风天气:返回的数据已强制使用gzip压缩,在请求头中添加&gzip=n的方法已失效。如果仅使用和风天气的数据接口,可使用tignioj/ESP8266_Heweather库提供的接口来获取和风天气提供的天气数据。

参考资料

  • String() - Arduino Reference
  • Welcome! — ESP8266 Arduino documentation
  • ESP8266-Arduino库 开发参考资料 – 太极创客

版权声明:本文为「梦幻之心星」原创,依据 CC BY-NC-SA 4.0 许可证进行授权,转载请附上原文出处链接及本声明。

博客园地址:https://www.cnblogs.com/Sky-seeker

关注微信公众号,获取即时推送;点击左下角阅读原文,享受最佳阅读体验!

关键词: