InfluxDBとGrafanaでエアコンの消費電力や各種センサデータを可視化する
記録したデータをグラフ化して、時間軸とか色々自由に調整してみたい!
と思い立ち、収集した時系列データをInfluxDBに保管して、Grafanaでインタラクティブなグラフとして可視化してみました。
エアコンの消費電力や室内の温湿度・気圧・照度などを24時間記録して表示できる環境が整い、こんな感じで状況を確認できるようになります(・∀・)
はじめに
時系列データのデータベース登録と可視化について
ここの部分は背景なので、やり方がわかれば良いのだよ!という方はすっ飛ばして次の項目にどうぞ^^
以前の記事のように、一定時間毎に収集された時系列のデータをファイルに保存して、Java ScriptやPHPなどを使ってグラフを作るのは簡単にできるので入門にはオススメです。ただ、何日も、何時間も記録したデータの好きなところを見るには少々手間がかかります。
データの保管はCSV形式のファイルとして保存する以外に、MySQLなどのデータベースに登録する方法があります。
ファイルに保存するより一手間かかりますが、データベースに入れてしまいさえすれば、SQL文で簡単にデータの操作ができるようになります。
ただし、MySQLなどのリレーショナルデータベースは最初から構造をしっかり決めておかないといけなかったり、大量の時系列データの処理には結構な手間がかかったりするので、情報収集系のようにどんどん変化するシステムに使うにはちょっと敷居が高いものでした。
そこで登場するのが「InfluxDB」です!
詳しい話はGoogle先生に聞けばいくらでも出てくるのでここでは割愛しますが、時系列データの扱いにとても優れたデータベースであるというのがポイントです。
そして、時系列データを格好良く表示してくれるのが「Grafana」です。ここも詳細は割愛!
全体の流れとしてはこうです。
《各種センサ: データ》
↓
《InfluxDB: 時系列データベース》
↓
《Grafana:可視化》
今回は全て同じRaspberry Pi 3B+上で動かしますが、それぞれ別のシステムで動かす事もできます。
前回までに「データ」はできているので、残りの「時系列データベース」と「可視化」の方法を紹介します。
使ったモノ
- Raspberry Pi 3B+、Raspbian Stretch、
- InfluxDB v1.0.2
- Grafana v5.2.2
実行環境
[highlight_bash]$ uname -a
Linux rpi3-03p 4.14.62-v7+ #1134 SMP Tue Aug 14 17:10:10 BST 2018 armv7l GNU/Linux[/highlight_bash]
センサなどの情報は以下の記事をご参照ください。
時系列データベース InfluxDB のインストール
influxdata社のページ(https://www.influxdata.com/blog/running-the-tick-stack-on-a-raspberry-pi/)を参考に、インストールします。
まずは、公式のInfluxData Repositoryを使えるようにします。
OSのバージョンによって設定内容が違ってくるので、初めに確認しておきましょう。
[highlight_bash]$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9″
VERSION="9 (stretch)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"[/highlight_bash]
※ちなみに、公式情報はファイル名を間違えている(/etc/os-releasesになっている)のでそのままコピペしてもダメです。
次に、GPG key を追加します。
[highlight_bash]$ curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add –
OK
$ echo “deb https://repos.influxdata.com/debian stretch stable" | sudo tee /etc/apt/sources.list.d/influxdb.list
deb https://repos.influxdata.com/debian stretch stable
[/highlight_bash]
念のため確認
[highlight_bash]$ cat /etc/apt/sources.list.d/influxdb.list
deb https://repos.influxdata.com/debian stretch stable[/highlight_bash]
今回はInfluxDBだけインストールします。
[highlight_bash]$ sudo apt install influxdb[/highlight_bash]
※関連するソフトウェアを一式入手すると、データ収集から可視化、データ処理までできるので凄いのですが、これはまた後日。
- telegraf 時系列データの収集
- chronograf 時系列データの可視化
- kapacitor 時系列データのデータ処理
インストールが終わったら、自動的に起動していると思うので確認します。
[highlight_bash]$ systemctl status influxdb
● influxdb.service – InfluxDB is an open-source, distributed, time series database
Loaded: loaded (/lib/systemd/system/influxdb.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2018-08-25 17:16:26 JST; 3min 14s ago[/highlight_bash]
無事に起動していました!
InfluxDB WebUIの動作確認
コチラのサイトの情報を参考に動作確認を行います。
Webブラウザで「http://{HostName}.local:8083」 にアクセスします。
※{HostName}の所には、InfluxDBをインストールしたラズベリーパイのホスト名を入れてください。
以下のようなページが出てきたら、クエリ入力欄に「SHOW DATABASES」と打ち込んでEnter!
クエリも受け付けてくれました。
※最初は何も無いので「Successful」と出ていればOKです。
データベースの操作を人が手動で行う場合には、このWebベースのユーザーインターフェイスを使うと便利です。
InfluxDB APIの動作確認
プログラムからデータベースを操作できるようにAPIが用意されています。
ラズパイにsshでログインした状態で、以下のcurlコマンドを実行して204が返ってくるか確認します。
※pingにアクセスすることで、データベースにアクセスできるか確認できます。
[highlight_bash]$ curl -sl -I http://localhost:8086/ping
HTTP/1.1 204 No Content
Content-Type: application/json
Request-Id: 31f45640-a841-11e8-8003-000000000000
X-Influxdb-Version: 1.0.2
Date: Sat, 25 Aug 2018 08:30:59 GMT[/highlight_bash]
次に、API経由でクエリ(q=SHOW DATABASES)を受け付けてくれるか確認します。
[highlight_bash]$ curl http://localhost:8086/query –data-urlencode “q=SHOW DATABASES"[/highlight_bash]
こんな感じで応答(JSON形式のデータ)が返ってきたらOKです!
[highlight_bash]{“results":[{“series":[{“name":"databases","columns":[“name"],"values":[[“_internal"]]}]}]}[/highlight_bash]
InfluxDBにデータベースを作成する
APIの動作が確認できたので、データベースを作ってデータを投げ入れてみます。
データベースを作るには、「CREATE DATABASE」を使います。
[highlight_bash]$ curl -i -XPOST http://localhost:8086/query –data-urlencode “q=CREATE DATABASE ${dbName}"[/highlight_bash]
ここで、${dbName}には作成したいデータベース名を指定してください。
例として「testdb」を作る場合はコチラ。
[highlight_bash]$ curl -i -XPOST http://localhost:8086/query –data-urlencode “q=CREATE DATABASE testdb"
HTTP/1.1 200 OK
Connection: close
Content-Type: application/json
Request-Id: be46bdbe-a84c-11e8-8005-000000000000
X-Influxdb-Version: 1.0.2
Date: Sat, 25 Aug 2018 09:53:39 GMT
Transfer-Encoding: chunked
{“results":[{}]}[/highlight_bash]
InfluxDBのデータベースにデータを登録してみる
データベースができたので、データを登録してみます。
※データ構造についてはコチラのサイトが凄くわかりやすいです。
ラインプロトコル(https://docs.influxdata.com/influxdb/v1.6/write_protocols/line_protocol_reference/)にも目を通しておくことをオススメします。
curlを使った登録の例です。
[highlight_bash]$ curl -i -XPOST “http://localhost:8086/write?db=${dbName}" –data-binary '${measName},${tag1}=${tagStr} ${fieldName}=${value} ${timestamp}'[/highlight_bash]
ここで、
- ${dbName} … データベース名
- ${measName} … Measurement名(〜の計測、というタイトル的な位置づけだとするとわかりやすい。)
- ${tag1} … タグ名(なんでも良いのでとりあえずtag1とした。WordPressのタグ付けと同じようなイメージ。)
- ${tagStr} … タグの値(文字列のみ。例えばhardwareというタグを作って、値を「RPi3B+」にするとか。)
- ${fieldName} … フィールド名(計測するデータ名。例えば電力を記録するために「watt」とか。)
- ${value} … フィールドの値(計測するデータの値。int/float/string/booleanを指定可能。)
- ${timestamp} … 時刻。エポック時間やRFC3339形式で指定。未指定だとシステムの時刻が使われます。また、プレシジョンオプションを指定しない場合はナノ秒になります。
ザックリと投げ入れるデータの構造(ラインプロトコル)をイメージ化するとこんな感じ。()と()の間はスペース。
[highlight_bash]{(measName,(tag1=T1,…)) (fieldName=value,f2=V2,…) (timestamp)}[/highlight_bash]
ということで、試しに投げてみた結果はコチラ。
[highlight_bash]$ curl -i -XPOST “http://localhost:8086/write?db=testdb" –data-binary 'Environment,hard=RasPi3B+ Temperature=39.2 1535191201003004005′[/highlight_bash]
時刻指定無しの場合はこのように書けます。
[highlight_bash]$ curl -i -XPOST “http://localhost:8086/write?db=testdb" –data-binary 'Environment,hard=RasPi3B+ Temperature=39.1′[/highlight_bash]
時刻を秒単位で設定するには、precision=sを追加します。
[highlight_bash]$ curl -i -XPOST “http://localhost:8086/write?db=testdb&precision=s" –data-binary 'Environment,hard=RasPi3B+ Temperature=39.1′[/highlight_bash]
登録されたデータを見てみましょう。
※pretyを指定することで整形されたJSONデータとして表示されます。
[highlight_bash]$ curl -G 'http://localhost:8086/query?db=testdb&pretty=true' --data-urlencode 'q=SELECT * FROM Environment' { "results": [ { "series": [ { "name": "Environment", "columns": [ "time", "Temperature", "hard" ], "values": [ [ "2018-08-25T10:00:01.003004005Z", 39.2, "RasPi3B+" ], [ "2018-08-25T10:02:25.065656514Z", 39.1, "RasPi3B+" ] ] } ] } ] } [/highlight_bash]
超簡単!!
InfluxDBの接続設定
データベースに接続する時の設定をWebのUIから行います。
「http://{HostName}.local:8083」にアクセスして、右上の歯車をクリックすると「Connection Settings」が表示されます。
ここの「Username」と「Password」を入力して、「Save」ボタンを押して完了です。
InfluxDBのカスタマイズ(SDカードの延命対策)
頻繁にSDカードに書き込んでいるとすぐに寿命が来そうなので、データの保存場所を外付けのSSDに変更します。
※ラズベリーパイに外付けのSSDを接続する方法はコチラを参照
まず、influxbを停止します。
[highlight_bash]$ sudo systemctl stop influxdb[/highlight_bash]
設定ファイルのバックアップを取ります。
[highlight_bash]$ sudo cp /etc/influxdb/influxdb.conf /etc/influxdb/influxdb.conf.org[/highlight_bash]
データの保存先指定カ所は以下の通りです。
[highlight_bash]$ cat /etc/influxdb/influxdb.conf |grep dir | grep -v -e ^#
dir = “/var/lib/influxdb/meta"
dir = “/var/lib/influxdb/data"
wal-dir = “/var/lib/influxdb/wal"[/highlight_bash]
この/var/lib/influxdb を外付けSSDに変更します。
まずはSSDに場所を確保します。
[highlight_bash]$ sudo mkdir -p /mnt/ex-ssd/var/lib
$ sudo mkdir -p /mnt/ex-ssd/var/log[/highlight_bash]
ファイルをコピー。pオプションを忘れるとデーモン起動時にエラーになるので注意!
[highlight_bash]$ sudo cp -pr /var/lib/influxdb /mnt/ex-ssd/var/lib/[/highlight_bash]
設定ファイルを編集します。先ほどのdirで指定されている部分をSSDに変更します。
[highlight_bash]$ sudo vim /etc/influxdb/influxdb.conf
dir = “/mnt/ex-ssd/var/lib/influxdb/meta"
dir = “/mnt/ex-ssd/var/lib/influxdb/data"
wal-dir = “/mnt/ex-ssd/var/lib/influxdb/wal"[/highlight_bash]
変更カ所の比較
[highlight_bash]$ diff -u /etc/influxdb/influxdb.conf.org /etc/influxdb/influxdb.conf
— /etc/influxdb/influxdb.conf.org 2018-08-26 12:07:16.911577768 +0900
+++ /etc/influxdb/influxdb.conf 2018-08-26 12:32:38.294734918 +0900
@@ -20,7 +20,8 @@
[meta]
# Where the metadata/raft database is stored
– dir = “/var/lib/influxdb/meta"
+# dir = “/var/lib/influxdb/meta"
+ dir = “/mnt/ex-ssd/var/lib/influxdb/meta"
retention-autocreate = true
@@ -44,10 +45,12 @@
# Controls if this node holds time series data shards in the cluster
enabled = true
– dir = “/var/lib/influxdb/data"
+# dir = “/var/lib/influxdb/data"
+ dir = “/mnt/ex-ssd/var/lib/influxdb/data"
# These are the WAL settings for the storage engine >= 0.9.3
– wal-dir = “/var/lib/influxdb/wal"
+# wal-dir = “/var/lib/influxdb/wal"
+ wal-dir = “/mnt/ex-ssd/var/lib/influxdb/wal"
wal-logging-enabled = true
# Trace logging provides more verbose output around the tsm engine. Turning[/highlight_bash]
編集が終わったらInfluxDBを再起動します。
[highlight_bash]$ sudo systemctl daemon-reload
$ sudo systemctl start influxdb
$ systemctl status influxdb[/highlight_bash]
以上でInfluxDBの初期設定は完了です。
Grafanaのインストール
データを可視化(グラフで表示)するためにGrafana(v5.2.2)を使えるようにしていきます。
公式サイトの情報に基づいて、ARMv7のパッケージを使ってインストールします。
パッケージをダウンロードしてインストールします。
[highlight_bash]$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana_5.2.2_armhf.deb
$ sudo dpkg -i grafana_5.2.2_armhf.deb[/highlight_bash]
デーモンをリロードしてgrafanaをEnable&起動します。
[highlight_bash]$ sudo systemctl daemon-reload
$ sudo systemctl enable grafana-server
$ sudo systemctl start grafana-server[/highlight_bash]
ステータスを確認して、active (running) になっていればOK!
[highlight_bash]$ systemctl status grafana-server
● grafana-server.service – Grafana instance
Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2018-08-25 16:29:43 JST; 7s ago[/highlight_bash]
ssコマンドを使って3000番ポートが待ち受け状態になっているか確認しておきます。
[highlight_bash]$ ss -lntp|grep 3000
LISTEN 0 128 :::3000 :::*[/highlight_bash]
Grafanaの初期設定
WebブラウザでGrafanaをインストールしたラズパイに接続します。
http://{HostName}.local:3000/
httpなので「Webサイトは安全ではありません」と出ていますが、ローカル環境なのでとりあえずよしとします。
初期アカウント/パスワード(admin/admin)でログインします。
すぐに新しいパスワードへの変更が求められますので、強いパスワードを設定しておきましょう。
(ローカル環境でも手を抜かない!)
ダッシュボードの作成
ダッシュボードに表示するデータベースを登録します。
「Add data source」をクリックして以下のように入力して行きます。
入力し終わったら「Save & Test」を押して、「Data source is working」と表示されたら完了です。
次に、左側のメニューからCreate > Dashboard > Add Panel > Graph を選択します。
パネルのタイトルをクリックするとメニューが出てくるので、「Edit」を選択します。
「Metrics」のタブで、データソースやデータの取得方法(クエリ)等を設定します。
※黒い画面は目がチカチカするので、設定を変えて白背景にしています。
これでデータが表示されると思います。
No data points と表示されたときの対処法
ブラウザのキャッシュの影響でパネルに配置したグラフの設定そのものができなくなる場合があります(これでしばらくハマりました)
ブラウザを一旦終了して再度読み込むか、キャッシュをクリアしてアクセスしてみてください。
また、データ数が少ないと「実は見えていないだけ」という事もあります。
そんな時は、グラフを選択してEdit > Display > Draw Modes の「Points」にチェックを入れると見えるかもしれません。
Grafanaのデータ保存先を変える(SDカードの延命対策)
InfluxDBの時と同様に外付けSSDに変更します。
まずはGrafanaを停止します。
[highlight_bash]$ sudo systemctl stop grafana-server && systemctl status grafana-server[/highlight_bash]
データをコピーします。
[highlight_bash]$ sudo cp -pr /var/lib/grafana /mnt/ex-ssd/var/lib/grafana
$ sudo cp -pr /var/log/grafana /mnt/ex-ssd/var/log/grafana[/highlight_bash]
保存先を変える方法(うまくいかなかった方、成功例はこの後)
/etc/grafana/grafana.ini の中に、[paths]というエントリーがあるので、同様に外付けディスクを指定していきます。
コピーを取って、以下のように変更します。
[highlight_bash]$ sudo cp /etc/grafana/grafana.ini /etc/grafana/grafana.ini.org[/highlight_bash]
[highlight_bash][paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
;data = /var/lib/grafana
data = /mnt/ex-ssd/var/lib/grafana
# Directory where grafana can store logs
;logs = /var/log/grafana
logs = /mnt/ex-ssd/var/log/grafana
# Directory where grafana will automatically scan and look for plugins
;plugins = /var/lib/grafana/plugins
plugins = /mnt/ex-ssd/var/lib/grafana/plugins[/highlight_bash]
状態を確認します。
[highlight_bash]$ sudo systemctl daemon-reload
$ sudo systemctl start grafana-server && systemctl status grafana-server[/highlight_bash]
が、しかし、、、保存先が変わっていない、、だと?
[highlight_bash]$ systemctl status grafana-server
● grafana-server.service – Grafana instance
Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2018-08-26 13:00:48 JST; 4min 20s ago
Docs: http://docs.grafana.org
Main PID: 390 (grafana-server)
CGroup: /system.slice/grafana-server.service
└─390 /usr/sbin/grafana-server –config=/etc/grafana/grafana.ini –pidfile=/var/run/grafana/grafana-server.pid cfg:default.paths.logs=/var/log/grafana cfg:default.paths.data=/var/lib/grafana[/highlight_bash]
ぐぬぬぬぬ、、、
保存先を変える方法(成功例)
設定ファイルを修正しても保存先が変わらず、コンチクショー!と思いながら/etc/を漁っていたら、defaultの中にgrafana-serverなるエントリーを発見!
[highlight_bash]$ cat /etc/default/grafana-server[/highlight_bash]
Google先生に改めて聞いてみたところ、ここにデフォルト設定がありそちらを参照している模様
(http://docs.grafana.org/installation/debian/)
バックアップを取ってからこちらを編集します。
[highlight_bash]$ sudo cp /etc/default/grafana-server /etc/default/grafana-server.org[/highlight_bash]
[highlight_bash]$ diff -u /etc/default/grafana-server.org /etc/default/grafana-server
— /etc/default/grafana-server.org 2018-08-26 13:13:09.082992464 +0900
+++ /etc/default/grafana-server 2018-08-26 13:13:53.082519805 +0900
@@ -4,9 +4,9 @@
GRAFANA_HOME=/usr/share/grafana
-LOG_DIR=/var/log/grafana
+LOG_DIR=/mnt/ex-ssd/var/log/grafana
-DATA_DIR=/var/lib/grafana
+DATA_DIR=/mnt/ex-ssd/var/lib/grafana
MAX_OPEN_FILES=10000
@@ -16,7 +16,7 @@
RESTART_ON_UPGRADE=true
-PLUGINS_DIR=/var/lib/grafana/plugins
+PLUGINS_DIR=/mnt/ex-ssd/var/lib/grafana/plugins
PROVISIONING_CFG_DIR=/etc/grafana/provisioning[/highlight_bash]
書き換えが完了したら、サービスを再起動してステータスを確認します。
[highlight_bash]$ sudo systemctl restart grafana-server && systemctl status grafana-server
● grafana-server.service – Grafana instance
Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2018-08-26 13:15:31 JST; 4s ago
Docs: http://docs.grafana.org
Main PID: 1304 (grafana-server)
CGroup: /system.slice/grafana-server.service
└─1304 /usr/sbin/grafana-server –config=/etc/grafana/grafana.ini –pidfile=/var/run/grafana/grafana-server.pid cfg:default.paths.logs=/mnt/ex-ssd/var/log/grafana cfg:default.paths.data=/mnt/[/highlight_bash]
無事に外付けSSDに変更されていました!
これでGrafanaの初期設定は完了です。
データを投げるスクリプトを作成する
それでは、収集した環境モニタリングデータをInfluxDBに登録するスクリプトを作っていきましょう。
まず、InfluxDBのWebUIにアクセスしてデータベースを作成します。
CREATE DATABASE “db_mon2018"
データはこのような形で保管しようと思います。
- Environment
node=rpi1- T1(温度)
- H1(湿度)
- L1(照度)
- P1(気圧)
- Power
node=rex1
device=Aircon1- V(電圧)
- I(電流
- W(電力)
Environmentに登録するときはこのようにします。
[highlight_bash]curl -i -XPOST “http://localhost:8086/write?db=db_env2018&precision=s" –data-binary 'Environment,node=rpi1 T1=${t1},H1=${h1},L1=${l1},P1=${p1} ${timestamp}'[/highlight_bash]
最初はフィールドの型指定も含めて手動で書込みテストをしておきます。
[highlight_bash]curl -i -XPOST “http://localhost:8086/write?db=db_mon2018&precision=s" –data-binary 'Environment,node=rpi1 T1=30.0,H1=60.0,L1=100.0,P1=1010.0′[/highlight_bash]
※最初のデータ登録でフィールドの型が自動的に決まってしまいます。最初に「30」などの整数値を送ってしまうと、後から「30.1」などの小数を含む値を投げたときにエラーになるのでご注意下さい。
pythonで温度・湿度・大気圧・照度のデータを投げる
温度・湿度・大気圧・照度センサのデータ読み取りはpythonで行っています。
InfluxDBにはpythonのクライアントが用意されているのでそれを使っていきます。
https://github.com/influxdata/influxdb-python
まずはインストールから。
[highlight_bash]$ sudo apt install python3-influxdb[/highlight_bash]
データを投げるスクリプトはこんな感じで。
[highlight_bash] # coding: utf-8 from datetime import datetime,timedelta,timezone from influxdb import InfluxDBClient def write_db(user,passwd,dbname,node,time,t1,h1,l1,p1): json_body = [ { "measurement": "Environment", "tags": { "node": "rpi1" }, "time": time, "fields": { "T1": t1, "H1": h1, "L1": l1, "P1": p1 } } ] print(json_body) client = InfluxDBClient('localhost', 8086, user, passwd, dbname) client.write_points(json_body) if __name__ == '__main__': datestr = datetime.now(timezone(timedelta(hours=+0), 'GMT')).strftime('%Y-%m-%dT%H:%M:%SZ') write_db(user='root',passwd='**********',dbname='db_mon2018',node='rpi1',time=datestr,t1=30.1,h1=60.0,l1=100.0,p1=1010.0) [/highlight_bash]
これを適当なファイルに保存して元になる「rpz_sensor.py」から呼び出して使います。
write_db()に与える引数は、適宜センサの値を割り当てて下さい。
(追記)2018-11-30、rpz_sensor.py の変更部分
具体的にどのように変更するか教えて欲しいというコメントいただきましたので追加しました。なお、こちらの記事に書いてある内容を実施していることを前提とします。
それでは早速本題に。わかりやすいようにrpz_sensor.pyに直接追記する方法を示します。
やっていることは、元のプログラムにいくつかimport文とwrite_db()を追加、そして新しく「“-d"オプション」を追加して、センサ値を直接表示する代わりにwrite_db()の引数として与えるようにしています。変更したファイルはrpz_sensor_db.pyとしました。rpz_sensor.pyとの差分は以下の通りです。
【注】データベース名(dbname)やrootのパスワード(password)は、適宜ご自身の環境に合わせて修正してください。
[highlight_python] --- rpz_sensor.py 2018-08-08 23:24:53.633412101 +0900 +++ rpz_sensor_db.py 2018-11-28 00:18:08.593243001 +0900 @@ -1,14 +1,16 @@ #!/usr/bin/env python3 +# coding: utf-8 """ RPZ-IR-Sensor BME280 and TSL2561 Controller Usage: - rpz_sensor.py [-l ] [-v] + rpz_sensor.py [-l ] [-v] [-d] rpz_sensor.py -h --help Options: -l Output log file name -v Show verbose message + -d Store data to influxdb -h --help Show this screen and exit """ @@ -16,9 +18,32 @@ import csv from bme280i2c import BME280I2C from tsl2561 import TSL2561 -from datetime import datetime +from datetime import datetime,timedelta,timezone from docopt import docopt +from influxdb import InfluxDBClient + +def write_db(user,passwd,dbname,node,time,t1,h1,l1,p1): + json_body = [ + { + "measurement": "Environment", + "tags": { + "node": "rpi1" + }, + "time": time, + "fields": { + "T1": t1, + "H1": h1, + "L1": l1, + "P1": p1 + } + } + ] + print(json_body) + client = InfluxDBClient('localhost', 8086, user, passwd, dbname) + client.write_points(json_body) + + def main(): args = docopt(__doc__) loglist = ['']*8 @@ -73,12 +98,15 @@ writer.writerow(['Time', 'Temp ch1', 'Temp ch2', 'Pressure ch1', 'Pressure ch2', 'Humidity ch1', 'Humidity ch2', 'Lux']) - #datestr = datetime.now().strftime("%Y/%m/%d %H:%M") datestr = datetime.now().strftime("%s")+"000" loglist[0] = datestr writer.writerow(loglist) + if args['-d'] != None: + datestr = datetime.now(timezone(timedelta(hours=+0), 'GMT')).strftime('%Y-%m-%dT%H:%M:%SZ') + write_db(user='root',passwd='**********',dbname='db_mon2018',node='rpi1',time=datestr,t1=bme280ch1.T,h1=bme280ch1.H,l1=tsl2561.lux,p1=bme280ch1.P) + if __name__ == '__main__': main() [/highlight_python]
これを以下のように実行すればInfluxDBにデータが登録されるようになります。
[highlight_bash]python3 rpz_sensor_db.py -d[/highlight_bash]
bashを使って電圧・電流・電力のデータ投げる
以前の記事で、電圧・電流・電力を/dev/shm/にCSV形式で保管しているので、cronを使って1分毎にデータをまとめて投げたいと思います。
1分前のデータを取ってきて、時刻を修正し、curlコマンドに与えるスクリプトをこんな感じで作ります。
[highlight_bash]#!/bin/bash cat /dev/shm/watt.$(date +\%Y\%m\%d-\%H).csv |grep $(date -d '1 minutes ago' +\%Y-\%m-\%dT\%H:\%M) > /dev/shm/.temp-influx while IFS=, read dt volt curr watt; do datestr=`date -d ${dt} +\%s` echo $datestr,$watt,$volt,$curr curl -i -XPOST "http://localhost:8086/write?db=db_mon2018&precision=s" --data-binary "Power,node=rex1 watt=$watt,volt=$volt,current=$curr $datestr" done < /dev/shm/.temp-influx rm /dev/shm/.temp-influx[/highlight_bash]
外気温を取得
無料のAPI(OpenWeatherMap)で天候情報を取得して、これもInfluxDBに登録します。
https://openweathermap.org/current
APIの使い方はマニュアルに書いてある通りで、まずは無料登録を行ってAPIキーを取得します。
こちらのサイト(https://openweathermap.org/api)にアクセスして、「Current weather data」の「Subscribe」ボタンを押します。
一番左の「Free」から、「Get API key and Start」ボタンを押します。すると、使い方などが表示されるので説明に沿って進めればOKです。
Freeライセンスは、1分間に60回までしか使ってはいけない(超えると制限される)ので、使用回数には注意してください。
APIキーが取得できたら天候を取得してみます。
APIには天候を取得したい地域の「地名」もしくは「ID」を指定する事ができますが、推奨されているID指定で進めます。
天候を取得したい地域のIDを調べたいので、Webブラウザで検索してみます。
東京の場合はURLにこのように表示されると思います。
https://openweathermap.org/city/1850147
末尾の「1850147」が都市名を示すIDです。
wgetでjsonファイルに保存する場合はこのような感じです。
※{APIKey}は自分のAPIキーに、{CityID}は都市名を示すID(東京は"1850147″)に置き換えてください。
[highlight_bash]wget -L “http://api.openweathermap.org/data/2.5/weather?id={CityID}&units=metric&APPID={APIKey}" -O weather.json[/highlight_bash]
JSON形式のデータをbashで簡単に扱うためにjqを入れます。
(参考:https://qiita.com/asukiaaa/items/a9413b2cc60c598c3d61)
[highlight_bash]$ sudo apt install jq[/highlight_bash]
取得したJSONファイルを引数に与えるとデータベースに登録するスクリプトを作成します。
[highlight_bash] #!/bin/bash if [ ! $# -eq 1 ]; then echo "Useage: `basename $0` JSON" exit fi DBNAME="database_name" # JSONファイルを読み込む JSON=`cat $1` # 各要素を変数に代入 dt=$(echo ${JSON} | jq ".dt") city=$(echo ${JSON} | jq ".name" | sed "s/\"//g") temp=$(echo ${JSON} | jq ".main" | jq ".temp") temp_min=$(echo ${JSON} | jq ".main" | jq ".temp_min") temp_max=$(echo ${JSON} | jq ".main" | jq ".temp_max") pres=$(echo ${JSON} | jq ".main" | jq ".pressure") humi=$(echo ${JSON} | jq ".main" | jq ".humidity") ## データベースに書き込む curl -i -XPOST "http://localhost:8086/write?db=${DBNAME}&precision=s" \ --data-binary \ "Weather,city=${city} \ temp=${temp},temp_min=${temp_min},temp_max=${temp_max},pressure=${pres},humidity=${humi} \ ${dt}" [/highlight_bash]
あとは、cronに登録して定期的に(5分に1回程度)データの取得&データベースの登録を実行すればOK!
しばらくしてデータが貯まってきたら、「ダッシュボードの作成」の所と同じ手順でパネルに登録すれば完了です。
「Outside」として表示するようにしました。
これで室内と屋外の温度・湿度・大気圧などの違いがわかるようになりました(^o^)
最終的に、このようなダッシュボードでエアコンの消費電力や温度・湿度・大気圧・照度を一挙に確認できるようになりました!
まとめ: influxdbとgrafanaを使って、エアコンの消費電力や温度・湿度・大気圧・照度を可視化できた!
Raspberry Piを使って収集した時系列データをInfluxDBに保管して、grafanaでインタラクティブなグラフとして可視化することができました。
一度環境を作ってしまえば、これから様々な時系列データを収集しても、グラフとして可視化して自由に確認できるようになります。
とっても便利!
小型の液晶ディスプレイを繋いで常時モニタリングしています。
毎日眺めていると色々な発見があってオモシロイですよ(^o^)
それではみなさん、良いラズパイ生活を!
ディスカッション
コメント一覧
まーく様
いつも初歩的な質問申し訳ありません。
pythonで温度・湿度・大気圧・照度のデータを投げるのスクリプトにおいて
write_db(user=’root’,passwd=’**********’,dbname=’db_mon2018′,node=’rpi1′,time=datestr,t1=30.1,h1=60.0,l1=100.0,p1=1010.0)
例文には直接数値が入っております。 具体的にはt1=*** h1=*** l1=*** p1=*** この***にはどのような値を入れれば良いのでしょうか?
自分なりに、いろいろと入力し試してはみたのですがエラーが表示されてしまいます。
お手数をおかけしますがよろしくお願いいたします。
変更後の質問とは別の要因な気もするので、こちらにもコメントします!
1)貼り付けられたh1,l1,p1が全角になっているのが気になります。半角であれば大丈夫です。
2)どのようなエラーが起きているかによって対策が変わります。表示されたエラーを貼り付けてもらえますと解決方法を探りやすいです。
3)最初のデータベース作成時に失敗している可能性があります。InfluxDBの新しいバージョンではWebUIが使えなくなっているのでコマンドで実行できるよう後日追記します。
たびたび申し訳ありません。質問を変更させてください。
「pythonで温度・湿度・大気圧・照度のデータを投げる」において
「これを適当なファイルに保存して元になる「rpz_sensor.py」から呼び出して使います」と有りますが、
具体的にはどのような方法をすれば良いのでしょうか。初歩的な事ですみません。
Pさま、質問了解しました。
記事の内容でわからないことは何でも気軽に聞いてもらって大丈夫です!
まず、こちらの記事の内容を実施していることが前提になります。
温度・湿度・気圧・照度をRaspberry Pi 3B+ で24時間監視する 〉3.2. サンプルプログラムを入手する
ここに出てくる「rpz_sensor.py」を編集しています。
pythonをご存じであれば、importして関数を呼び出していると言えば通じると思うのですがいかがでしょうか?
難しそうであれば「rpz_sensor.py」に直接追加する方法を本文に追記したいと思います。
マークさま
お返事ありがとうございます。
rpz_sensor.pyを編集しスクリプトそのまま追記して見ました。
例文のrootパスワードだけは変更しました。
rpz_sensor.py実行状態
pi@ns110:~/src/env-monitoring/rpz-sensor/python3 $ ./rpz_sensor.py
BME280 0x76
Temp : 21.8C
Pressure : 1019.4hPa
Humidity : 57.8%
[{‘time’: ‘2018-11-29T14:03:59Z’, ‘fields’: {‘T1’: 30.1, ‘P1’: 1010.0, ‘H1’: 60.0, ‘L1’: 100.0}, ‘measurement’: ‘Environment’, ‘tags’: {‘node’: ‘rpi1’}}]
grafanaにてデータの登録を見ることができましたが、何か間違っている事が有りますでしょうか?
よろしくお願いいたします。
Pさま、
おおよその状況がわかりました。
例文の25〜27行目までrpz_sensor.pyに追記していませんか?
あるいは、テスト用の27行目をそのまま追記しているせいかと思います。
(実行時に表示される前半の温湿度・気圧と、JSONデータの中身が違っているので。。。)
ということで、手っ取り早くrpz_sensor.pyどのように編集すれば良いか後ほど本文に追加しますね!
まーくさま
お忙しいところお返事ありがとうございます。
よろしくお願いします。
本文に追記しましたので確認してみて下さい!