無人部屋に監視カメラが必要だったので作ったときの備忘録。
モチベーションは外付けのモニターとキーボードを使わないこと
使ったもの
だいたい次のものを使用した。
- 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の設定をする
- System Preference > Sharing を開く
- Internet Sharing(Service)のチェックボックスを活性化する
- To computers usingのThunderbolt Ethernet(Ports)のチェックボックスを活性化する
- ラズパイを起動して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 # テスト
# -*- 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