Edited at

ラズパイで監視カメラを作ったときの備忘録

More than 1 year has passed since last update.

無人部屋に監視カメラが必要だったので作ったときの備忘録。

モチベーションは外付けのモニターとキーボードを使わないこと


使ったもの

だいたい次のものを使用した。


  • Mac

  • Raspberry Pi 3 Model B

  • Raspberry Piの電源

  • Thunderbolt Ethernetアダプタ

  • MicroSD カード 16 GB

  • Logitech WebCam(USB)

  • Buffaloの無線LAN子機


Raspbian(OS)のインスコ

$ # 最新のRASPBIANを取得

$wget https://downloads.raspberrypi.org/raspbian_latest
--2017-09-12 20:02:28-- https://downloads.raspberrypi.org/raspbian_latest
Resolving downloads.raspberrypi.org... 93.93.135.188, 93.93.128.211, 93.93.128.230, ...
Connecting to downloads.raspberrypi.org|93.93.135.188|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-09-08/2017-09-07-raspbian-stretch.zip [following]
--2017-09-12 20:02:31-- https://downloads.raspberrypi.org/raspbian/images/raspbian-2017-09-08/2017-09-07-raspbian-stretch.zip
Connecting to downloads.raspberrypi.org|93.93.135.188|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2017-09-08/2017-09-07-raspbian-stretch.zip [following]
--2017-09-12 20:02:32-- http://director.downloads.raspberrypi.org/raspbian/images/raspbian-2017-09-08/2017-09-07-raspbian-stretch.zip
Resolving director.downloads.raspberrypi.org... 93.93.130.214, 93.93.130.104, 93.93.128.133, ...
Connecting to director.downloads.raspberrypi.org|93.93.130.214|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1757290390 (1.6G) [application/zip]
Saving to: 'raspbian_latest'

raspbian_latest 100%[==============================================================================================>] 1.64G 271KB/s in 2h 4m

2017-09-12 22:06:45 (230 KB/s) - 'raspbian_latest' saved [1757290390/1757290390]

wget https://downloads.raspberrypi.org/raspbian_latest 16.39s user 71.27s system 1% cpu 2:04:16.75 total

$ # SHA1でファイルを確認
$openssl sha1 raspbian_latest
SHA1(raspbian_latest)= c35688583510fc93c5deac637976b7a5c9c55689
openssl sha1 raspbian_latest 3.70s user 0.46s system 92% cpu 4.478 total

$ # 解凍
$unzip raspbian_latest
Archive: raspbian_latest
inflating: 2017-09-07-raspbian-stretch.img
unzip raspbian_latest 32.40s user 4.09s system 87% cpu 41.859 total

$ # ファイルの確認
$ ls -al
total 13033808
drwxr-xr-x 4 os10 staff 136 9 12 22:38 .
drwxr-xr-x 12 os10 staff 408 9 12 20:02 ..
-rw-r--r-- 1 os10 staff 4916019200 9 8 01:23 2017-09-07-raspbian-stretch.img
-rw-r--r-- 1 os10 staff 1757290390 9 8 01:30 raspbian_latest


SDカードのフォーマットとRaspbianのコピー

$ # ※先にSDカードをマウントする

$ diskutil list
...
/dev/disk2 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *15.8 GB disk2
1: Windows_FAT_32 NO NAME 15.8 GB disk2s1

$ # SDカードをフォーマット
$ diskutil eraseDisk FAT32 RPI /dev/disk2
Started erase on disk2
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk2s2 as MS-DOS (FAT32) with name RPI
512 bytes per physical sector
/dev/rdisk2s2: 30487440 sectors in 1905465 FAT32 clusters (8192 bytes/cluster)
bps=512 spc=16 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=411648 drv=0x80 bsec=30517248 bspf=14887 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk2

$ # SDカードをアンマウント
$ diskutil unmountDisk /dev/disk2
Unmount of all volumes on disk2 was successful

$ sudo dd bs=16m if=2017-09-07-raspbian-stretch.img of=/dev/rdisk2
$ # デバイス名にrを付けつと10倍ぐらい早い。進捗はCtrl+tで確認する。
$ # Imageの容量は5GBで6MB/secの速度だったので、だいたい10minぐらい。
load: 2.00 cmd: dd 73563 uninterruptible 0.00u 0.04s
3+0 records in
2+0 records out
33554432 bytes transferred in 5.498053 secs (6102966 bytes/sec)
load: 2.00 cmd: dd 73563 uninterruptible 0.00u 0.07s
...
4916019200 bytes transferred in 461.069118 secs (10662217 bytes/sec)
sudo dd bs=16m if=2017-09-07-raspbian-stretch.img of=/dev/rdisk2 0.01s user 3.18s system 0% cpu 7:43.63 total


