7
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Node-REDでできること part2 (応用編)

Last updated at Posted at 2019-02-13

はじめに

やりたいこと

  • Node-REDでどんなことがどこまでできるのかを調べる
  • part2(応用編)では、Node-REDの設定ファイルや小技などをまとめました

Node-REDのまとめ記事

動作環境

  • OS : CentOS Linux release 7.5.1804 (Core)
  • Node-RED : v0.19.5
  • docker : 18.09.1
    • Node-REDイメージ : nodere/node-red-docker (IMAGE ID/d4f07b39b24d)
    • Dockerを使いますが、ホストに立てても大丈夫かと思います。

免責事項

  • 検証をして確実と思われる情報を載せておりますが、誤っている可能性もゼロではないので、参考程度にご利用ください
  • 本来はコードと実行結果のコンソールログも載せるべきなのですが、数と量が多いので、一旦は画面イメージまでとさせてください。

調査結果

変数共有

調べたこと

  • 各ノード、フロー間の情報のやりとりをどのように行うのか確認する
  • contextオブジェクトの中にデータを保持しておくことができ、別の個所でその値を参照できる仕組みがある
    • ローカルノードコンテキスト変数:単一のノードで共有できる変数
    • フローコンテキスト変数:フローで共有できる変数
    • グローバル変数:全体で共有できる変数
  • コンソールのコンテキストタブでも値を確認できる

ソースコードイメージ

// ローカルノードコンテキスト変数
// 同じノードが再度利用されるときに、前の値を引き継げる
var con_count = context.get('con_count')||0;
con_count += 1;
context.set('con_count',con_count);

// フローコンテキスト変数
// 同じフロー内にいるノードで情報を引き継げる。再利用時も引き継がれる
var flow_count = flow.get('flow_count')||0;
flow_count += 1;
flow.set('flow_count',flow_count);

// グローバル変数
// すべての場所から参照可能
var global_count = global.get('global_count')||0;
global_count += 1;
global.set('global_count',global_count);

時間測定

調べたこと

  • 性能を測定する際には、処理時間を測定したいケースが度々発生するので、測定方法を確認する
  • 前述の変数とJSの基本機能であるDate関数を使えば簡単に実現できる
    • functionノードAで今の時間を記録し、処理終了後にfunctionノードBでも今の時間を記録する。両者の差分を取って経過時間を測定する

ソースコードイメージ

// functionノードA
global.set('global_count',new Date().getTime());

// functionノードB
var start = global.get('global_count');
var diff = new Date().getTime() - start;
msg.payload = diff + "ミリ秒"

画面イメージ
X1.jpg

定期実行

調べたこと

  • 単にInjectノードの設定で指定した時間間隔を設定するだけ
    • 指定した時間間隔、日時などある程度細かく設定できる

画面イメージ
X2-1.jpg
X2-2.jpg

複数入力の時間内判定

調べたこと

  • 複数の入力が一定時間内に送られたらtrueを返すロジックが必要になったので、実現性を確認する
  • フローコンテキストに時間とイベントを紐づけて記録し、チェック機能で両者を取り出して時間を測るだけ
// Input1側(Input2側もInput1をInput2にするだけ)
var time_table = flow.get("time_table") || {}
var user_data = time_table[msg.payload] || {}
user_data["Input1"] = new Date().getTime()
time_table[msg.payload] = user_data
flow.set("time_table",time_table)
return msg;
// 取り出し&比較ロジック
var time_table = flow.get("time_table") || {}
var user_data = time_table[msg.payload] || {}
var in1_time = user_data["Input1"]
var in2_time = user_data["Input2"]
try{
    var diff = (in1_time - in2_time) / 1000
    msg.diff = time_table
    if(Math.abs(diff) < 5){
        msg.payload = "5秒未満"
        msg.flag = true
    }else{
        msg.payload = "5秒以上"
        msg.flag = false
    }
    
}catch(e){
    msg.flag = false
}
return msg;

画面イメージ
X3.jpg

functionノードのログ出力

調べたこと

  • functionノード内からログに出力する機能を確認する
    • 警告以上のログは、コンソールに出力される
    • ログファイルには指定されたログレベル以上のものが記録される
      • ログファイルに記述されるlevelについては、以下の通り定義されている模様
        • off:1, fatal:10, error:20, warn:30, info:40, debug:50, trace:60, audit:98, metric:99
// functionノードでの記述
node.trace("トレースレベルのログ")
node.debug("デバッグレベルのログ")
node.log("インフォレベルのログ");
node.warn("警告レベルのログ");
node.error("エラーレベルのログ");

functionノードの状態設定

調べたこと

  • node.statusを使えば、状態を変えられるらしいので、確認する
    • fill,shape,textの3つを指定できる
  • statusノードにも伝播される
// 緑の〇でOKをステータスとして表示させる
node.status({fill:"green",shape:"dot",text:"OK"});

画面イメージ
X4.jpg

JSのrequire

調べたこと

  • functionノードにモジュールを直接requireすることはできないので、実現方法を確認する
    • settings.jsに記述し、functionノードから参照する
    • settings.jsへの修正が必要なため、Node-REDの再起動が必要?
// settings.js内の設定
// axiosをfunctionノードで使いたい
functionGlobalContext: {
    axios:require('axios')
},
// functionノードの中
const axios = global.get('axios');

SSL化

調べたこと

  • Node-REDへのアクセスおよび、http/wsをhttps/wssにする方法を確認する
  • 鍵を作成して特定の場所に置けばよい
    • http/ws と https/wssの共存はできない模様
// settings.js
// XXXには、認証に必要な鍵と認証書のパスを記述する
var fs = require("fs");

https: {
     key: fs.readFileSync('XXX'),
    cert: fs.readFileSync('XXX')
},

ユーザ認証

調べたこと

  • Node-REDのフローを特定の人だけに変更できるようにするため、認証をする方法がないか確認する
    • いくつかの手段があるが、ひとまずbasic認証で可とする
// settings.js
// XXXには、ユーザ名とパスワードのMD5のハッシュ値をいれる
httpAdminAuth: {
  user:"XXX",
  pass:"XXX"
},

ログファイル出力

調べたこと

  • Node-REDはデフォルトではコンソールにしか出力できないらしいので、ログファイル出力の方法を確認する
  • logstashに送る方法もあるらしいが、うまくいかなかった
// settings.js
// XXXにはログファイルのパスを入れる
var fs = require("fs");
fs.writeFile('XXX',''); // 初期化

logging: {
  file:{
    level: 'debug',
    metrics: false,
    audit: false,
    handler : function(settings){
      return function (msg){
       fs.appendFile('XXX',(new Date(msg.timestamp)).toISOString() + " : " + JSON.stringify(msg) + '\n');
      }
    }
  }
},

デスクトップ版

調べたこと

  • Serverを立てずに利用できると、利用できる人が増えるのではないかという発想で探したら、electronを使ったデスクトップアプリ版が存在していた
  • デスクトップアプリ版の差異を確認する
    • 2つのバージョンがあり、組み込まれているノードの数が異なる
    • Node.jsを入れない影響か、作業環境の影響か、ノードの追加インストールとフローの書き出しができなかった
7
12
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
7
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?