ゴミ出しの前日にLINEでアラートを出す【Python3】
私の自治体ではペットボトルや瓶・カンなどの回収は2週に1回しかないので出し忘れると大変です。あの悔しい思いを繰り返すのが嫌なので通知プログラムを作ることにしました。つまり設定した日程(例えば第1、第3金曜日とか)の前日にアラートを送ることにします。これはもちろんゴミ出し以外のスケジュールにも転用可能です。pythonのdatetimeとかを使えばスケジュールは作れそうです。通知はスマートフォンやスマートウォッチで確認できるLINEに送るのが良いでしょう。pythonを定期実行する方法としてはwindowsですとタスクスケジューラが使えますが、ラズパイユーザーの私はcrontabを(初めて)利用してみようと思います。
LINE Notifyの設定
LINE Notifyに接続し、マイページ➡アクセストークンの発行と進みます。
notify-bot.line.me
この時トークン名を「ゴミ出し」とし、通知を送信するグループ(あらかじめ作成しておくと良い)を選択します。
Pythonでライン送信
次のプログラムを実行すればLINEが送信できます。tokenには先ほど発行したトークンを入力してください。こちらのコードを参考にしました。
import requests def send_line(text): url ='https://notify-api.line.me/api/notify' token = "トークンを張り付け" headers ={'Authorization' : 'Bearer ' + token} message = text payload = {'message' : message} p = requests.post(url, headers=headers, data=payload) print(p) text="てすてすてす" send_line(text)
無事ラインが届きました。
Pythonでゴミ出しカレンダーを作成
まず明日の日付が何回目の何曜日なのかを判断します。こちらの記事の関数に1日分のタイムデルタを加算しただけです。結果には(第n週、X曜日)というタプルが返されます。
import calendar import datetime def get_nth_week(day): return (day - 1) // 7 + 1 def get_nth_dow(year, month, day): return get_nth_week(day), calendar.weekday(year, month, day) today = datetime.datetime.now() #現在日時取得 tomorrow = today + datetime.timedelta(days=1) #現在日時に+1日のタイムデルタを加算 tom_nth_dow = get_nth_dow(tomorrow.year, tomorrow.month, tomorrow.day) #明日の(第n週、X曜日)を取得 print("today:", today) print("tomorrow:", tomorrow) print("tom_nth_dow:", tom_nth_dow)
結果
today: 2020-04-30 21:21:00.556439 tomorrow: 2020-05-01 21:21:00.556439 tom_nth_dow: (1, 4)
となります。ここで出力された(1,4)は第1回目の金曜日であることを表します。
次にゴミ出しのカレンダーを作成します。pandasのDataFrameを利用しました。列方向は曜日で行方向はその月で何回目かを表しています。
import pandas as pd schedule=pd.DataFrame([ ["Mon" ,"Tue" ,"Wed" ,"Thurs" ,"Fri" ,"Sat", "Sun"], ["" ,"プラスチック" ,"" ,"" ,"ビン・カン","" ,"" ], ["" ,"" ,"金物" ,"" ,"" ,"" ,"" ], ["" ,"プラスチック" ,"" ,"" ,"ビン・カン","" ,"" ], ["" ,"" ,"金物" ,"" ,"" ,"" ,"" ], ["" ,"" ,"" ,"" ,"" ,"" ,"" ], ]) print(schedule)
結果
最後に上の二つを組み合わせます。pandas DataFrameの.iatを使ってデータフレームの中の該当インデックスの値を取り出します。
date_jp = ['月','火','水','木','金',"土",'日'] date_check = schedule.iat[tom_nth_dow] print("明日は第"+str(tom_nth_dow[0])+date_jp[tom_nth_dow[1]]+"曜日") print(date_check+"回収の日です")
結果
明日は第1金曜日 ビン・カン回収の日です
tom_nth_dowには(1,4)、すなわち第1金曜日が入っていましたので、sheduleより"ビン・カン"が取り出されました。
ゴミ出しLINE通知プログラム
python3でLine送信とゴミ出しカレンダーを作ることが出来ましたので、あとは単純にこれを組み合わせて通知プログラムを作成します。
import calendar import datetime import pandas as pd import requests def get_nth_week(day): return (day - 1) // 7 + 1 def get_nth_dow(year, month, day): return get_nth_week(day), calendar.weekday(year, month, day) def send_line(text): url ='https://notify-api.line.me/api/notify' token = "Line notifyトークンを張り付け" headers ={'Authorization' : 'Bearer ' + token} message = text payload = {'message' : message} p = requests.post(url, headers=headers, data=payload) print(p) schedule=pd.DataFrame([ ["Mon" ,"Tue" ,"Wed" ,"Thurs" ,"Fri" ,"Sat", "Sun"], ["" ,"プラスチック" ,"" ,"" ,"ビン・カン","" ,"" ], ["" ,"" ,"金物" ,"" ,"" ,"" ,"" ], ["" ,"プラスチック" ,"" ,"" ,"ビン・カン","" ,"" ], ["" ,"" ,"金物" ,"" ,"" ,"" ,"" ], ["" ,"" ,"" ,"" ,"" ,"" ,"" ], ]) date_jp = ['月','火','水','木','金',"土",'日'] today = datetime.datetime.now() tomorrow = today + datetime.timedelta(days=1) tom_nth_dow = get_nth_dow(tomorrow.year, tomorrow.month, tomorrow.day) date_check = schedule.iat[tom_nth_dow] text1 = "第"+str(tom_nth_dow[0])+date_jp[tom_nth_dow[1]]+"曜日" text2 = "明日は"+date_check+"収集の日("+text1+")です。" if date_check =="": print("明日のゴミ出しは有りません") else: send_line(text2)
結果
明日はビン・カン収集の日(第1金曜日)です。
結果として翌日である5/1金曜がビン・カン回収の日であることがラインで送信されました。該当の回収がない場合は何も起こりません。これでプログラムは完成しましたので、後は定期実行の設定となります。windowsのタスクスケジューラなどでも可能ですが、本記事ではRaspberry Piでcrontabを利用したいと思います。
crontabを使った連続実行
LXTeminalでcrontabを編集できます。
crontab -e
末尾に次のように書き加えます。
00 20 * * * sudo python3 /home/pi/<プログラム名>.py
これは毎日20時00分に指定のコマンドを実行することを示しています。
ctrl+Xでcrontabを閉じれば作業は終了です。コードに何らかの不備があるとcrontabは何もアクションしませんので、次の設定で毎分実行などにしてみて動作確認ができてから、所望の時間に設定すると良いと思います。
*/1 * * * * sudo python3 /home/pi/<プログラム名>.py
狙い通りのラインが20時に送られてきました!