室温をデータベースに記録して可視化する(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);
});
実際には、前回作成した室温監視プログラムに機能追加しました→https://github.com/haneco/temperature-checker 次回は、記録したデータの可視化を行います。