Try   HackMD

MicroPython 空氣品質 AQI 獲取之方式

PaoyungJul 17, 2022

ℳ𝒾𝒸𝓇ℴ𝒫𝓎𝓉𝒽ℴ𝓃 隨手記

前言

前陣子開始聽到有在擷取環保署空氣品質 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
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

範例

有了上面的參數說明,將程式修改如下即可。(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

聰明的你該知道怎麼選了嗎? 請多多利用此參數讓原本跑不動的程式跑起來吧!

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

關於作者  

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

我是 𝙋𝙖𝙤𝙮𝙪𝙣𝙜,是 MicroPythonEspruino 的愛好者,一直認為:

「Maker 應該把重心放在應用上,而不該被語言工具限制了創意」

所以想藉由較為簡捷且詳細的解說讓更多人可以學習進而自由發揮,而非淪為只能將程式碼複製貼上的複製人,如果你認同這樣的理念,請一起為此目標努力,如果我的文章內容對你有幫助,請轉發或協助需要的人。

若有專案需求,請利用 連絡我,謝謝!


  1. 舊的AQI網址
    http://opendata2.epa.gov.tw/AQI.json ↩︎

  2. 郵件通知API更新並重新註冊 👉會員註冊

    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
    ↩︎

  3. ESP32 Wrover
    可選用 ESP32 另外掛載 8MB PSRAM 的版本來解決記憶體不足的情況。 ↩︎