読者です 読者をやめる 読者になる 読者になる

Raspberry Piと温度・湿度・光センサーでオフィスの状況を可視化する

monitoring

インフラ周りを見ている佐野です。普段は運用寄りの業務を担当していて、トレタの構築・運用管理、キャパシティの確保、開発環境やデプロイ環境の整備などを行っています。今回の記事は業務とは関係ないネタです。冬休みにRaspberry Pi(以下ラズパイ)をチョメチョメしたのでそのことについて書きます。件のとおり、温度、湿度、光センサーを作ってみました。誰もいない自分の部屋に置いといてもおもしろくないので、作ったものをオフィスに持ってきて執務エリアの状況をモニタリングしています。

冬休みの宿題

そもそもなぜこれをやろうと思ったか、なのですが、前々からIoTみたいなものに触れてみたいと思っていました。そんな折、沖縄で海ぶどうを栽培して売っていた経験があるというセールスのあぶちゃんと話をしていて、彼から海ぶどうの品質管理の難しさ(光の強さ、海水温、二酸化炭素濃度、酸素含有量の計測etc)の話を聞いて、温度と光量の監視くらいならシステム化できるんじゃないかと思って手を出してみました。これが結構おもしろくて、「1週間くらいかかりそうだし冬休みの暇つぶしにちょうどいいかな」と思っていたんですが、1〜2日程度で近いものができてしまいました。あとは空気の組成をどう調べるかと電源や通信環境など屋外で使うための仕組みをうまいこと設えれば海ぶどうの監視に使えるかも...しれません...。

少し長めのエントリになってしまったので、以下が目次になります。

  1. 様子&買ったもの
  2. ラズパイの初期設定
  3. wifiの設定
  4. 温度センサー(DHT11)
  5. 光センサー(BH1750FVI)
  6. データの取得と通知
  7. メトリクス
  8. 今後
  9. 参考文献

1. 様子&買ったもの

こんな様子でオフィスに置いてあります。水色のモジュールが温度湿度センサー、輪ゴムで巻きつけてあるのが光センサーです。はんだごて持ってないので...。

f:id:hiroakis:20160214202835j:plain

参考までに必要なもの列挙。キーボード、ディスプレイはmacbookを使います。

  • Raspberry Pi 2
    • 本体。秋月電子秋葉原店で購入。
  • Raspberry Piのケース
    • ケース。秋月電子秋葉原店で購入。
  • microSDカード
    • ラズパイのストレージとして使う。とりあえず16GB。秋月電子秋葉原店で買った。
  • USBカードリーダー
  • 電源
    • ラズパイの電源プラグ。秋月電子秋葉原店で購入。
  • USB wifi
  • センサー一式
  • ジャンパーワイヤー
    • 配線。オス - オス、オス - メス、メス - メスをそれぞれ適度に用意する。どこに何を繋がっているかわかりやすくするためにそれぞれ複数色用意する。秋月電子秋葉原店で購入。
  • ブレッドボードミニ
    • 配線の土台として使う。秋月電子秋葉原店で購入。
  • LANケーブル
    • Macbookとラズパイをつないで初期設定する際に使う。
  • LANアダプタ
    • MacbookのUSBポートとLANをつなぐために使う。

2. ラズパイの初期設定

マイクロSDのフォーマット、OSインストール、ラズパイの初期設定の順に行います。

  • マイクロSDのフォーマット

こちらのサイトを参考にフォーマットを行います。

  • OSインストール

ここからラズパイのOSイメージをダウンロードします。続いてUSBカードリーダーにフォーマット済のマイクロSDを装着して下記コマンドでイメージを書き込みます。書き込みが完了したらマイクロSDをラズパイに装着して電源を入れます。

diskutil list
diskutil unmountDisk /dev/disk2
# ラズパイのイメージを書き込む
sudo dd bs=1m if=/Users/hiroakis/Desktop/2015-11-21-raspbian-jessie-lite.img of=/dev/disk2
  • ラズパイの初期設定

