3
3

More than 5 years have passed since last update.

Node-RED on Docker - Part5: InfluxDBのnodeを作成する

Last updated at Posted at 2015-02-16

練習としてCreating your first nodeを動かすことができました。次はもう少し実際の利用にあわせてInfluxDBにメッセージを保存するnodeを書いてみます。node-red-nodesのstorageディレクトリにデータベース用のnodeがいくつかあります。今回はPostgreSQLの110-postgres.jsを参考にします。

Cannot find module 'influx'

前回settings.jsに追加のnodesディレクトリを設定しました。コンテナを起動するときにDockerホストのディレクトリをマウントするようにしています。

~/docker_apps/nod-red/settings.js
...
nodesDir: '/data/nodes',
...

最初はこの追加ディレクトリにInfluxDBのnodeを配置しましたが、require("influx");のところでモジュールの読み込みに失敗してしまいます。InfluxDBクライアントはNode-REDのpackage.jsonの最後に追加しました。google/nodejs-runtimeのDockerfileではONBUILD RUN npm installでnpmモジュールをインストールしています。

package.json
    "dependencies": {
        "express": "3.17.2",
        "when": "3.7.2",
...
        "influx":"3.3.0"
    },

作成したnodeをnpmパッケージとして公開する方法がPackagingにあります。まだ開発中なのでNode-REDをcloneしたディレクトリにあるnodes/core/storage/配下に直接追加してDockerイメージを再作成することにします。npmに登録するのはテストが通ってからにします。

InfluxDBのnode

ファイル名の数字のprefixはnodesディレクトリ内でnodeのロード順を定義するようです。とりあえず98にしました。jsファイルにnodeのロジックを記述します。

~/docker_apps/node-red/nodes/core/storage/98-influxdb.js
module.exports = function(RED) {
    "use strict";
    var influx = require("influx");
    function InfluxDBNode(n) {
        RED.nodes.createNode(this,n);
        this.host = n.host;
        this.port = n.port;
        this.db = n.db;
        this.user = this.credentials.user;
        this.password = this.credentials.password;
    }
    RED.nodes.registerType("influxdb",InfluxDBNode,{
        credentials: {
            user: {type:"text"},
            password: {type: "password"}
        }
    });
    function InfluxNode(n) {
        RED.nodes.createNode(this,n);
        this.influxdb = n.influxdb;
        this.influxConfig =  RED.nodes.getNode(this.influxdb);
        var node = this;
        if(this.influxConfig) {
            node.clientdb = influx({
                host : this.influxConfig.host,
                port : this.influxConfig.port,
                username : this.influxConfig.user,
                password : this.influxConfig.password,
                database : this.influxConfig.db
            });
            node.on("input", function(msg) {
                node.clientdb.writePoint(msg.topic, JSON.parse(msg.payload), function(err) {
                    if(err) {
                        node.error(err);
                    }
                });
            });
        }
    }
    RED.nodes.registerType("influx",InfluxNode);
}    

htmlファイルにはnodeの設定を記述します。ユーザーが値を入力するフォームのテンプレートとNode-REDへの登録を行います。今回は最初なのでcategoryはconfigsotrage-outだけ作成してレコードを登録する機能だけ実装します。

~/docker_apps/node-red/nodes/core/storage/98-influxdb.html
<script type="text/x-red" data-template-name="influxdb">
    <div class="form-row">
        <label for="node-config-input-host"><i class="fa fa-bookmark"></i> Host</label>
        <input class="input-append-left" type="text" id="node-config-input-host" placeholder="localhost" style="width: 40%;" >
        <label for="node-config-input-port" style="margin-left: 10px; width: 35px; "> Port</label>
        <input type="text" id="node-config-input-port" placeholder="8086" style="width:45px">
    </div>
    <div class="form-row">
        <label for="node-config-input-db"><i class="fa fa-briefcase"></i> Database</label>
        <input type="text" id="node-config-input-db" placeholder="">
    </div>
    <div class="form-row">
        <label for="node-config-input-name"><i class="fa fa-user"></i> Username</label>
        <input type="text" id="node-config-input-user" placeholder="username">
        <label for="node-config-input-password"><i class="fa fa-lock"></i> Password</label>
        <input type="password" id="node-config-input-password" placeholder="password">
    </div>
