基于Arduino和ESP8266的JSON數據獲取與解壓之和風天氣
基于Arduino和ESP8266的JSON數據獲取與解壓之和風天氣
摘要
- 簡要比較了幾個免費天氣數據接口;介紹了通過HTTP和HTTPS獲取數據,以及Gzip壓縮格式數據的獲取;解壓Gzip格式數據的方法;介紹了獲取網絡數據時的注意事項,包括數據完整性、數據存儲、內存分配、數據有效性檢查。推薦了一個獲取并解析和風天氣數據的第三方庫。
背景說明
-
起因:點燈科技氣象數據接口暫停使用,尋找替代方案。
-
免費天氣數據接口比較
數據來源 網絡協議 內容編碼 數據格式 接口限制 更新頻率 點燈科技 HTTPS None JSON 30次/天 2小時 和風天氣 HTTPS Gzip JSON 1000次/天 10分鐘 高德天氣 HTTPS None JSON 300000/天 多次/時
操作實踐
獲取數據
-
通過 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 許可證進行授權,轉載請附上原文出處鏈接及本聲明。
博客園地址:http://www.rzrgm.cn/Sky-seeker
關注微信公眾號,獲取即時推送;點擊左下角閱讀原文,享受最佳閱讀體驗!
![]()

浙公網安備 33010602011771號