先の手順ですでにOSインストールが完了しているので、macbookとラズパイをUSBケーブルで繋げてsshします。「システム環境設定」->「共有」と進み、「インターネット共有」をONにし、「USBイーサーネットにチェック」をつけます。この状態でラズパイとmacbookをつなげて下記コマンドを叩くとラズパイのIPがわかるのでそのIPにsshできます。

cat /var/log/system.log | grep OFFER
ssh pi@ラズパイのIP

下記コマンドで初期設定を行います。

sudo raspi-config

「Expand Filesystem」⇒「OK」カード容量を最適化
「Internationalisation Options」⇒「Change Timezone」⇒「Asia」⇒「Tokyo」を設定。
「Internationalisation Options」⇒「Change Keyboard Layout」で、キーボードを最適化

3. wifiの設定

wifiの設定を行います。下記コマンドでSSIDとパスワードをコンフィグに書き込んでネットワークを再起動。接続可能なSSIDは sudo iwlist wlan0 scan でスキャンできます。

sudo sh -c "wpa_passphrase [SSID] [PASS] >> /etc/wpa_supplicant/wpa_supplicant.conf"

ここまでできればあとはwifiごしにsshできるようになります。ここで割と重要なのが、省電力モードの無効化です。買ったwifiデバイスによってはsshがプツプツ切れるという現象が発生します。調べたところ省電力モードが原因のようなので次のようにして省電力モードを無効にしておきます。

lsusb
 => Bus 001 Device 004: ID 2019:ab2a PLANEX GW-USNano2 802.11n Wireless Adapter [Realtek RTL8188CUS]

(lsusbコマンドとか2年ぶりくらいに打ちました...)

sudo vim /etc/modprobe.d/Realtek_RTL8188CUS.conf
# 下記を書き込む
options 8192cu rtw_power_mgnt=0 rtw_enusbss=0

なお、こちらのページを参考にさせていただきました。

4. 温度センサー(DHT11)

温度センサーはDHT11を使います。データシートはこちら。この手のものを触り慣れている人にとっては常識かもしれませんが、簡単に説明させていただくと、ラズパイの各端子にはそれぞれ役割があります。なのでモジュール側の端子の対応する場所と接続します。例えば電力を供給する端子の一部は下記の場所にあります。他にもデジタル信号の入出力に使う端子(GPIO)と、I2CやSPIに対応している端子もあります。

f:id:hiroakis:20160214202908j:plain

(しかし...ネットから画像を拝借すればよかったのに、なんでわざわざこのヘッタクソな絵を書いたのか...自分でも思い出せない)

温度センサーを取り付けたらラズパイ上から温度を取得するためのライブラリをインストールします。DHT用のライブラリはgithub上に公開されているのでそれを利用します。

sudo apt-get install build-essential python-dev
git clone https://github.com/adafruit/Adafruit_Python_DHT.git
cd Adafruit_Python_DHT/
sudo python setup.py install

インストール後、Pythonから下記のようにして温度と湿度が取得できるようになります。read_retryの第二引数はラズパイのGPIO端子のピン番号を表していて、今回はGPIO(4)に接続したので4としています。

import Adafruit_DHT
 
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, 4)

5. 光センサー(BH1750FVI)

光センサーはBH1750FVIを使います。こちらのサイトを参考に、ラズパイでI2C通信ができるように設定を行います。さらにI2Cバス番号とデバイスアドレスの取得ができるようにi2c-toolsをインストールし、PythonからI2C通信を行うためにpython-smbusをインストールします。

sudo apt-get install python-smbus i2c-tools

i2c-toolsをインストールするとi2cdetectコマンドが使えるようになるので、sudo i2cdetect 0またはsudo i2cdetect 1 を実行します。今回は後者で結果が返ってきたのでバス番号は「1」であることがわかりました。さらに結果からアドレスは「0x23」であることがわかりました。ここで判明したバス番号とデバイスアドレスを用い、次のようにして光センサーの測定結果にアクセスできます。

import smbus
 
bus = smbus.SMBus(1)
addr = 0x23
luxRead = bus.read_i2c_block_data(addr,0x11)