SSHの有効化

どうやら最近は初期状態で無効化されているらしいため

$ cd /Volumes

Macintosh HD boot
$ ls -al
total 12
drwxr-xr-x@ 4 root wheel 136 9 13 00:54 .
drwxr-xr-x 34 root wheel 1224 8 13 16:54 ..
lrwxr-xr-x 1 root wheel 1 8 12 21:44 Macintosh HD -> /
drwxrwxrwx@ 1 os10 staff 2048 9 13 00:54 boot

$ touch ./boot/ssh
$ # bootフォルダにsshという空ファイルを作成すれば良いらしい

$ diskutil unmountDisk /dev/disk2
Unmount of all volumes on disk2 was successful


ラズパイをMacに接続する

次の手順でMacのNetworkのSharingの設定をする

1. System Preference > Sharing を開く

2. Internet Sharing(Service)のチェックボックスを活性化する

3. To computers usingのThunderbolt Ethernet(Ports)のチェックボックスを活性化する

4. ラズパイを起動してMacとLANケーブルで接続する


ラズパイにSSHで接続

$ # ネットワークのインターフェイスを確認(bridge***オプションがEthernetのインターフェイス)

$ ifconfig
...
bridge100: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=3<RXCSUM,TXCSUM>
ether a6:5e:60:ab:ad:64
inet 192.168.2.1 netmask 0xffffff00 broadcast 192.168.2.255
inet6 fe80::a45e:60ff:feab:ad64%bridge100 prefixlen 64 scopeid 0x10
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x2
member: en6 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 15 priority 0 path cost 0
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
$ # inetがIPv4なのでThunderboltのI/Fは次のようになる
$ # - IPアドレス: 192.168.2.1
$ # - サブネットマスク: 255.255.255.0(/24)
$ # - ブロードキャストアドレス: 192.168.2.255
$ # なので対象のIPアドレスは19.168.2.2~244の範囲となる

$ # ネットワークに存在するホスト一覧を取得する
$ nmap -n -sP 192.168.2.1/24
Starting Nmap 6.47 ( http://nmap.org ) at 2017-09-13 02:37 PHT
Strange error from connect (65):No route to host
Nmap scan report for 192.168.2.1
Host is up (0.0058s latency).
Nmap scan report for 192.168.2.3
Host is up (0.0052s latency).
Nmap done: 256 IP addresses (2 hosts up) scanned in 0.03 seconds
$ # このIPアドレス(192.168.2.3)がそれっぽい

$ # SSH接続
$ ssh pi@192.168.2.3 # pi@raspberrypi.local でもOK
pi@192.168.2.3's password: # PWはraspberry
$ # NOTE: REMOTE HOST IDENTIFICATION HAS CHANGEDの場合は次のコマンドでフィンガープリントを削除する
$ # ssh-keygen -R 192.168.2.3


VNCを使う

VNCを使う理由はキャプチャした画像の確認をするため



  • Raspberry側の設定

    $ # raspberryにVNCを入れる
    
    $ sudo apt-get update
    $ sudo apt-get install tightvncserver
    $ tightvncserver # VNCサーバーを起動
    # PWの設定



  • Mac側の設定


    • Finderを起動

    • Go > Connect to Server

    • Server Address: vnc://raspberrypi.local:5901

    • GUIが表示されればOK




Wifiの設定


  • Buffaloの無線LAN子機をラズパイに刺す

  • GUIでWifiの設定を行なう


    • CUIからwpa-supplicant.confでやってもよい



  • Wifi設定後はThunderbolt Ethernetアダプタを使用しない


カメラの設定

$ # USBカメラをラズパイに接続する

$ lsusb
Bus 001 Device 004: ID 0411:01a2 BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070]
Bus 001 Device 005: ID 046d:0826 Logitech, Inc. HD Webcam C525
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ # LogitechのWebcamが認識されている

$ # キャプチャソフトをインスコ
$ sudo apt install fswebcam
...
Unpacking fswebcam (20140113-1) ...
Setting up fswebcam (20140113-1) ...
Processing triggers for man-db (2.7.6.1-2) ...

