物聯網開發筆記 (八) 串中央氣象局 API
因為有幫家父的開心農場裝設監視器,平時人在台北時他就很常透過監視器看花花草草長得如何,由於家父說他希望偶爾也可以關掉系統自動控制,由人工遠端控制,所以打算來串一下中央氣象局的氣象預測資料,透過上一篇的 Line Notify 推送到他使用的 iOT 群組。
註冊會員索取授權碼
因為抓不到網站的 metadata,這邊用連結的方式提供氣象資料開放平臺。
這裡的社群登入選項真的很少,但我忘記在哪裡有看到一條文字寫著 facebook 登入使用者無法取得該資料(非全部資料都無法取得),所以我還是用帳號密碼登入。
新註冊的使用者,必須要先到信箱收驗證信,我自己用 gmail 等了好久才收到信
資料測試
有很多的項目可以選端看需求,因為我只要開心農場位置的天氣,所以我就選擇該縣市的API。
展開任何一個 API,內容都可以看到很詳細的參數,右上的 Try it out 可以直接在這上面操作 API,並回傳相關資訊在下方給你看。
Authorization
只要填入剛才申請的授權碼,這是必要的欄位,其餘欄位沒有給都會說明預設會給什麼。
非常建議參數必須要填寫自己需要的就好,因為資料太多回傳數度很慢。
回傳的資料就會顯示出來,如過這些資料是你需要的,就可以直接複製上方的 Request URL
,看是要在哪個語言中直接用 GET 取得資料即可。
Python 實作通知
因為我在其他的地方已經有實作通知天氣給家庭群組,所以這邊我只需要指定鄉鎮的天氣預報綜合描述(WeatherDescription)即可。
{
"startTime": "2023-05-25 06:00:00",
"endTime": "2023-05-25 09:00:00",
"elementValue": [{
"value": "短暫陣雨。降雨機率 30%。溫度攝氏20度。舒適。西北風 平均風速<= 1級(每秒1公尺)。相對濕度95%。",
"measures": "NA"
}]
}
我只需要拿到 value 值,但這個值在這個回傳的 json 內在很底層,而且時間是以 3 小時切割,所以會拿到很多的資料。
import requests
def GetData(): dict:
return requests.get('url').json()
data = GetData()
if (data['success'] == 'true):
pass
else:
pass
cityObject = data['records']['locations'][0]
locationName = cityObject['locationsName'] + cityObject['location'][0]['locationName'];
因為我只有單純的一個縣市 + 一個鄉鎮,所以直接取得就好
接下來比較複雜的地方是我們要的資料,因為被拆分為每三小時一個資料區區間,所以要先篩選一下資料,只要今天的資料,而且 0~6、21~0 的資料都因為在睡覺不需要。
# Python datetime 庫
from datetime import datetime
# 先取得 weatherElement
locationObject = cityObject['location'][0]['weatherElement']
# 取得今天日期
currentDay = datetime.datetime.now().day
# 暫存資料用
data = [];
for item in locationObject[0]['time']:
startTime = datetime.strptime(item['startTime'], '%Y-%m-%d %H:%M:%S')
# 不是今天就跳過
if startTime != currentDay:
continue
# 如果開始時間不是 21,0,3 這三個時間就加入暫存
if startTime not in [21, 0, 3]:
data.append(item)
# Print Data
for item in data:
startTime = datetime.strptime(item['startTime'], '%Y-%m-%d %H:%M:%S')
print(startTime.hour)
透過先篩選掉資料後,資料筆數減少不少,畢竟這個 API 會給你 36 小時內的資料。
後續就是針對資料進行排版美化,以及設定資料發送的時間,經過考量我最後是採用每天凌晨六點安排發送今日 06~18 的資料。
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.cron import CronTrigger
def func:
# 實作邏輯
pass
trigger = CronTrigger(hour=6)
jobId = 'notifyWeather'
scheduler = BackgroundScheduler()
scheduler.add_job(func, trigger, id=jobId)