きっかけ
昨日の天気予報では、雨ではなかったのに、当日、雨予報に変わっている時、傘を忘れてしまう。
残念ながら私のキャンパスは駅から離れたど田舎キャンパスであるため、雨の日傘が無いと必然的に死んでしまう。
→さてどうしよう
→翌日の天気を通知してくれるアプリも無いことはない。
→だが、Android側のタスクキラーで弾かれたり、細かい設定がいじれない。
→なら自分でつくろう AWSのLambda使ってみたいし
みなさんでも無料で構築可能です。是非挑戦してみてください。
###こんな感じで実装
お天気情報取得からLineに通知
なんと先人がここまで実装してくださってました。
きれいなコードで見やすい。とてもありがたい。
Pythonで天気予報をLINE通知する
LineNotifyに登録
LineNotifyのAPIキーを取得します。
普段のLineアカウントで即登録できるのでとても早く取得できて驚き。
どうやらこれ自分以外にも送れそうなので、もしかしてめちゃくちゃ何かに使えるAPIなのでは・・・?(語彙力)
Lambdaを構築
AWSに登録していない人はまず登録しましょう。
Amazon Web Service
[注]色々説明が入りますが、私自身、AWS初心者のため認識が間違っている場合があります。
AWSは基本は従量課金制ですが、Lambdaは個人使用ではなかなか消費できない量(一分間に何回も出来るレベル)の無料枠があるので、おそらく無料で出来ます!
###■まずLambda関数を登録しましょう
エラーが出てますが、撮り忘れの写真をもう一度再現しただけなので、特に関係ありません。
終わったあとに気が付きましたが、ウェザーの綴りは「Weather」らしいです。。。
登録するとこういった画面が出てきます。
この画面の意味は、Whether_To_LineNotifyというLambda関数が存在して、Amazon CloudWatch Logsという機能が、そいつのログを監視しているよ~みたいな感じ(だと思います。)
その下にはこのようなエディタがあります。
画像右上のハンドラと書かれているのが、Lambdaが実行する関数です。
つまり、Lambda_functionのLambda_handler()を実行する。ということです。
AWSはなんとCLIからちょこまか操作せずに、ブラウザ上でサクサク開発出来るんですね。。。驚きです。(もちろんCLIからもデプロイ出来ます)
###■スクリプトを作成
上記のお天気情報をLineに通知するソースを少し編集しました。 (Pythonで天気予報をLINE通知する)
GitHub https://github.com/Yougurut/WhetherToLineNotify
Line Notify API Keyは環境変数を使ってるので、柔軟に書き直してください。
CITY_CODEをいじれば全国各地の天気予報が取得可能です。
import otenki
def lambda_handler(event, context):
# TODO implement
otenki.OtenkiNotify()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import sys
import urllib.parse
import urllib.request
import datetime
import os
# weather's API
WEATHER_URL="http://weather.livedoor.com/forecast/webservice/json/v1?city=%s"
CITY_CODE="130010" # TOKYO
# LINE notify's API
LINE_TOKEN= os.environ.get("LINE_NOTIFY_API_KEY")
LINE_NOTIFY_URL="https://notify-api.line.me/api/notify"
def get_weather_info():
try:
url = WEATHER_URL % CITY_CODE
html = urllib.request.urlopen(url)
html_json = json.loads(html.read().decode('utf-8'))
except Exception as e:
print ("Exception Error: ", e)
sys.exit(1)
return html_json
def set_weather_info(weather_json, day):
min_temperature = None
max_temperature = None
try:
weather = weather_json['forecasts'][day]['telop']
max_temperature = weather_json['forecasts'][day]['temperature']['max']['celsius']
min_temperature = weather_json['forecasts'][day]['temperature']['min']['celsius']
except TypeError:
# temperature data is None etc...
pass
msg = "\n天気: %s\n最低気温: %s\n最高気温: %s" % \
(weather, min_temperature, max_temperature)
return msg
def send_weather_info(msg):
method = "POST"
headers = {"Authorization": "Bearer %s" % LINE_TOKEN}
payload = {"message": msg}
try:
payload = urllib.parse.urlencode(payload).encode("utf-8")
req = urllib.request.Request(
url=LINE_NOTIFY_URL, data=payload, method=method, headers=headers)
urllib.request.urlopen(req)
except Exception as e:
print ("Exception Error: ", e)
sys.exit(1)
def OtenkiNotify():
weather_json = get_weather_info()
now = datetime.datetime.now() + datetime.timedelta(hours=9) ## GMT+9:00
weekday = now.weekday()
yobi = ["月", "火", "水", "木", "金", "土", "日"]
msg_header = "\n本日" + str(now.date()) +"(" + yobi[weekday] + ")"
msg = set_weather_info(weather_json, 0)
print (msg_header + msg)
send_weather_info(msg_header + msg)
if("雨" in weather_json['forecasts'][0]['telop']):
send_weather_info(msg_header+"\n☔☔☔☔☔☔☔☔\n今日は雨が降ります。\n傘を忘れずに!\n☔☔☔☔☔☔☔☔")
(Pythonで天気予報をLINE通知する)
との変更点は
・時間をawsのシステムと合わせる
・曜日を追加
・日本語に
・雨の日は追加で傘を持っていくように通知
といった内容です。
この2つのコードをrootに追加したあとに、上部のバーの保存ボタンを押したあとにテストしてみてください。最初保存ボタンを押して無くて10分ぐらい格闘してました
これで自分のLineアカウントに今日のお天気の通知が行けばOKです。
###■トリガー(予定)を登録。
先程のせたDesignerにCloudWatch Eventsというトリガーを追加します。
CloudWatch Eventsというトリガーはどの時間・間隔でLambda関数を走らせるのか?というものです。
スケジュール式はcron(0 21 * * ? *)となっていますが、これは毎日UTC21:00(日本時間の朝6:00)にLambda関数を走らせるという意味です。
#結果
ちゃんと朝6:00に天気予報のLine通知が来ました。
これで雨の日に傘を忘れることが無くなる。。。はず!!!
AWS初心者でも2時間ほどで実装できたので、雨の日の傘で困っている方は是非挑戦してください!!