Webカメラで定期的に写真を撮って定期的に送ってくるLINEBotを作った
はじめに
Pythonで Raspberry Pi3 B+ に Webカメラ ( logicool C270) ) を接続して、定期的に写真を撮って送ってくれるLINEBotを作りました。
上記の機材があって、友達に「技術の無駄遣いしよ、なんか面白そうだからつくって」と言われたので実装しました。
「写真を撮って保存 → 保存した写真をライングループに送信」という流れをプログラムで実装し、それをRaspberry Pi で定期実行させています。
開発期間は半日ぐらい、LINEBotはかなり簡単でした。
目次
Step1 . webカメラの写真を撮る
fswebcam を使って撮影しました。
次の手順で写真が撮れます。
デバイスが接続されているか確認します。
lsusb
fswebcamのインスト―ル
sudo apt-get install fswebcam
とりあえず一回とってみる
fswebcam -p MJPEG image.jpg
optionもあるので参考に(man-fswebcam)
Pythonでは、subprosessモジュールを使うとコマンドの実行ができます。参考
import subprocess def get_picture(): cheese=['fswebcam','-p','MJPEG','-r','1280x1024','--no-banner','-D','1',image.jpg] try: subprocess.check_call(cheese) print ("Command finished.") except: return "Command envailed."
cheese変数にコマンドを入れて(スペース区切りでリストに代入)subprocess.check_call(cheese)
で実行しています。
fswebcam -p MJPEG -r 1280x1024 --no-banner -D 1 imgage.jpg
を実行しているのと同義です。
いくつかオプションがあります。
- -p MJPEG : フォーマットをmjpegで
- -r 1280×1024 : 画像サイズの指定
- -D 1 : 撮影時、1秒遅延させる。(写真撮影の安定性が上がります)
参考
Step2 . LINEグループに撮った画像を送信する
LINEグループへの送信はLINE Notify APIを使います。他のBotに比べてめちゃめちゃ簡単です。やってみたい人はLINEBotからやり始めるといいかも。
こちらのサイトの一番下にサービス提供者様へと書いているところがあるので、そこから登録できます。
登録後、グループ or 個人チャット に対するアクセストークンが発行できます。
pythonのrequestsモジュールを使って、画像とメッセージを投げることができます。
import requests def post(): headers = {"Authorization" : "Bearer "+ TOKEN} # ヘッダ payload = {"message" : MESSAGE} # メッセージ files = {"imageFile": open(image.jpg, "rb")} # 送信画像データ res = requests.post(url,headers=headers,params=payload,files=files)
Step1で撮った画像を、request.postで送信するだけです。
参考
Step3 . プログラムを定期実行させる
通常、上記のコードは、python3 hogehoge.py
のように実行しますが、これをcronを用いて定期実行します。
crontab -e
でcrontabを開き、定期実行したい時間や、プログラムを指定できます。
書き方については、参考記事を見て下さい。
今回は、1時間に一回・9時~20時・月~土を指定しました。
00 9-20 * * 1-5 python3 home/pi/PATH.../hogehoge.py
参考
- cron 設定ガイド
- 決まった時間に処理する)
- cronの使い方 http://www.raspberrypirulo.net/entry/2016/10/27/Cron%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9](http://www.raspberrypirulo.net/entry/2016/10/27/Cronの使い方)
Step4 . 細かなバグ修正など
Step3まででとりあえずプログラムは動きます。
しかし、「撮影 => 送信」のタイミングや、同じ画像名であったことから、結構不安定でした。
解決策
- 「撮影 => 送信」の間に30秒の遅延時間を入れました。(30秒もいらないかも)
from time import sleep ... sleep(30)
- 画像名を写真の撮影時刻に変えました。
次のように時刻を取得します。
import datetime def get_now_time(): d = datetime.datetime.today() return d.strftime("%Y-%m-%d %H:%M:%S")
- 画像名時刻にしたので、ちゃんと送信ができたら撮影した画像を削除します。
import os ... os.remove('./'+img_name)
動作
こんな感じです。研究室の写真を定期的にとって、研究室の学生がいるグループに送信しています。Webカメラの位置は自由なので中だけではなく、研究室からみえる外の景色等も撮れますね。
しっかり動きました。
LINE Botは、git repositoryを公開しているので参考に貼っておきます。
SlackBotでも同じようなことをしたのでこちらも是非。