$ # 撮影テスト
$ pwd
/home/pi
$ fswebcam -r 640x480 -F 1 -S 100 ./test.jpg # -Fはフレーム, -Sは露光
--- Opening /dev/video0...
Trying source module v4l2...
/dev/video0 opened.
No input was specified, using the first.
Adjusting resolution from 384x288 to 352x288.
--- Capturing frame...
Captured frame in 0.00 seconds.
--- Processing captured image...
Fontconfig warning: ignoring UTF-8: not a valid region tag
Writing JPEG image to 'test.jpg'.
$ # /home/pi/test.jpg に画像が保存されるのでVNCで確認する

$ # カメラのパラメータの調節ソフト
$ sudo apt install guvcview
$ # Menu > Sound & Video > guvcview を起動


モーションセンサーの設定

$ sudo apt-get install -y motion

$ # 撮影テスト
$ sudo motion -c /etc/motion/motion.conf
$ # /var/lib/motion/ に保存される。GUIでチェックする

$ # 設定ファイル更新(以下の様に)
$ sudo vi /etc/motion/motion.conf
# Motionをサービスとして実行
daemon on
# 動画機能OFF
ffmpeg_output_movies off
# 写真のサイズ
width 640
height 480
# 動体検知のしきい値
threshold 3000
gap 100
# 画像について
locate_motion_mode on # 動体検知箇所をかこう
text_double on # テキスト大きく

$ sudo vi /etc/default/motion
# スタートアップの時にデーモンとして動かす
start_motion_daemon=yes


Slackで通知

次を事前に行なう


  • Slack登録

  • Slack Appを作成

  • 次の2点を有効化する

     1. Add features and functionality(Bot)

     2. Install your app to your workspace(対象のTeam)


  • Botを対象のチャンネルにインバイトする


Pythonの依存モジュールのインスコ

$ sudo pip install slacker

pi@raspberrypi:~/slack $ sudo pip install slacker

Collecting slacker
Downloading slacker-0.9.60.tar.gz
Requirement already satisfied: requests>=2.2.1 in /usr/lib/python2.7/dist-packages (from slacker)
Building wheels for collected packages: slacker
Running setup.py bdist_wheel for slacker ... done
Stored in directory: /root/.cache/pip/wheels/57/61/2c/99406ad2141fdf3ede576acedad209a3b63b9674af56bbfa19
Successfully built slacker
Installing collected packages: slacker
Successfully installed slacker-0.9.60


メッセージ投稿テスト

$ python

Python 2.7.9 (default, Mar 8 2015, 00:52:26)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from slacker import Slacker
>>> token = "HOGEHOGE" # OAuth Tokens for Your Team > Bot User OAuth Access Token
>>> slk = Slacker(token)
>>> cn = "C71DQB3MG" # チャンネル名はエンコード済みのもの。slackのURLを見れば分かる
>>> msg = 'APIだよ'
>>> slk.chat.post_message(cn, msg)
<slacker.Response object at 0xb64aca50>


画像のアップロードテスト

$ python

Python 2.7.9 (default, Mar 8 2015, 00:52:26)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from slacker import Slacker
>>> token = "HOGEHOGE" # OAuth Tokens for Your Team > Bot User OAuth Access Token
>>> slk = Slacker(token)
>>> cn = "C71DQB3MG"
>>> fn = '/home/pi/hoge.jpg'
>>> comment = "test"
>>> slk.files.upload(fn, channels=[cn], initial_comment=comment) # 画像を投稿
<slacker.Response object at 0xb64aca50>


Motionで自動画像投稿

Motionの設定で画像をSaveするたびにスクリプトをフックさせる

$ sudo vi /etc/motion/motion.conf

# confからsave時にスクリプトをフックできる
on_picture_save python /home/pi/slack/bot.py %f # %f=画像のファイル名

$ cd /home/pi
$ mkdir slack
$ cd slack
$ vi bot.py # 後述のスクリプト作成
$ chmod a+x /home/pi/slack/bot.py # 実行権限付与
$ python ./bot.py /home/pi/test.jpg # テスト


bot.py

# -*- coding: utf-8 -*-

import sys
from slacker import Slacker
from datetime import datetime

class Slack(object):

__slacker = None

def __init__(self, token):
self.__slacker = Slacker(token)

def post_to_file(self, file_path, encoded_ch_name):
now = datetime.now()
comment = "Uploaded At: " + now.strftime('%Y-%m-%d %H:%M:%S') + '(UTC)'
print("Sending a picture")
self.__slacker.files.upload(file_path, channels=[encoded_ch_name], initial_comment=comment)
print("Done")

if __name__ == "__main__":

param = sys.argv
file_path = param[1]

token = "" # Bot User OAuth Access Token
slack = Slack(token)
encoded_ch_name = "C71DQB3MG"
slack.post_to_file(file_path, encoded_ch_name)



