はじめに
この記事は、こちらの記事で挙げた監視システムを構築した際の技術ログとなります。
オフィスの形状のせいか座席によって温度差があり、最北端の席に座っている社長がいつも「寒い、寒い」と震えているので、
Raspberry Pi2とAWS CloudWatchを使って、暑い場所と寒い場所の温度差を実際の数値で確認しました。
監視システムの概念図
実際の監視画面
実現方法
利用したパーツ類
前提条件
以下の手順はすべて、下記の環境で行いました。
- Raspberry Pi2にインストールしたOS: Raspbian Jessie
- 作業端末: iMac (OS X 10.11.3)
- 有線LANインタフェース名:en0
- 無線LANインタフェース名:en1
Raspberry Pi2のセットアップ
OSイメージ書き込み
Raspberry Pi公式サイトのダウンロードページ より、Raspbian (Raspberry Pi公式のDebian系Linux) をダウンロードします。
ダウンロード中に、OS Xの「ディスク ユーティリティ」(Disk Utility.app)を用いて下記を行っておくと良いでしょう。
- SDカードをFAT32でフォーマット
- SDカードドライブを選択して、「消去」ボタンを押下したあとに
MS-DOS(FAT)
を選択
- SDカードドライブを選択して、「消去」ボタンを押下したあとに
- SDカードドライブの識別子(例:disk2、disk3…)の確認
- SDカードドライブを選択して、「情報」ボタンを押下したあとに出てくるウィンドウで「BSD装置ノード」を調べる
ダウンロード完了後、Raspberry Pi公式サイトのインストールガイド を参考に、下記コマンドを実行して、ダウンロードしたOSイメージをSDカードに書き込みます。 。そこそこの時間(数分〜数十分程度)がかかりますので、ゆっくり待ちます。
# ここでは下記を仮定しています # * 上記手順で調べたSDカードドライブの識別子: diskn # * ダウンロードしたOSイメージファイルパス: path/to/your/image.img # パーティションをマウント解除 $ sudo diskutil unmountDisk /dev/diskn # イメージ書き込み $ sudo dd bs=1m if=path/to/your/image.img of=/dev/diskn
OS起動
下記を行い、OSを起動します。
- マイクロSDカード挿入
- LANケーブルで Raspberry Pi2 と 作業端末を直結
- (電源用)マイクロUSBケーブルとをコンセントへ接続
SSH接続
ディスプレイ・キーボードを直接Raspberry Pi2に繋げられば不要なのですが、今回はそれら無し(headless)でのセットアップを行うため、SSH接続経由で諸々の作業を行います。
起動直後のRaspberry Pi2のIPが不明なため、IPv6のリンクローカルマルチキャストアドレス(ff02::1
)へping6
して探り当てました。
# ff02::1 => リンクローカルマルチキャストアドレス $ ping6 -I en0 ff02::1 PING6(56=40+8+8 bytes) fe80::ae87:a3ff:fe26:e76d%en0 --> ff02::1 16 bytes from fe80::ae87:a3ff:fe26:e76d%en0, icmp_seq=0 hlim=64 time=0.099 ms 16 bytes from fe80::bbbe:fdf7:757a:2150%en0, icmp_seq=0 hlim=64 time=0.635 ms 16 bytes from fe80::ae87:a3ff:fe26:e76d%en0, icmp_seq=1 hlim=64 time=0.105 ms 16 bytes from fe80::bbbe:fdf7:757a:2150%en0, icmp_seq=1 hlim=64 time=0.583 ms ... # fe80::ae87:a3ff:fe26:e76d%en0はMacのIPなので # fe80::bbbe:fdf7:757a:2150%en0こっちが正解
探り当てたIPv6アドレスにSSH接続します。
$ ssh pi@fe80::bbbe:fdf7:757a:2150%en0 # 初期ユーザ ## user_id: pi ## password: raspberry
raspi-config
コマンドでの初期設定
$ sudo raspi-config
(お好みで)SSH接続後に上記コマンドを実行して、各種設定を行います。
少なくとも、Expand Filesystem
は行ったほうが良いかと存じます。
- Expand Filesystem:ルートパーティションサイズ拡大
- Change Locale:ロケールを ja_JP.UTF8 UTF8 へ変更
- Change Timezone:タイムゾーンを Asia > Tokyo へ変更
有線LAN・無線LAN設定
下記の設定変更・確認を行います。
- 便宜上、有線LANのIPを固定割当
- 無線LANのIP割当をDHCPで行う
$ sudo vi /etc/network/interfaces # 便宜上、有線LANのIPを適当に固定割当にする auto eth0 iface eth0 inet static address 192.168.11.100 netmask 255.255.255.0 # 無線LAN接続情報は別ファイルに記載する allow-hotplug wlan0 iface wlan0 inet dhcp wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
上記設定で指定してある無線LAN接続情報の設定ファイル: /etc/wpa_supplicant/wpa_supplicant.conf
の内容は、こちらを参考に、wpa_passphrase
コマンドを利用して記述します。
下記の部分は、自ネットワーク環境の情報に置き換えてください。
無線LANのWPAパスフレーズ
無線LANのSSID
$ sudo sh -c "wpa_passphrase 無線LANのSSID 無線LANのWPAパスフレーズ >> /etc/wpa_supplicant/wpa_supplicant.conf" # 内容確認 $ sudo cat /etc/wpa_supplicant/wpa_supplicant.conf ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="無線LANのSSID" psk=2b1d17284c5410ee5eaa............. }
設定反映のため、再起動します。
$ sudo reboot
再起動後に、無線LANの接続を確認します。
# ... # 再起動後 # ... # wlan0のipv4アドレス (inetアドレス) が割り当てられていることを確認 $ ifconfig wlan0 Link encap:イーサネット ハードウェアアドレス xx:xx:xx:xx:xx:xx inetアドレス:192.168.3.xxx ブロードキャスト:192.168.3.255 マスク:255.255.255.0 ... # 接続している無線LANのSSIDも念のため確認 $ iwconfig wlan0 IEEE 802.11bgn ESSID:"{{無線LANのSSID}}" ...
以上で無線LAN接続が確認できました。
avahi (Zeroconf) 設定
avahiとは、Zeroconfのフリーの実装です。
マルチキャストDNSという技術により、難しい設定をすることなく、同一LAN内にて raspberrypi.local
といった{{hostname}}.local
という形式の名前で名前解決できるようになります。
設定しなくても問題ありませんが、パッケージをインストールする程度で使えるようになるので、インストールしておくと良いかと存じます。
# avahiのパッケージインストール $ sudo apt-get install avahi-daemon
/etc/hostname
と/etc/hosts
の内容を確認します。
$ sudo cat /etc/hostname raspberrypi $ sudo cat /etc/hosts ... 127.0.1.1 raspberrypi
Raspberry Pi2を再起動します。
$ sudo reboot
Raspberry Pi2再起動後、同一LAN内の他のホストから、raspberrypi.local
に向けてping
を飛ばして名前解決の動作確認を行います。
作業端末がWindowsの場合、Appleのサイト から Windows 用 Bonjour をインストールする必要があるかと存じます。
$ ping raspberrypi.local PING raspberrypi.local (192.168.3.222): 56 data bytes 64 bytes from 192.168.3.222: icmp_seq=0 ttl=64 time=23.439 ms 64 bytes from 192.168.3.222: icmp_seq=1 ttl=64 time=2.591 ms ...
vim
インストール
デフォルトだと、vi
しかインストールされていないので、vim
もインストールします。
$ sudo apt-get install vim # vim ~/.bashrc # 環境変数EDITOR追記 export EDITOR="vim"
AWS CLIインストール
aptのawscli
パッケージをインストールします。
$ apt-cache search awscli awscli - Universal Command Line Environment for AWS $ sudo apt-get install awscli
温度センサ(DS18B20)回路・測定プログラム実装
配線図のとおりに、回路接続を行います。
- DS18B20の1番ピン (GND) – ラズパイGPIOのGNDのどれか
- DS18B20の2番ピン (DQ) – ラズパイGPIO4
- 3.3VとGPIO4ピンを抵抗で繋いでプルアップします
- DS18B20の3番ピン (Vdd) – ラズパイGPIOの3.3Vのどれか
ピン配置は下記サイトを参考にしました。
1-Wireセットアップ
今回使用した温度センサ:DS18B20は、1-Wireというプロトコルで通信を行うことで測定値を取得できます。そのため、Raspberry Pi2側で1-Wireを有効化します。
/etc/modules
に下記の行を追記
$ sudo vim /etc/modules w1-gpio w1-therm
/boot/config.txt
に下記の行を追記
$ sudo vim /boot/config.txt dtoverlay=w1-gpio-pullup,gpiopin=4
最後にRaspberry Pi2を再起動する
$ sudo reboot
温度センサとRaspberry Pi2間の疎通確認
こちら を参考に疎通確認を行います。
正常に接続・設定できている場合、/sys/bus/w1/devices/
内に、28-00000723c22d
のような名前形式のディレクトリができます(環境により、このディレクトリ名は異なります)。存在しない場合は、配線・設定をもう一度確認してください。
$ ls -la /sys/bus/w1/devices/ lrwxrwxrwx 1 root root 0 3月 7 14:49 28-00000723c22d -> ../../../devices/w1_bus_master1/28-00000723c22d lrwxrwxrwx 1 root root 0 3月 7 14:48 w1_bus_master1 -> ../../../devices/w1_bus_master1 ...
存在する場合、該当するディレクトリ内のw1_slave
という名前のファイルを表示してみます。
すると、下記のような文字列が確認できるはずです。
$ cat /sys/bus/w1/devices/28-00000723c22d/w1_slave d7 01 4b 46 7f ff 09 10 55 : crc=55 YES d7 01 4b 46 7f ff 09 10 55 t=29437
この文字列の、t=29437
の部分の値がセ氏温度を1000倍した値を表しています。
無事に疎通確認ができましたでしょうか。
温度計測プログラム実装
上記の、sys/bus/w1/devices/28-00000723c22d/w1_slave
で取得できるデータをうまいこと加工できれば、どんな言語でも良いのですが、 timofurrer/w1thermsensor というPythonライブラリが簡単そうでよかったので、
今回はPythonで実装して、/home/pi/pi_therm_sensor/PiThermSensor.py
へ設置しました。
# -*- coding: utf-8 -*- from w1thermsensor import W1ThermSensor def get_temperature(): sensor = W1ThermSensor() temperature_celsius = sensor.get_temperature() return temperature_celsius temperature = get_temperature() print("{0:.3f}".format(temperature))
CloudWatchへの送信処理実装
cloudwatch put-metric-data
用にIAMユーザ追加
Raspberry Pi2から、AWS CLIのコマンドによりCloudWatchへ測定した温度を送信する際に用いるIAMユーザを追加します。
- AWSマネジメントコンソールを開く
- IAM > ユーザ の順に遷移して、
新規ユーザ作成
ボタンを押下 - ユーザー名をお好みで入力(今回は
IoT
とした)。「ユーザーごとにアクセスキーを生成」はチェックしたままでOK - ユーザ作成後に提示される
credentials.csv
ファイルをダウンロード - IAM > ユーザー 画面にて、 先ほど追加したユーザ名:
IoT
を検索してクリック アクセス許可
タブ のページに存在するポリシーのアタッチ
ボタンを押下CloudWatchFullAccess
ポリシーを検索して選択し、ポリシーのアタッチ
ボタンを押下
下記のような状態になっていれば大丈夫です。
AWS CLIのプロファイル設定
上記手順でIAMユーザを作成した際のcredentials.csv
をもとにプロファイルを設定します。 aws configure
コマンド実行時に、秘匿情報の入力を要求されるので指示にしたがって入力します。
ここでは、作成するプロファイル名をiot
とします。
aws configure --profile iot # アクセスキー:credentials.csv の Access Key Id # アクセスキーシークレット:credentials.csv の Secret Access Key # リージョン:ap-northeast-1 (東京リージョン)
測定した温度をCloudWatchへ送信するシェルスクリプト実装
AWS CLIのコマンド aws cloudwatch put-metric-data
で測定した温度を送信するシェルスクリプトを実装し、/home/pi/pi_therm_sensor/clowdwatch_put_temperature.sh
へ設置しました。
上記手順で作成したプロファイル:iot
を用いて、測定した温度をraspberry_pi_temperature
というメトリクス名で送信しています。
#!/bin/bash REGION="ap-northeast-1" THERM_SENSOR_CMD="/usr/bin/python /home/pi/pi_therm_sensor/PiThermSensor.py" TEMPERATURE=`$THERM_SENSOR_CMD` echo "temperature: "$TEMPERATURE /usr/local/bin/aws cloudwatch put-metric-data \ --profile iot \ --namespace "Pi" \ --metric-name "raspberry_pi_temperature" \ --dimensions "Host=pi" \ --unit "None" \ --value $TEMPERATURE \ --region $REGION
Cronで測定した温度を定期的にCloudWatchへ送信する
上記手順で作成したシェルスクリプトを、Cronで定期実行するように設定を追記します。
$ crontab -e * * * * * /home/pi/pi_therm_sensor/clowdwatch_put_temperature.sh >> /var/log/cron.log 2>&1
ただし、Raspbian
の初期設定のままだと、/var/log/cron.log
へログ出力がなされなかったので下記設定を行いました。
/etc/rsyslog.conf
設定変更
$ sudo vim /etc/rsyslog.conf # /var/log/messages に大量のエラーログが吐かれてしまうので、 # 最後にある下記設定をコメントアウト # daemon.*;mail.*;\ # news.err;\ # *.=debug;*.=info;\ # *.=notice;*.=warn |/dev/xconsole # 下記の行がコメントアウトされているので # 有効にする cron.* /var/log/cron.log # rsyslog再起動 $ sudo service rsyslog restart
/var/log/cron.log
を確認
$ sudo tail /var/log/cron.log ... Mar 2 16:55:18 raspberrypi CRON[3377]: (CRON) info (No MTA installed, discarding output) ... # No MTA installed # などと言われるので # postfixをインストール $ sudo apt-get install postfix mailutils
すべて正常に動作している場合、AWSマネジメントコンソールのCloudWatchにて、 raspberry_pi_temperature
で検索すれば、
下図のような画面が表示されるはずです。
感想
Raspberry Pi2による温度計測については、
- OS(Raspbian)側で、Raspberry PiのGPIOを用いたハードウェア制御の仕組みを用意してくれている
- Raspberry Piブームのおかげで、Web上に参考になる先行事例がたくさんある
- 一般的なスクリプト言語でプログラムを記述できる
といった理由により、とても簡単にできたと存じます。
また、CloudWatchによる温度の可視化・監視についても、AWS CLIを用いることで、 いくつかのコマンドを叩くだけで、簡単にできてしまいました。
便利なモノはたくさん揃っているので、これからは、手間がかかる/本質以外の箇所は既存のモノを組み合わせてスピーディーに解決し、 アイデアの本質的な部分へ最大限の力を注ぐことが大切なのではないでしょうか。
参考サイト
- ラズベリーパイ(B+)を購入!Macbookと連携して開封から初期設定までやってみた! | うえぶまなぶ
- Raspberry Pi + 無線LAN セットアップ – Qiita
- Raspberry Piで手作り温度計! | Device Plus – デバプラ
- Raspberry Piと1-Wireステンレス防水温度センサ(DS18B20)を使って水温を計る | ものづくりエクスペリメント
- Raspberry Piで1-Wireデジタル温度センサのDS18B20をPythonから使う – Qiita