jimaoka blog

ライトなインフラエンジニアです

Raspberry Pi で温湿度・光量を取得してグラフ化する

f:id:jimaoka:20160619184251j:plain

目次

はじめに

最近暑くなってきたので、一体この部屋は何度あるのだろうと思い、室温が知りたくなってきます。 温度計を買おうかとも思いつつ、やはり時間的な推移を見たいので、Raspberry Piでグラフを表示してみることにしました。

(たぶん) 巷でよくあるRaspberry Piでセンサ値を取ったりしてグラフを出すやつです。

  • 温度(℃) 、湿度(%)、輝度(lux)

を取得して、こんな感じでグラフ化するところまでやります。

f:id:jimaoka:20160621215948p:plain

必要なもの

けっこうたくさんありますが、必要なものリストです。

ブレッドボード周辺のセットアップ

まず、BH1750は回路にピンがついていない為、はんだで取り付けます。 (下の画像は付けたあとのものです)

f:id:jimaoka:20160620225119j:plain

配線図を参考にブレッドボードにセンサやジャンパー線を刺していきます。
(2つとも1つのラズパイに繋いで書いたらごちゃごちゃになったので分けてます、間にある抵抗は10kΩです)

f:id:jimaoka:20160619233349p:plain

かなり参考にならなさそうですが、実物はこんな感じになっています。

f:id:jimaoka:20160619212521j:plain

Raspberry Piのセットアップ

Download Raspbian for Raspberry Pi より、Raspbianの最新版をダウンロードしてきます。 (今回はコマンドラインのみを想定しているため、RASPBIAN JESSIE LITEを選択)

Mac上で作業を行っていきます。

SDカードを挿したら、適当に中身をフォーマットします。(FAT32)

f:id:jimaoka:20160619192002p:plain

### /dev/disk2 で認識されていることが分かる
% diskutil list
/dev/disk0 (internal, physical):
..
/dev/disk1 (internal, virtual):
..
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *32.2 GB    disk2
   1:                        EFI EFI                     209.7 MB   disk2s1
   2:       Microsoft Basic Data RASPBERRYPI             32.0 GB    disk2s2
 
### アンマウントする
% diskutil umountDisk /dev/disk2
Unmount of all volumes on disk2 was successful
 
### 書き込み(かなり時間がかかる)
% sudo dd bs=1m if=~/Desktop/2016-05-27-raspbian-jessie-lite.img of=/dev/disk2
Password:
1323+0 records in
1323+0 records out
1387266048 bytes transferred in 1044.634431 secs (1327992 bytes/sec)

書き込み終わったら、Macから抜いてRaspberry PiにSDを挿します。

SDを挿したら、LANケーブルとMicroUSBケーブルをさして電源を入れます。

f:id:jimaoka:20160619211612j:plain

Macからであれば、このままBonjourでいい感じに接続できます。

### ユーザ名は"pi"で、初期パスワードは"raspberry"
% ssh -l pi raspberrypi.local
pi@raspberrypi.locals password:
 
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
 
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
pi@raspberrypi:~ $
 
### SDカード容量の最適化
$ sudo raspi-config
「1 Expand Filesystem」 → 「Yes」

### タイムゾーン変更
$ sudo raspi-config
「5 Internationalisation Options」 → 「I2 Change Timezone」 → 「Asia」 → 「Tokyo」

$ sudo reboot
値の読み取り

まずは温湿度センサから

### 必要なものをインストール
$ sudo apt-get update
$ sudo apt-get install build-essential python-dev git vim
 
### DHTセンサ用ライブラリをインストール
$ git clone https://github.com/adafruit/Adafruit_Python_DHT.git
$ cd Adafruit_Python_DHT/
$ sudo python setup.py install
 
### pythonから値を読み込む
$ cd ..
$ vim getHumTemp.py
# coding: utf-8
import Adafruit_DHT
 
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, 4)
print "温度: " + str(temperature) + ", 湿度: " + str(humidity)
$ sudo python getHumTemp.py
温度: 24.0, 湿度: 46.0

輝度センサ

### SPI有効化
$ sudo raspi-config
「9 Advanced Options」 → 「A5 SPI」 → 「SPI enable### I2C有効化
$ sudo raspi-config
「9 Advanced Options」 → 「A6 I2C」 → 「I2C enable### モジュールの読み込み設定
$ sudo vim /etc/modules
snd-bcm2835
i2c-dev
 