read_i2c_block_dataの第一引数はセンサーモジュールのアドレス、第二引数は測定のモード(分解能と1回あたりの測定時間)を表しています。0x11は0.5Luxの分解能で120msごとに測定を行うということを示しています。データシートおよびこちらの参考情報より。

6. データの取得と通知

以上の情報を用いて、下記のようなコードをcronあたりに仕込んで定期的にオフィスの状況をslackに通知するようにします。

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

import requests
import json
import Adafruit_DHT
import smbus

def post_to_slack(text):
    payload = {
        "channel": "#xxxxx",
        "username": "raspi",
        "text": text,
        "iconemoji": ":ghost:"
    }
    headers = {'content-type': 'application/json'}
    requests.post("https://hooks.slack.com/services/XXXXX", data=json.dumps(payload), headers=headers)


def temperature_and_humidity():
    humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, 4)
    if humidity and temperature:
        return temperature, humidity
    else:
        return 0.0, 0.0

def lux():
    bus = smbus.SMBus(1)
    addr = 0x23

    try:
        lux = bus.read_i2c_block_data(addr, 0x11)
        return float(lux[1]* 10)
    except Exception as e:
        return 0.0

if __name__ == '__main__':
    t, h = temperature_and_humidity()
    l = lux()
    text = "おつかれさまです。ただいまの執務エリアは気温 {0} deg C, 湿度 {1} %, 明るさ {2} Lux です。定時だ。帰れ。残業される方はお仕事頑張ってください。".format(t, h, l)
    post_to_slack(text)

こんな感じになります。

f:id:hiroakis:20160209224201p:plain f:id:hiroakis:20160209224208p:plain

(丁寧語だったり乱暴だったりまだbotの人格が定まっていない...。)

7. メトリクス

さらにメトリクスも取ります。グラフ化には普段の業務でも使っているMackerelを用います。温度・湿度・光のグラフは、取得した値をMackerelのAPIにpostすることで生成します。ラズパイ自身の情報および監視はmackerel-agentで行います。ここでラズパイのCPUアーキはARMなので、下記のようにmackerel-agentがARMで動くようにクロスコンパイルするか、もしくはラズパイ上でビルドします。

gox -osarch=linux/arm

以下、グラフ化されたオフィスの状況です。

  • 温度

f:id:hiroakis:20160209224752p:plain

  • 湿度

f:id:hiroakis:20160209224804p:plain

f:id:hiroakis:20160209224758p:plain

グラフはこの記事を書こうと思った1月中頃のものです。トレタのオフィスの空調はビル管に管理されているからか、温度は人がいない時間帯でもわりと温かいですね。湿度は私の調べによると50%前後がちょうどよいらしいです。ちょっと低いですね...。光は...はんだごてがなくて輪ゴムつかったというやっつけ仕事なので的確かどうかわかりませんが、日の出/退社時間と一致しているので感知はできている模様です。

8. 今後

  • はんだごて を買う
  • 温度、湿度、光のしきい値に応じて何かアクションを起こすように。自動で加湿器のスイッチをいれるとかできたら面白いんだが...。水の供給まで自動化はできないかな...。
  • 海ぶどう(いけるか?w)

まだまだ妄想レベルですが。

9. 参考文献

最後に

お約束の文章を書かせていただきます...。トレタでは技術が好きな仲間を募集しています。トレタはBtoB向けの予約管理サービス*1で、平たく言ったらお店向けの業務アプリケーションです。業務アプリケーションと聞くと、堅そうな、味気ないような印象を受ける方もいるかもしれません。私自身もとはSIerやBtoCサービスの企業でキャリアを積みましたが、このようなBtoBサービスを自社で作るというのも味があっておもしろいですよ。これについては機会があったらまたこのブログにでも書こうかな、と思っています。なんでtoCからtoBに来たのか?なんでトレタに入ったのか?トレタの何がおもしろいのか?とか。

おわり

*1:インターネットでお店の予約ができるような機能を提供したり、一部toCのサービスもあります

© Toreta, Inc.

Powered by Hatena Blog