Webカメラで定期的に写真を撮って定期的に送ってくるLINEBotを作った

はじめに

Pythonで Raspberry Pi3 B+ に Webカメラ ( logicool C270) ) を接続して、定期的に写真を撮って送ってくれるLINEBotを作りました。

上記の機材があって、友達に「技術の無駄遣いしよ、なんか面白そうだからつくって」と言われたので実装しました。

「写真を撮って保存 → 保存した写真をライングループに送信」という流れをプログラムで実装し、それをRaspberry Pi で定期実行させています。

開発期間は半日ぐらい、LINEBotはかなり簡単でした。

目次

Step1 . webカメラの写真を撮る

fswebcam を使って撮影しました。

次の手順で写真が撮れます。

  1. バイスが接続されているか確認します。

    lsusb

  2. fswebcamのインスト―ル

    sudo apt-get install fswebcam

  3. とりあえず一回とってみる

    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

参考

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カメラの位置は自由なので中だけではなく、研究室からみえる外の景色等も撮れますね。

f:id:sho0126hiro:20190616175509j:plain:w300

しっかり動きました。

LINE Botは、git repositoryを公開しているので参考に貼っておきます。

github.com

SlackBotでも同じようなことをしたのでこちらも是非。

sho0126hiro.hatenablog.com