### 必要なものをインストール
$ sudo apt-get install python-smbus i2c-tools libi2c-dev
 
### アドレスの確認
$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --
 
### 値の読み取り
$ vim getLux.py
# coding: utf-8
import smbus
 
bus = smbus.SMBus(1)
addr = 0x23
lux = bus.read_i2c_block_data(addr,0x10)

print "輝度: " + str((lux[0]*256+lux[1])/1.2)
$ sudo python getLux.py
輝度: 571.666666667
Focuslightのセットアップ

セットアップが簡単そうな、Focuslightというグラフツールを使用してグラフを描いていきます。

Focuslight - Lightning fast Graphing / Visualization

Ruby2.0以上が必要とのことなので、rbenvでRuby環境のセットアップを行います。 (あとで見たら、aptでインストールできるRubyが2.1だったのでそちらで十分だった・・)

### システム全体でインストールする
$ sudo su
root$ apt-get install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm3 libgdbm-dev
root$ git clone https://github.com/sstephenson/rbenv.git /usr/local/rbenv
root$ git clone https://github.com/sstephenson/ruby-build.git /usr/local/rbenv/plugins/ruby-build
root$ vim /etc/profile.d/rbenv.sh
export RBENV_ROOT=/usr/local/rbenv
export PATH="/usr/local/rbenv/shims:/usr/local/rbenv/bin:$PATH"
eval "$(rbenv init -)"
root$ visudo
- Defaults        env_reset
- Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
+ Defaults        env_keep +=  "PATH"
root$ source /etc/profile.d/rbenv.sh
root$ which rbenv
/usr/local/rbenv/bin/rbenv
root$ rbenv install 2.2.5
Downloading ruby-2.2.5.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.5.tar.bz2
Installing ruby-2.2.5...
Installed ruby-2.2.5 to /usr/local/rbenv/versions/2.2.5
root$ rbenv global 2.2.5
root$ ruby -v
ruby 2.2.5p319 (2016-04-26 revision 54774) [armv7l-linux-eabihf]
root$ exit
$ source /etc/profile.d/rbenv.sh
$ ruby -v
ruby 2.2.5p319 (2016-04-26 revision 54774) [armv7l-linux-eabihf]

そしてFocuslightのセットアップを行っていきます。

### 必要なパッケージのインストール
$ sudo apt-get install rrdtool libmysqlclient-dev librrd-ruby librrd4 librrd-dev libsqlite3-dev sqlite3
 
### bundler
$ sudo gem install bundler
 
### bundle install
$ git clone https://github.com/tagomoris/focuslight.git
$ cd focuslight
$ bundle
$ bundle exec focuslight init

### 小数も受け付けるようにする
$ vim .env
- FLOAT_SUPPORT=n # y
+ FLOAT_SUPPORT=y

