室温をデータベースに記録して可視化する(InfluxDB導入編)
エアコンから温度データを取得できるようになったので、このデータをデータベースに記録して後から参照できるようにしたいと思います。
室温の変化や外気温との関係を分析することで効率よくエアコン運用ができるようになる…かどうかはさておき、普段は室温の変化なんてそんなに気にしていませんが可視化するとどうなるのかなと興味があるので。
データベースはMySQLとSQL Server、PostgreSQLなどRDBしか使ったことがないのですが、今回は時系列データベースのInfluxDBを使ってみたいと思います。
エアコンのセンサー監視はRaspberry Pi 3で行なっているので、これにインストールして使用します。
また、可視化については最終的にはダッシュボードを自作したいですが、とりあえず仕事でも使ったことのあるGrafanaを使ってサクッと実現させたいと思います。
InfluxDBをRapsberry Pi 3にインストール
リポジトリを追加してInfluxDBをインストール
$ curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add - $ echo "deb https://repos.influxdata.com/debian jessie stable" | sudo tee /etc/apt/sources.list.d/influxdb.list deb https://repos.influxdata.com/debian jessie stable $ sudo apt-get update $ sudo apt-get install influxdb
InfluxDBを起動
$ sudo systemctl start influxdb
動作確認。
$ curl -sl -I http://localhost:8086/ping $ ps aux | grep influx influxdb 2380 1.1 1.0 800020 9456 ? Ssl 12:10 0:00 /usr/bin/influxd -config /etc/influxdb/influxdb.conf pi 2396 0.0 0.1 5720 1856 pts/0 S+ 12:10 0:00 grep --color=auto influx pi@raspberrypi:~ $ ss -lntp | grep 808 LISTEN 0 128 127.0.0.1:8088 *:* LISTEN 0 128 :::8086 :::* pi@raspberrypi:~ $ curl -sl -I http://localhost:8086/ping HTTP/1.1 204 No Content Content-Type: application/json Request-Id: 8eef0538-a7e8-11e7-8001-000000000000 X-Influxdb-Version: 1.3.5 Date: Tue, 03 Oct 2017 03:11:33 GMT pi@raspberrypi:~ $ curl http://localhost:8086/query?pretty=true --data-urlencode "q=SHOW DATABASES" { "results": [ { "statement_id": 0, "series": [ { "name": "databases", "columns": [ "name" ], "values": [ [ "_internal" ] ] } ] } ] }
データベース作成
CLI経由でsensorという名前のデータベースを作成します。
$ influx Connected to http://localhost:8086 version 1.3.5 InfluxDB shell version: 1.3.5 > create database sensor > show databases name: databases name ---- _internal sensor > exit
データ投入
HTTP経由でデータを投入してみます。
$ curl -i -XPOST 'http://localhost:8086/write?db=sensor' --data-binary 'temperature,location=LDK value=27.0 1434055562000000000' $ curl -i -XPOST 'http://localhost:8086/write?db=sensor' --data-binary 'temperature,location=屋外 value=26.0 1434055562000000000'
データの確認
投入したデータを確認します。
$ curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=sensor" --data-urlencode "q=SELECT \"value\" FROM \"temperature\" WHERE \"location\"='LDK'" { "results": [ { "statement_id": 0, "series": [ { "name": "temperature", "columns": [ "time", "value" ], "values": [ [ "2015-06-11T20:46:02Z", 27 ] ] } ] } ] } $ curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=sensor" --data-urlencode "q=SELECT \"value\" FROM \"temperature\" WHERE \"location\"='屋外'" { "results": [ { "statement_id": 0, "series": [ { "name": "temperature", "columns": [ "time", "value" ], "values": [ [ "2015-06-11T20:46:02Z", 26 ] ] } ] } ] }
データの削除
$ curl -XPOST 'http://localhost:8086/query?pretty=true' --data-urlencode "db=sensor" --data-urlencode "q=DROP SERIES FROM \"temperature\"" $ curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=sensor" --data-urlencode "q=SELECT \"value\" FROM \"temperature\"" { "results": [ { "statement_id": 0 } ] }
JavaScriptでセンサーの値を取得してInfluxDBへ投入する
Node.jsでエアコンからセンサーの値を取得してデータを投入します。だいたいこんな感じ。
// エアコンのセンサーから値を取得する http.get(`http://192.168.11.2/aircon/get_sensor_info`, (response) => { let body = ''; response.setEncoding('utf8'); response.on('data', (chunk) => { body += chunk; }); response.on('end', () => { // 取得した文字列をオブジェクトに変換 const sensorValues = {}; const items = body.split(','); const length = items.length; for (let i = 0; i < length; i++) { const keyVal = items[i].split('='); sensorValues[keyVal[0]] = keyVal[1]; } // InfluxDBに室温と外気温をPOSTする const timestamp = +(new Date()) * 1000000; const postData = `temperature,location=LDK value=${sensorValues.htemp} ${timestamp} temperature,location=屋外 value=${sensorValues.otemp} ${timestamp}`; const options = { host: 'localhost', port: 8086, path: `/write?db=sensor`, method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }; const request = http.request(options, (dbResponse) => { dbResponse.setEncoding('utf8'); dbResponse.on('data', (dbResponseData) => { console.log(dbResponseData); }); }); request.on('error', (error) => { console.log(error.message); }); request.write(postData); request.end(); }); }).on('error', (error) => { console.log(error.message); });
実際には、前回作成した室温監視プログラムに機能追加しました。
次回は、記録したデータの可視化を行います。