さて、Raspberry Pi 2も常時稼働する様になったことだし、監視カメラサーバーでも構築してみよう。カメラモジュールを買うと高いので激安のLogicool C270を買う。まあ、使い道が無くなっても再利用できるしね。
さて、Logicool C270を適当なところに設置(自分が普段座る場所が画角に入ると自宅にいるだけで検知されるので、自分が映らない方向に設置)して、USBでRaspberry Pi 2に繋ぐ。
lsusb
ちゃんと繋がっていてシステムに認識されていることを確認しよう。次に監視カメラの定番ソフトウェアであるmotionをインストールする。
sudo apt-get install motion
いろいろどっちゃりインストールされる。インストールが済んだら設定ファイルを弄る。今回は単一のカメラしか使わないので、/etc/motion/motion.confを直接弄ればオッケー。複数繋ぐ場合は設定をカメラごとに別ファイルに書くらしい。
daemon off (テスト時はとりあえずoff)
width 1280 (C270だと1280×720で問題なく動く)
height 720
output_pictures off (とりあえず画像ファイルを吐かないように)
ffmpeg_output_movies off (同じく動画ファイルを吐かないように)
target_dir /mnt/storage/motion (吐き出す時は外部のUSBメモリに吐く様にする)
stream_port 8080 (デフォルトは8081だけどちょっと気持ち悪いので)
stream_localhost off (motionが外部向けのストリームサーバーとして動くように)
stream_auth_method 2 (一応、MD5でパスワード認証)
stream_authentication user:pass (認証用のユーザー名とパスワード)
webcontrol_port 0 (このポートに接続すると設定をウェブベースで弄れるんだけどいらないので無効に)
とりあえず、監視はするけど記録はしない設定にしてテストする。まずはdaemonではなく普通にプロセスとして起動してみる。
sudo motion -n
ターミナルに吐き出されるログを見ながらちゃんと画像がストリーミングされるかどうか確認する。あ、ルーターのPort Forwardingで8080番ポートをRaspberry Pi 2にリダイレクトしないと外部からは見れないので注意。なぜか、ローカル側からはiPhoneのSafariでは見れるけど、MacやPCのSafariやFirefoxでは見れなかった。ついでに吐き出すログのイベントを見てるとモーション検知が動いてるかどうかも分かる。locate_motion_mode onにすれば検知した動作のある範囲を枠で表示してくれるので、検知感度の調整はそれを見ながらやればいい。終了は^Cで。
動作が確認出来たら、motion.confのdaemon offをonにして、さらにシステム起動時にdaemonとして起動する様に/etc/default/motionを書き換える。
start_motion_daemon=yes
再起動して、ちゃんとmotionが動いて外部からアクセスできれば監視カメラ設置完了。
監視カメラとして検知した動きを記録するようにすると、自宅でカメラの前をうろうろしただけでどんどん記録されちゃうので、外部トリガーで記録する度に一定程度古くなったデータを自動削除するようにしないとあっという間に空き容量なくなっちゃうかな。まあ、旅行時とかだけなら問題ないかも。今後の課題としておこう。
1週間以上経過した動体検知記録を削除するようなスクリプトを書いて、動体検知画像の出力の度に実行する様にすることにした。
/usr/local/bin/motion-delete.sh
—
#!/bin/sh
MOTION_DIR=/mnt/storage/motion/
find $MOTION_DIR -type f -mtime +7 -delete
—
で、これをmotion.confから実行する。書き換えるのは以下の箇所。
locate_motion_mode on
on_picture_save /usr/local/bin/motion-delete.sh
後は、サービスを再起動する。
sudo service motion restart
これで動体検知をすると画像を吐き出し、そのついでに一週間以上経過したものを見つけたら削除してくれるはず。軽く運用してどれぐらいのファイルが吐き出されるかを確認してから保存期間を調整しよう。できれば長期旅行を考えると一ヶ月ぐらいは保存しておきたい。
どうやらmotionは自動起動するとuid=motionで起動するようだ。したがって、rootのみ読み書き可でマウントされている/mnt/storageには書き込めない。さらに困ったことに、書き込みに失敗すると/var/log/user.logにfatal errorとほざいて終了してしまう。
なので、/mnt/storageをfstabをごにょごにょして誰でも読み書き可能な状態でマウントされるようにした。
locate_motion_modeがonだと動体を検出するとイベント終了までずっとファイルを記録し続けるため、大量にファイルが吐き出されてしまう。監視カメラとしては何かが起きたことだけが分かれば良いので、もっと出力画像を少なくするために、イベントごとに一枚だけ記録することにするため、onからbestに変更した。これで、イベントの中で最も動きの大きかった一枚が記録されるはずだ。
最近になってmotionで外部からstreamingを参照するときの認証ができなくなっていることに気が付いた。
どうやらMD5認証がこれまではちゃんと動作していたのに、どこかでエンバグしてちゃんと働かなくなってしまっているらしい。BASIC認証にすると問題なく認証できる。ぐぬぬ。セキュリティ的にはよろしくないが、どうしようもない。直すところは/etc/motion/motion.confの中。
stream_auth_method 2
この2がMD5認証なのでBASIC認証の1に変更する。
ついでにいつの間にかmotion.confの設定項目が結構増えていたので、最近のパッケージ更新で作られていたmotion.conf.dpkg-distをベースにmotion.confを書き直しておいた。
後、すっかり忘れていたがmDNSでIPv6ベースで名前解決が出来るようになったのでmotion.confに明示的にIPv6を使うように設定する
ipv6_enabled on
mDNSベースで名前解決してアクセスするとIPv6を使ってくれるので、表示もレスポンスも極めて良くなった。
ログを自動でローテーションさせたいので、/etc/motion/motion.confのlog_fileをコメントアウトしてログをsyslogに送るようにしていたのだが、logrotateの設定を眺めているとmotionのログをローテーションする設定がちゃんとmotion自身によって作成されていた。まったく杞憂だったので、デフォルト通りにログを/var/log/motion/motion.logに吐くように戻すことにする。
というわけで、まずはコメントアウトしたlog_fileを元に戻してmotionのサービスを再起動。ログがちゃんと正しく作成されていることを確認する。
logrotateのmotionのログのローテーションの設定はデフォルトで毎月ローテーションで12回更新と丸一年間保存する設定になっているが、このサーバーでは現在、30日経過した記録画像は消去する設定になっている。なので、ログも毎週ローテーションの4回更新で十分なので変更する。logrotateのmotionのログローテーションは/etc/logrotate.d/motionに設定されているので、以下の項目を変更する。
rotate 12
monthly
これを
rotate 4
weekly
にすればいい。残りの項目はデフォルトのままで十分だろう。
設定が完了したらlogrotateサービスを再起動する。
sudo service logrotate restart