### 開始
$ bundle exec focuslight start
16:16:51 web.1     | started with pid 31225
16:16:51 worker1.1 | started with pid 31226
16:16:51 worker2.1 | started with pid 31227
16:16:54 web.1     | I, [2016-06-19T16:16:54.676882 #31225]  INFO -- : listening on addr=0.0.0.0:5125 fd=13
16:16:54 web.1     | I, [2016-06-19T16:16:54.677595 #31225]  INFO -- : worker=0 spawning...
16:16:54 web.1     | I, [2016-06-19T16:16:54.681587 #31225]  INFO -- : master process ready
16:16:54 web.1     | I, [2016-06-19T16:16:54.686755 #31235]  INFO -- : worker=0 spawned pid=31235
16:16:54 web.1     | I, [2016-06-19T16:16:54.688837 #31235]  INFO -- : Refreshing Gem list
16:16:57 web.1     | I, [2016-06-19T16:16:57.171210 #31235]  INFO -- : worker=0 ready

http://raspberrypi.local:5125 にアクセスする。

f:id:jimaoka:20160620011938p:plain

値の送信

ここまできたら、focuslightを起動している状態で、スクリプトによりデータ送信を行っていきます。

### 値の送信スクリプトの作成
$ sudo vim /usr/local/bin/sendSendorValues.py
# coding: utf-8
import Adafruit_DHT
import smbus
import commands
 
# Get Lux
bus = smbus.SMBus(1)
addr = 0x23
lux = bus.read_i2c_block_data(addr,0x10)
 
# Get Humidity and Temperature
humidity, temperature = Adafruit_DHT.read_retry(Adafruit_DHT.DHT11, 4)
 
# Throw data to Focuslight
output = commands.getoutput("curl -F number=" + str((lux[0]*256+lux[1])/1.2) + " http://localhost:5125/api/home/sensor/lux")
print output
output = commands.getoutput("curl -F number=" + str(humidity) + " http://localhost:5125/api/home/sensor/humidity")
print output
output = commands.getoutput("curl -F number=" + str(temperature) + " http://localhost:5125/api/home/sensor/temperature")
print output
 
### 動作確認
$ sudo /usr/bin/python /usr/local/bin/sendSendorValues.py
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   542  100   397  100   145    386    141  0:00:01  0:00:01 --:--:--   386
{"error":0,"data":{"id":4,"service_name":"home","section_name":"sensor","graph_name":"lux","number":1450,"description":"","sort":0,"created_at":"2016/06/20 14:49:39","updated_at":"2016/06/20 14:52:25","mode":"gauge","color":"#99cc66","ulimit":1.0e+15,"llimit":-1000000000.0,"type":"AREA","adjust":"*","adjustval":"1","unit":"","complex":false,"md5":"a87ff679a2f3e71d9181a67b7542122c","meta":null}}
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   545  100   400  100   145    387    140  0:00:01  0:00:01 --:--:--   387
{"error":0,"data":{"id":5,"service_name":"home","section_name":"sensor","graph_name":"humidity","number":43,"description":"","sort":0,"created_at":"2016/06/20 14:49:40","updated_at":"2016/06/20 14:52:26","mode":"gauge","color":"#cc6699","ulimit":1.0e+15,"llimit":-1000000000.0,"type":"AREA","adjust":"*","adjustval":"1","unit":"","complex":false,"md5":"e4da3b7fbbce2345d7772b0674a318d5","meta":null}}
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   548  100   403  100   145    391    140  0:00:01  0:00:01 --:--:--   392
{"error":0,"data":{"id":6,"service_name":"home","section_name":"sensor","graph_name":"temperature","number":26,"description":"","sort":0,"created_at":"2016/06/20 14:49:41","updated_at":"2016/06/20 14:52:27","mode":"gauge","color":"#9933cc","ulimit":1.0e+15,"llimit":-1000000000.0,"type":"AREA","adjust":"*","adjustval":"1","unit":"","complex":false,"md5":"1679091c5a880faf6fb5e6087eb1b2dc","meta":null}}
 
### crontabに追記 (毎分実行するように設定)
$ sudo vim /etc/crontab
...
+ * * * * * root /usr/bin/python /usr/local/bin/sendSendorValues.py
 
### cronの再読み込み
$ sudo service cron rload
[ ok ] Reloading configuration files for periodic command scheduler: cron.

cronに登録してしばらく置いておくと徐々にグラフができてきます・・!

f:id:jimaoka:20160620235602p:plain

まとめ

一日置いておくとこんな感じになりました。

今のところ温度や湿度をしきい値にしてアクションを起こす等は考えてないですが、快適な温度や湿度を考えるのには役立ちそうです。また今後もセンサを取り付けてほかのパラメータも取っていけると思うので、どんどん増やしていきたいと思っています。

f:id:jimaoka:20160621220137p:plain

参考文献

Zabbixに送信する (2017/1/5 追記)

最近自宅用のZabbixサーバの構築も行ったため、Zabbixのグラフで描画してみることにしました。

### zabbix-agentのインストール
$ sudo apt-get install zabbix-agent

### 送信スクリプトの変更
$ sudo vim /usr/local/bin/sendSendorValues.py
+ # Throw data to Zabbix
+ output = commands.getoutput("zabbix_sender -z zabbix.jimaoka.com -s \"raspberry.jimaoka.com\" -k environment.lux -o" + str((lux[0]*256+lux[1])/1.2))
+ print output
+ output = commands.getoutput("zabbix_sender -z zabbix.jimaoka.com -s \"raspberry.jimaoka.com\" -k environment.humidity -o" + str(humidity))
+ print output
+ output = commands.getoutput("zabbix_sender -z zabbix.jimaoka.com -s \"raspberry.jimaoka.com\" -k environment.temperature -o" + str(temperature))
+ print output

送信されたデータをZabbixTrapperで取り、スクリーンなどで表示

f:id:jimaoka:20170105191906p:plain

f:id:jimaoka:20170105191919p:plain

これでセンサーデータを見てアラートを上げることもできそうです。