部室に温度センサーとかつけて監視する
(過去のblogから移動しました 元公開日時 2016-12-22 05:45:44)
こんにちは, KMC2回生のwass80です。
この記事はKMC Advent Calendar 2016 21日目の記事です.
昨日の記事はtronくんの「Neutron 買ってみたのは いいけれど……」でした。記事タイトルが575ですね。
明日の記事はbase64くんの「いい感じのメドレーを自動生成したい」です。自分がもやりたかったことやられたので, 後でいい感じコミットぜったいしたる。
今回はRaspberryPi3 ModelBを買ったので, 使って部室の監視をしたいと思います。
概略図
Raspberryにつながった温度センサーの値をfluentdでinfluxDBに送りつける。
grafanaでグラフを表示。
用意するもの
- Amazon
- 秋月
- 部室に落ちていたもの
- ブレッドボード
- オス-オスジャンプワイヤー
- microUSBケーブル
- 買い忘れたもの
- オス-メスのジャンプワイヤー
RasberryPi3はArduinoと違って, オス-メスのジャンプワイヤーが必要になるので注意しましょう。買い忘れました。
RasberryPi3
センサーをつなげて値を読み取りましょう。
セットアップ
Raspberry Pi 3を買ってMacを使ってWiFi接続とSSHの接続するまで
SDカードにRaspbianを焼いてRasberryPi3に差し込みます。
USBで電源を供給すれば起動します。HDMIで画面を見ます。
初期パスワードはuser:pi/pass:raspberryです。速やかに変更しましょう。
sshがデフォルトで無効になっているので有効化する必要があります。
Wifiでつながると便利なのでその設定もします。
温度センサー
第39回「ラズベリーパイで温度・湿度・気圧をまとめて取得!AE-BME280でIC2通信」
このセンサーにははんだ付けが必要です。
I²C方式シリアル通信をします。
上の記事通りに接続したら, I²Cを有効化します。
Github: SWITCHSCIENCE/BME280のコードを借りて(少し改変して)データを表示してみます。
t, p, h = readData()
print("気温:%f\t大気圧:%f\t湿度:%f" % (t, p, h))
pi@raspberrypi:~ $ python bme280/bme280.py
気温:19.729584 大気圧:1005.779496 湿度:56.260745
動いてそうです。
このデータを10秒おきに次のfluentdに送りつけましょう。
from fluent import sender
import time
logger = sender.FluentSender('raspi', host='sharp')
if __name__ == '__main__':
while True:
t, p, h = readData()
print("気温:%f\t大気圧:%f\t湿度:%f" % (t, p, h))
logger.emit('climate', {'temperature': t, 'pressure': p, 'humidity': h})
time.sleep(10)
systemd用のunitファイルを書きましょう。
#/etc/systemd/system/bme280.service
[Unit]
Description = bme280 climate sensor
[Service]
ExecStart = /home/pi/bme280/bme280.py
Restart = always
Type = simple
[Install]
WantedBy = multi-user.targe
$ sudo systemctl enable bme280
$ sudo systemctl start bme280
fluentd
ログの受け渡しをするサービス。
fluentdは Input → Filter → Output の経路でJSONのログ(event)を流します。
例えば, 以下のことができます。
- あるログファイルの書き込みを感知して(Input)
- それがErrorのログならば(Filter)
- Slackへ通知する(Output)
今回は以下の構成になります。
- TCPでログを受け取る(Input)
- そのすべてを(Filterなし)
- influxDBに送りつける(Output)
InputとFilterとOutputを結びつけるのは, ログに紐づくタグです。
Inputでログにタグを付け, 対応するFilter, Outputが動きます。
fluentdはすでに部室で動いていたので間借りします。
fluentdはデフォルトでTCPで受け取る以下のForward Inputが動いています。
#不要なコード
<source>
type forward
port 24224
bind 0.0.0.0
</source>
RaspberryPIからraspi.climate
タグをつけてfluentdに送っています。
#前述抜粋
logger = sender.FluentSender('raspi', host='sharp') #sharpはfluentdのあるサーバ名
logger.emit('climate', {'temperature': t, 'pressure': p, 'humidity': h})
なので以下の設定を追加します。
<match raspi.climate> #このタグであれば
@type copy #次のOutputそれぞれに受け渡す
<store> #ファイルに保存
@type file
path /var/log/td-agent/raspi/climate.log
</store>
<store> #influxdbに送りつける
@type influxdb
host 192.168.220.31
port 8086
dbname climate
user root
password root
use_ssl false
time_precision s
</store>
</match>
# matchは上からマッチし, マッチしたものがあればそれ以上マッチしない。
<match raspi.**> #上にマッチしなければ, 別のファイルに保存。
@type file
path /var/log/td-agent/raspi/raspi.log
</match>
今回はinfluxDBに送るついでにファイルにも保存していますが, DBを真面目に運用するなら必要ないでしょう。
influxDB
field/tagキーに値を時系列で突っ込んで行くデータベース。
「性別(∋男,女)」のように値の種類(=カーディナリティ)が少ないものはtagキー。
「気温=実数」のようにカーディナリティが高いものはfieldキーに指定します。
influxDBの準備にはdocker-composeを用いました。
参考: nicolargo/docker-influxdb-grafana
# docker-compose.yml
version: '2'
services:
influxdb:
image: influxdb:latest
ports:
- "8083:8083"
- "8086:8086"
env_file:
- 'env.influxdb'
volumes:
- influxdb-storage:/var/lib/influxdb
grafana:
image: grafana/grafana:latest
ports:
- "13000:3000"
links:
- influxdb
volumes:
- grafana-storage:/var/lib/grafana
environment:
- GF_SERVER_ROOT_URL=%(protocol)s://example.jp/~wass80/app/grafana
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
volumes:
influxdb-storage:
driver: local
grafana-storage:
driver: local
起動する。
$ docker-compose up -d
InfluxDB と fluentd を組み合わせを試してみた
データベースを作ればデータを受け取る準備が完了します。
influxDBのWebインターフェースはdeprecatedのようなので, 今回はCLIを用いました。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
791734f2cf3a grafana/grafana:latest "/run.sh" 8 hours ago Up 8 hours 0.0.0.0:13000->3000/tcp dockerinfluxdbgrafana_grafana_1
d39bac4136e8 influxdb:latest "/entrypoint.sh influ" 8 hours ago Up 8 hours 0.0.0.0:8083->8083/tcp, 0.0.0.0:8086->8086/tcp dockerinfluxdbgrafana_influxdb_1
$ docker exec -it d39 influx
Visit https://enterprise.influxdata.com to register for updates, InfluxDB server management, and monitoring.
Connected to http://localhost:8086 version 1.1.1
InfluxDB shell version: 1.1.1
> CREATE DATABASE climate
> SHOW databases
name: databases
name
----
_internal
climate
#fluentdの設定 前述抜粋
<store> #influxdbに送りつける
@type influxdb
host 192.168.220.31 # influxDBの動くサーバ
port 8086
dbname climate #データベース名
user root
password root
use_ssl false
time_precision s
</store>
これで{'temperature': t, 'pressure': p, 'humidity': h}
というfleid:値がinfluxdbに流れます。
Grafana
influxDBの内容をめっちゃかっこよく表示してくれるいい子。
先程のdocker-composeで一緒に起動していました。
今回はBasic認証がすでにかかっているところで動かすため, Grafanaの認証を無効化しています。
リバースプロキシ用の設定を環境変数に追加しています。
# docker-compose.yml (前述抜粋)
grafana:
image: grafana/grafana:latest
ports:
- "13000:3000"
links:
- influxdb
volumes:
- grafana-storage:/var/lib/grafana
environment:
- GF_SERVER_ROOT_URL=%(protocol)s://example.jp/~wass80/app/grafana
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
influxDBを登録しましょう。
GUIで設定できます。
あとはめっちゃいい感じGUIでグラフの設定をします。
いいですね。
できました。
凡例の色付き横線を押すと色の変更と軸の左右の変更ができます。
他にも色々センサーを買いましたが, RaspberryPIがアナログ入出力が出来ないことを知りませんでした。A-D変換を買ってきます。
明日の記事をお楽しみに。