Motionをデーモン化

$ # サービスとして有効化

$ sudo systemctl enable motion
$ sudo systemctl list-unit-files -t service # サービス一覧の設定確認
$ sudo systemctl is-enabled motion # motionの設定確認
motion.service is not a native service, redirecting to systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install is-enabled motion
enabled
$ # enabledなのでOK

$ # ランレベル変更
$ sudo systemctl set-default multi-user.target # デフォルトのターゲットをマルチユーザーモードに変更(電源入れればMotion有効化)
$ sudo systemctl get-default
multi-user.target

$ # スタートしてサービスの状態確認
$ sudo systemctl start motion
$ sudo service motion status
● motion.service - LSB: Start Motion detection
Loaded: loaded (/etc/init.d/motion; generated; vendor preset: enabled)
Active: active (exited) since Wed 2017-09-13 01:19:37 UTC; 5h 51min ago
Docs: man:systemd-sysv-generator(8)
Process: 5219 ExecStop=/etc/init.d/motion stop (code=exited, status=0/SUCCESS)
Process: 5268 ExecStart=/etc/init.d/motion start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/motion.service

Sep 13 01:19:37 raspberrypi systemd[1]: Starting LSB: Start Motion detection...
Sep 13 01:19:37 raspberrypi motion[5268]: Starting motion detection daemon: motion.
Sep 13 01:19:37 raspberrypi systemd[1]: Started LSB: Start Motion detection.
Sep 13 01:19:38 raspberrypi motion[5274]: [0:motion] [NTC] [ALL] conf_load: Processing thread 0 - config file /etc/motion/motion.conf
Sep 13 01:19:38 raspberrypi motion[5274]: [0:motion] [NTC] [ALL] motion_startup: Motion 4.0 Started
Sep 13 01:19:38 raspberrypi motion[5274]: [0:motion] [ERR] [ALL] myfopen: Error opening file /var/log/motion/motion.log with mode a: Permission denied
Sep 13 01:19:38 raspberrypi motion[5274]: [0:motion] [EMG] [ALL] motion_startup: Exit motion, cannot create log file /var/log/motion/motion.log: Permission denied

$ # motionユーザーのパーミッションがないらしいので変更
$ sudo chown motion:motion /var/run/motion
$ sudo chown motion:motion /var/log/motion/motion.log

$ # 再確認
$ sudo systemctl start motion
$ sudo systemctl status motion
...
Sep 13 07:17:01 raspberrypi systemd[1]: Starting LSB: Start Motion detection...
Sep 13 07:17:02 raspberrypi motion[5860]: Starting motion detection daemon: motion.
Sep 13 07:17:02 raspberrypi systemd[1]: Started LSB: Start Motion detection.
Sep 13 07:17:03 raspberrypi motion[5866]: [0:motion] [NTC] [ALL] conf_load: Processing thread 0 - config file /etc/motion/motion.conf
Sep 13 07:17:03 raspberrypi motion[5866]: [0:motion] [NTC] [ALL] motion_startup: Motion 4.0 Started
$ # 今度はOK

$ # サービスのログを全部見たい場合は
$ sudo journalctl -b | less # 全ログチェック
$ sudo journalctl -u motion | less # モーションのログチェック

$ # その他
$ sudo systemctl stop motion
$ sudo systemctl disable motion


参考文献

http://qiita.com/toshihirock/items/8e7f0887b565defe7989

https://medium.com/@tzhenghao/how-to-ssh-into-your-raspberry-pi-with-a-mac-and-ethernet-cable-636a197d055

http://qiita.com/wf9a5m75/items/6712181de189169eb444

http://www.pawprint.net/designresources/netmask-converter.php

https://vivibit.net/raspbian-enable-ssh/

https://www.raspberrypi.org/forums/viewtopic.php?t=191252

http://daisukekmr.hatenablog.com/entry/2015/01/22/201919

http://qiita.com/kinpira/items/bf1df2c1983ba79ba455

http://a244.hateblo.jp/entry/2016/10/14/053000

http://qiita.com/Go-zen-chu/items/63f65156c748b34e1678

http://safe-linux.homeip.net/web/motion/motion-03.html

https://github.com/yusukeyamatani/slackbot/blob/master/slack_bot.py

https://github.com/os/slacker

https://github.com/Motion-Project/motion/issues/309

https://raspberrypi.stackexchange.com/questions/41342/how-to-start-motion-in-daemon-mode-on-rpi-running-raspbian-jessie

https://raspberrypi.stackexchange.com/questions/43740/how-do-i-change-runlevel-on-model-3