【Python×Make】天気予報をLINEへ自動配信
先日、以下の記事を書きました。
この件について奥さんにしゃべったところ、以下の条件でLINEへメッセージを送れないか?というご要望をいただきました。
1. 以下のいずれかの条件を満たす場合にLINEへ配信してほしい
・当日に雨が降る場合(傘を忘れないようにしたいから)
・当日に30℃を超える場合 (暑いから外出の予定を変えるから)
2.以下の項目をLINEに配信してほしい
・当日の天気の概要
・「最高気温」「最低気温」「降水量」
3. 朝7:30に配信してほしい
実現方式の検討
前回はMakeのみでシステムを構築したのですが、今回は独自ロジックも多く含まれそうなのとこれからも改修の要望がありそうなのでPythonとMakeを組み合わせます。
こんな感じ実装を進めます。
・Makeのスケジュール実行機能をトリガーとしてPythonが動いてるサーバへアクセス
・サーバ内にてOpenWeather APIを含む処理を実行し、実行結果をMakeへ連携
・実行結果をMake内で加工してLINEへ配信
※上記から登録すると、今なら1ヶ月間無料でProプランを利用できます。お試しにはちょうど良いかと思います。また、課金登録をしない限り、料金が請求されることはありませんのでご安心ください。
サーバ側の実装
まずはサーバ側のPythonコードについて解説します。エンドポイントは以下となります。(一部hogehogeにマスキングしてます。)
HTTP通信のパラメータに含まれる「lat」(緯度を表す)、「lon」(経度を表す)をエンドポイント層に渡します。
from flask import Flask, jsonify, request
from logic.deliver_wheather_for_line_logic import deliver_wheather_for_line_logic
#エンドポイント層
@app.route('/hogehoge', methods=['POST'])
def deliver_wheather_for_line():
data = request.get_json()
lat = data.get('lat')
lon = data.get('lon')
weather_report = deliver_wheather_for_line_logic(lat,lon)
return weather_report
ロジック層ではAPI続層から受け取った天気予報の情報を使って、「最高気温が30℃以上か?」または「天気が雨か?」を判定します。いずれかの判定がTrueの場合は天気の情報をエンドポイント層へ返却します。
from flask import jsonify
from api.openweather_api import conn_openweather_onecall
#ロジック層
def deliver_wheather_for_line_logic(lat,lon):
weather_data = conn_openweather_onecall(lat,lon)
weather_data_json = weather_data.json()
max_temperature = weather_data_json['daily'][0]['temp']['max']
weather_today_id = weather_data_json['daily'][0]['weather'][0]['id']
judge_flg_temperature = judge_temperature(max_temperature)
judge_flg_weather_today = judge_weather_today(weather_today_id)
if judge_flg_temperature or judge_flg_weather_today:
return weather_data_json['daily'][0]
else:
return jsonify({})
# 最高気温が30℃以上かを判定する
def judge_temperature(temperature):
if temperature >= 30:
return True
else:
return False
# 返却される天気のコード値から雨か否かを判定する
def judge_weather_today(weather_today_id):
first_digit = int(str(weather_today_id)[0])
if first_digit in [2,3,5,6]:
return True
else:
return False
APIアクセス層は以下となります。細かいパラメータの説明は割愛します。
import requests
from utils.api_error_handlers import handle_request_errors
from config import Config
#APIアクセス層
@handle_request_errors
def conn_openweather_onecall(lat, lon):
url = (f"{Config.OPENWEATHER_ONECALL_URL}?"
f"lat={lat}&"
f"lon={lon}&"
f"exclude={Config.OPENWEATHER_EXCLUDE_MODE}&"
f"units={Config.OPENWEATHER_UNITS}&"
f"lang={Config.OPENWEATHER_LANG}&"
f"appid={Config.OPENWEATHER_API_KEY}")
response = requests.get(url)
return response
Make側の実装
Make側のモジュールは以下のように配置します。左側のHTTPモジュールでサーバへアクセスし、真ん中のJSONモジュールでJSON形式のデータに整えます。最後に右側のLINEモジュールでメッセージを配信します。
各モジュールの設定値について解説していきます。
HTTPモジュール
一部マスキングしてますが、こんな感じです。エンドポイント層のIFと合わせるために、「lat」(緯度を表す)、「lon」(経度を表す)をパラメータとして定義してます。
JSONモジュール
JSONファイルはデータの型を定義する必要があるのでAppendixにあるサンプルデータを貼り付けて型の自動生成をしてください。
LINEモジュール
LINEモジュールは以下のようにパラメータをセットします。ここは自分好みにセットしていただいて問題ないです。
また、LINEモジュールの詳しい設定方法は以下の記事を参照してください。
以上です。それでは動作確認をしてみましょう。
動作確認
左下の「Run once」ボタンを押して実行してみましょう。
こんな感じで配信されてきました。
スケジュールは「Run once」ボタン付近にあるスケジュールを7:30にセットしておけばOKです。
今回は以上です。
Appendix
OpenWeather API(One Call API 3.0)の返り値サンプル
⭐️参考⭐️
https://openweathermap.org/api/one-call-3
{
“dt”:1684951200,
“sunrise”:1684926645,
“sunset”:1684977332,
“moonrise”:1684941060,
“moonset”:1684905480,
“moon_phase”:0.16,
“summary”:”Expect a day of partly cloudy with rain”,
“temp”:{
“day”:299.03,
“min”:290.69,
“max”:300.35,
“night”:291.45,
“eve”:297.51,
“morn”:292.55
},
“feels_like”:{
“day”:299.21,
“night”:291.37,
“eve”:297.86,
“morn”:292.87
},
“pressure”:1016,
“humidity”:59,
“dew_point”:290.48,
“wind_speed”:3.98,
“wind_deg”:76,
“wind_gust”:8.92,
“weather”:[
{
“id”:500,
“main”:”Rain”,
“description”:”light rain”,
“icon”:”10d”
}
],
“clouds”:92,
“pop”:0.47,
“rain”:0.15,
“uvi”:9.23
}