2023年5月18日 星期四

利用 ESP8266 MicroPython 取得氣象網站的天氣開放資料

當設計程式進行Web應用或者是手機應用,若需要秀出天氣數據或者天氣預報數據時,不妨使用 OpenWeatherMap 天氣API服務。 OpenWeatherMap是OpenWeather Ltd擁有的在線服務,它通過API提供全球天氣數據,包括任何地理位置的當前天氣數據,天氣預報,天氣預報和歷史天氣數據。該公司提供了對任何位置的逐分鐘超局部降雨預報。 

 本實作使用WeMos D1 Mini ESP8266的無線WiWi模組連上網路,利用HTTP的GET方法進行資料請求,自氣象網站取回天氣資料,故須先取得氣象網站的程式開發API Key,請參考這裡

本實作使用 WeMos D1 Mini 開發板,以 WiFi 進行基地台連線並取得網站資料。直接將 WeMos D1 Mini 開發板以 USB 線連接到開發電腦進行程式編譯上傳即可。溫度的LED燈號接腳本例使用D1(GPIO5)、D2(GPIO4)、D3(GPIO0)作為點亮紅、黃、綠LED的正極腳位,腳位對應如下圖(來源: www.mischianti.org)。

 
OpenWeatherMap 提供當前天氣的地圖,一周預報,降水,風,雲,來自氣象站的其他數據。免費用戶就可以使用絕大部分功能。提供 JSON 、 XML ,、以及 HTML 等多種格式數據。本實作將利用取回的溫度資料進行顯示天氣資訊狀態識別,氣溫低於攝氏25度點亮綠色LED,氣溫介於攝氏25至34度點亮黃色LED,氣溫高於攝氏34度點亮紅色LED。

取得開發API Key後串接取得天氣資料的網址格式如下,詳細網址參數說明請參考這裡
http://api.openweathermap.org/data/2.5/weather?q=天氣地區&units=metric&lang=zh_tw&appid=開發金鑰
完整程式內容如下:
from machine import Pin
import network
import urequests, ujson

#設定燈號輸出接腳
ledR = Pin(5, Pin.OUT)
ledY = Pin(4, Pin.OUT)
ledG = Pin(0, Pin.OUT)
#網路天氣URI參數設定與組合
#API_key = "<API金鑰>"
area = "Taipei,TW"
url  = "https://api.openweathermap.org/data/2.5/weather?"
url += "q=" + area   # 城市與國別
url += "&units=metric&lang=zh_tw"   # 溫度單位、語言
url += "&appid=" + API_key

#設定網路連線帳號密碼
SSID = "<WiFi名稱>"        # WiFi名稱
PASSWORD = "<WiFi密碼>"    # WiFi密碼

#自訂無線基地台連線函式
def connect_wifi(ssid, passwd):
    sta = network.WLAN(network.STA_IF)
    sta.active(True)
    if not sta.isconnected():
       print("連線中... \n")
       sta.connect(ssid, passwd)
       while not sta.isconnected():
          pass
    print("連線成功... \n")
#進行網路連線
connect_wifi(SSID, PASSWORD)

#嘗試取回天氣資料並加以解析
try:
    response = urequests.get(url)
    data = ujson.loads(response.text) #轉換JSON格式資料成Python字典物件
except:
    data = None

if not data:
    print("沒有查詢到天氣資料")
else:    
    print("__________________________")
    weather = data["weather"][0]
    print("現在天氣: ", weather["description"])
    print("--------------------------")
    main = data["main"]
    temp = main["temp"]
    print("最高溫度: ", main["temp_max"])
    print("最低溫度: ", main["temp_min"])
    print("當前溫度: ", temp)
    print("當前壓力: ", main["pressure"])
    print("當前溼度: ", main["humidity"])
    print("__________________________")
    #依據溫度設定LED燈號
    if temp <= 25.0:
        print("綠燈")
        ledR.value(0)
        ledY.value(0)
        ledG.value(1)
    elif temp <= 34.0:
        print("黃燈")
        ledR.value(0)
        ledY.value(1)
        ledG.value(0)
    else:        
        print("紅燈")
        ledR.value(1)
        ledY.value(0)
        ledG.value(0)
提示:本例自OpenWeatherMap取回的JSON格式資料會利用ujson模組的loads()方法轉換為Python字典物件後再加以存取使用。