</script>

<script type="text/javascript">
    RED.nodes.registerType('influxdb',{
        category: 'config',
        defaults: {
            host: { value:"localhost",required:true},
            port: { value: 8086,required:true},
            db: { value:"influxdb",required:true}
        },
        credentials: {
            user: {type:"text"},
            password: {type: "password"}
        },
        label: function() {
            return this.db;
        }
    });
</script>
<script type="text/x-red" data-template-name="influx">
    <div class="form-row">
        <label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
        <input type="text" id="node-input-name" placeholder="Name">
    </div>
    <div class="form-row">
        <label for="node-input-influxdb"><i class="fa fa-tag"></i> Server</label>
        <input type="text" id="node-input-influxdb">
    </div>
</script>
<script type="text/x-red" data-help-name="influx">
    <p>A InfluxDB I/O node. </p>
</script>
<script type="text/javascript">
    RED.nodes.registerType("influx",{
        category: "storage-output",
        color:"#dbb84d",
        defaults: {
            influxdb: {type:"influxdb",required:true},
            name: {value:""}
        },
        inputs: 1,
        outputs: 0,
        icon: "influxdb.png",
        align: "right",
        label: function() {
            var influxDBNode = RED.nodes.node(this.influxdb);
            return this.name||(influxDBNode?influxDBNode.label():"influxdb");
        },
        labelStyle: function() {
            return this.name?"node_label_italic":"";
        }
    });
</script>

最後にInfluxDBのアイコンを用意します。

~/docker_apps/node-red/public/icons/influxdb.png

Dockerイメージの作成と起動

Dockerイメージのビルドとコンテナを起動します。

$ cd ~/docker_apps/node-red/
$ docker build -t node-red .
$ docker run -d  --name node-red \
  -p 1880:1880 \
  -v /opt/nodes:/data/nodes \
  node-red

Node-REDでflowの作成

input:inject

inject nodeをworkspaceにドラッグ&ドロップします。テスト用にPayloadにInfluxDBに保存するJSONを文字列で書きます。キーはダブルクォートで囲います。TopicはInfluxDBのseries名になります。

  • Payload: string {"temperature":4.5,"humidity":6.7}
  • Topic: sensortest
  • Repeat: None
  • Name: dummy-input

inject-node.png

storage:influx

storageカテゴリからinfluxをworkspaceにドラッグ&ドロップします。nodeのconfigに接続するInfluxDBのHost名やDatabase名を設定します。

  • node

    • Name: influxdb-store
    • Server: sensor-test
  • config

    • Host: 10.1.3.67
    • Port: 8086
    • Database: sensor-test
    • User: admin
    • Password: password

influx-edit-config.png

デプロイと実行

InfluxDBにテスト用のDatabaseとユーザーを作成します。

$ curl -X POST 'http://10.1.3.67:8086/db?u=root&p=root' -d '{"name": "sensor-test"}'
$ curl -X POST 'http://10.1.3.67:8086/db/sensor-test/users?u=root&p=root' \
  -d '{"name": "admin", "password": "password"}'

画面右上のDeployボタンを押してデプロイします。テストなのでflowの起動はinject nodeの左側のボタンをクリックします。

deploy-run.png

InfluxDBの管理画面

sensor-testデータベースのクエリ画面を開きます。

  • Databases > sensor-test > Explore Data

以下のような簡単なQueryを記述してExecute Queryボタンを押すと1レコードヒットしました。Node-REDのinject nodeに定義したPayloadがInfluxDBに保存できたようです。

influx-admin-query.png

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3