基于Arduino和ESP8266的JSON数据获取与解压之和风天气
基于Arduino和ESP8266的JSON数据获取与解压之和风天气
摘要
- 简要比较了几个免费天气数据接口;介绍了通过HTTP和HTTPS获取数据,以及Gzip压缩格式数据的获取;解压Gzip格式数据的方法;介绍了获取网络数据时的注意事项,包括数据完整性、数据存储、内存分配、数据有效性检查。推荐了一个获取并解析和风天气数据的第三方库。
背景说明
-
起因:点灯科技气象数据接口暂停使用,寻找替代方案。
-
免费天气数据接口比较
操作实践
获取数据
-
通过 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
关注微信公众号,获取即时推送;点击左下角阅读原文,享受最佳阅读体验!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