PaoyungJul 17, 2022
ℳ𝒾𝒸𝓇ℴ𝒫𝓎𝓉𝒽ℴ𝓃 隨手記Image Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
前陣子開始聽到有在擷取環保署空氣品質 AQI 資料的夥伴們在討論,說是資料只到 2022/05/30 就沒有再更新了[1],原因是環保署環境資料開放平臺已經更新 API 版本[2],新版 API 必需要申請 API Key,且要求使用 SSL 才能讀取,而在通訊需加密資料量又大增的情況下,有夥伴就好奇我使用一般 WROOM 版 ESP32 的 MicroPython,是如何在「陳大 ming.py ESP32 字量極限」中載入950個中文字的同時,還能連上環保署網站讀取資料?
其實並沒有什麼神奇秘訣,就只是「使用 API 前請詳閱公開說明書」。
首先先瞭解在 MicroPython 讀取 HTTP 資料最常使用的就是 urequests 模組,但它在處理資料時是把全部的內容整個傳了回來,優點是操作方便,缺點是資料內容一多記憶體就爆了[3],莫說還要做 JSON 格式轉換,除非將 urequest 改寫成能批次處理的版本,不然就必須調整讀取資料的內容量或格式。正巧新版 API 的JSON 格式就是資料量較大的這種情況(CSV格式則較小),而通常在環保署下載的資料並非全部都是需要的,所以只要使用正確的參數即可取得真正需要的部份。我們可以在環保署下載API參數說明手冊,閱讀後即可發現使用 filters 這個參數就能讓資料有效的縮減。(減少運算量和流量也是愛地球喔!)
Image Not Showing
Possible Reasons
|
---|
有了上面的參數說明,將程式修改如下即可。(filters 更多的用法請參閱說明手冊)
採用 JSON 格式 (程式碼簡明易操作)
import urequests
import network
def connectWifi():
# ....
# 請依需求自行撰寫
def getAQI(key, filters):
url = f'https://data.epa.gov.tw/api/v2/aqx_p_432?filters={filters}&api_key={key}&format=json'
r = urequests.get(url)
jObj = r.json()['records']
r.close()
return jObj
def demo():
# 請自行申請 api key,下面這組是無效的
key = '8x3x0xfx-axcx-4x9x-bx3x-4x6x0xexfx8x'
#filters = 'sitename,EQ,桃園'
filters = 'siteid,EQ,17'
data = getAQI(key, filters)[0]
# 欄位都是小寫的
print(f'縣市: {data["county"]}')
print(f'測站名稱: {data["sitename"]}')
print(f'AQI: {data["aqi"]}')
print(f'PM2.5: {data["pm2.5"]}')
# >>> connectWifi()
# Connect OK!
# >>> demo()
# 縣市: 桃園市
# 測站名稱: 桃園
# AQI: 33
# PM2.5: 10
# >>>
採用 CSV 格式 (需要做欄位對應)
import urequests
import network
def connectWifi():
# ....
# 請依需求自行撰寫
def getAQI_csv(key, filters):
url = f'https://data.epa.gov.tw/api/v2/aqx_p_432?filters={filters}&api_key={key}&format=csv'
r = urequests.get(url)
csv = r.text
r.close()
return csv
def demo_csv():
# 請自行申請 api key,下面這組是無效的
key = '8x3x0xfx-axcx-4x9x-bx3x-4x6x0xexfx8x'
#filters = 'sitename,EQ,桃園'
filters = 'siteid,EQ,17'
lines = getAQI_csv(key, filters).split('\n')
fields = lines[0].split(',')
row = lines[1].split(',')
data = {}
for idx in range(len(fields)):
data[fields[idx]] = row[idx]
# 欄位都是小寫的
print(f'縣市: {data["county"]}')
print(f'測站名稱: {data["sitename"]}')
print(f'AQI: {data["aqi"]}')
print(f'PM2.5: {data["pm2.5"]}')
# >>> connectWifi()
# Connect OK!
# >>> demo_csv()
# 縣市: 桃園市
# 測站名稱: 桃園
# AQI: 33
# PM2.5: 10
# >>>
JSON 未使用 filters | JSON 使用 filters | CSV 未使用 filters | CSV 使用 filters |
---|---|---|---|
約 66.6KB | 約 5.1KB | 約 10.1KB | 👑 約 300Bytes |
聰明的你該知道怎麼選了嗎? 請多多利用此參數讓原本跑不動的程式跑起來吧!
郵件通知API更新並重新註冊 👉會員註冊
ESP32 Wrover
可選用 ESP32 另外掛載 8MB PSRAM 的版本來解決記憶體不足的情況。 ↩︎