Node-RED紹介（インストールからWebGUI作成）

Node-REDはIoT向けのビジュアルなフロー記述言語です。
まるで大人版Scratchで、楽しめます。

本資料は、つぎのような Node-REDラジオを作成した経験をもとに、Node-RED の簡単な使い方をまとめた資料です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/c579a308-b5e4-3f1e-82e8-44359d7905f7.png)


# はじめに

本ドキュメントではつぎの項目を説明します。

- Node-RED　メリット、デメリット
- Node-RED　インストール 
- Node-RED　起動、終了
- Node-RED　Hello　World　
- node-red-dashboard　GUI構築、グラフ表示　
- その他
 - プログラムの保存と読み込み
 - グローバル変数（代入と参照） 
 - Node-RED　複数インスタンスの同時起動
 - functionノード で、var os = require('os')
 - コンソールロガー　console.log("abc",var)

# Node-RED　メリット、デメリット

## メリット
- IoT実験、プロトタイプが簡単にできる
- 外部接続がしやすい。（シリアル接続、MQTT接続など）
- ビジュアルにフローを記述できて楽しい
- Web表示GUIが簡単につくれる
- 動作プラットフォームが多い　ラズパイ、WinPc、Mac、Linux、クラウドサーバ（AWS、GCP等）、Android

　Android OS で動かす時は、Androidアプリ「Termux」または「UserLAnd」をインストールし、そのアプリ上で Node,Node-RED を動かします。
　　　　Androidで実行する　https://nodered.jp/docs/platforms/android

## デメリット
- 複雑なGUIを作りにくい
- Arduino で動かない。Arduinoに接続する時は、USBシリアル等を使用する
- ESP32 で動かない。ESP32に接続する時は、WiFi MQTT 等を使用する
- 関数ノードの内容をnode.jsで記述する必要がある。pythonで書けない　

　node-red-contrib-python-function は、プラットフォームにより不安定のようです。



## プログラミング
Node-REDプログラミングは、つぎの手順でビジュアルにフローを作成して行います。
（１）ノード配置（入力ノード、処理ノード、出力ノード）を配置します。
（２）ノード間を結線します。
（３）ノードのプロパティを設定します。
（４）デプロイして、プログラムを実行します。
（５）デバッグします。
　　　デバッグはフローの適当な箇所にデータを入力したり、フローに流れているデータを出力して行います。
　　　データ入力は「inject」ノード、データ出力は「debug」ノードを使用します。

# Node-RED　インストール方法

## インストール全般
Node.js をインストールした後、　Node-RED本体のインストールを行います。

[Node-RED User Group Japan インストール](https://nodered.jp/docs/getting-started/installation)

## Windows 10 64bit へのインストール  
### Node.js LTS 8.x のインストール（推奨は安定している8.x）
（１）インストーラをダウンロードします。 [nodejs.org　node-v8.11.3-x64.msi ](https://nodejs.org/dist/v8.11.3/) 
（２）インストーラを実行します。　　node-v8.11.3-x64.msi 
（３）Node.js　バージョン出力にて動作確認をします。　　node  -v

### Node-RED本体のインストール
（１）Administratorとしてコマンドプロンプトを起動します。
（２）インストーラを実行します。　npm install -g --unsafe-perm node-red 
（３）コマンドプロンプトを終了します。

# Node-RED　起動、終了
（１）一般ユーザで、コマンドプロンプトを起動します。
（２）Node-RED　を起動します。　　node-red
　　　これでWebサーバが起動されます。
（３）Webブラウザで、つぎのいづれかの　URL　を入力して表示します。
　`http://localhost:1880/`　　
　`http://127.0.0.1:1880/`

ブラウザ上にNode-REDのフロー記述画面が表示されます。
この画面が Node-RED の主画面で、フローの作成、編集、デプロイを行えます。

（４）終了する場合は、コマンドプロンプトを閉じます。

# Node-RED で Hello World
## 「inject」ノードの配置とプロパティ設定

（１）左側にあるノードリストの「入力」グループにある「inject」をクリックしながら、右側のフロー画面にドロップします。画面はつぎのようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/64fb0112-09f5-9b5a-aef5-fcd119e4b729.png)

（２）ドロップしてできた「timestamp」をダブルクリックして、ペイロード欄の内容「日時」をつぎの値に変更します。
文字列「az」「Hello, World!」、画面はつぎのようになります。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/7e0e3d73-32f3-484b-8b2e-ce02d85ba518.png)

（３）「完了」ボタンをクリックします。ノードの名前が「Hello, World!」に変わります。

## 「debug」ノードの配置

左側にあるノードリストの「出力」グループにある「debug」を右側のフロー画面にドロップします。画面はつぎのようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/f70253ab-9b6b-9c72-bc63-8e28060e37f8.png)


## ノードの結線

「inject」と「debug」をつぎのように結線します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/ae6d6cfe-6a78-bd75-035a-4c24e01a996c.png)

## デプロイ　（作成したフローを利用可能な状態にする）
画面右上にある「デプロイ」ボタンを押して、システムを利用可能な状態にします。

## フローの実行　
画面右上にある「デバッグ」タブをクリックします。
「Hello, World!」ノードの左端にあるボタンをクリックすると、デバッグタブに、次の３行が表示されます。
時刻
msg.payload : string[13]
"Hello, World!"

画面はつぎのようになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/4a79b6ea-61f9-4062-fe85-1eafa202b9b0.png)


# Node-RED で　GUI構築
## GUIモジュール「node-red-dashboard」パレットのインストール
（１）画面右上の「横３本線」アイコンをクリックして、ドロップダウンリストを表示します。
（２）「パレットの管理」をクリックします。
（３）「ノードを追加」タブをクリックします。
（４）「ノードを検索」欄に「node-red-dashboard」と入力します。つぎのような画面になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/f4bf9cf0-7161-af2b-80d1-c221eb4fa588.png)

（５）下欄に表示された、「node-red-dashboard」の「ノードを追加」ボタンをクリックします。
（６）ポップアップが表示されたら、「追加」ボタンをクリックし、数分待ちます。
（７）「ノードをパレットに追加しました」という表示がでて消えます。
（８）右上の「閉じる」ボタンをクリックします。

## 作成するフロー画面とGUI画面

これからの作業で作成するフロー画面はつぎのようになります。
左側にデータを入力する３部品（button、slider、numeric）、
右側にデータを出力する３部品（text、Gauge、chart）があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/17ceccd0-2d1c-1478-2efd-b37e4b976a59.png)

Webブラウザに表示するGUI画面はつぎのようになります。
上からデータを入力する３部品（button、slider、numeric）、
その下にデータを出力する３部品（text、Gauge、chart）があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/4858e53a-b59f-ab59-6cdf-02d9430e2287.png)


## GUI画面の設定
（１）画面右上の「ダッシュボード」タブを選択します。
（２）タブ内の上段で「配置」タブを選択します。
（３）「タブ＆リンク」の右にある「＋タブ」をクリックします。
（４）「Tab1」を選択し、右にある「＋グループ」をクリックします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/28003899-7faa-eb57-cb44-e683a484d5fa.png)

## 入力用GUIノードの配置
左上の「ノードを検索」欄に「ui」と入力し、GUIの16ノードに絞り込みます。
次の入力用GUI３ノードを、フロー画面に左側に配置します。

button
slider
numeric

## 出力用GUIノードの配置
次の出力用GUI３ノードを、フロー画面に右側に配置します。

text
Gauge
chart

## フロー集約用ノードの配置

左上の「ノードを検索」欄に「ui」を削除して、空にします。
機能の「function」ノードをフロー画面に中央に配置します。

## ノード間の結線
　前述のフロー画面のように、入力部品ノード、「function」ノード、出力部品ノードを結線します。


## ノードのプロパティ設定
ノードを選択して、ダブルクリックするとプロパティ設定画面が表示されます。
### button ノード
（１）Payload欄に「数値」「5」を設定します。

設定画面は、つぎのようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/bd5a0af0-9489-f524-aba2-331f2f6a6981.png)
（２）「完了」をクリックします。

### slider 、numeric 、text、Gauge、functionノード
（１）「完了」をクリックします。
### chart　ノード
（１）Y-axis欄にmin 0、max 10 を設定します。
（２）「完了」をクリックします。

## デプロイ　
右上段にある「デプロイ」をクリックします。
## GUI画面表示
（１）右上にある「ダッシュボード」タブをクリックします。
（２）直下にある「右上向き矢印」アイコンをクリックします。
（３）ブラウザの新しいタブが開き、GUI画面が表示されます。　

## GUI画面の操作
入力GUI部品（button、slider 、numeric）を操作すると、対応して
出力GUI部品（text、Gauge、chart）の値が変化します。

## 入力部品　slider 、numeric　に出力値を反映させる方法

（１）つぎのように、出力値を入力部品に戻すように配線を２本追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/8ca41be7-201d-9ab5-965b-9d9191aedadb.png)

（２）slider 、numeric　のプロパティ変更
つぎのように「 If msg arrives on input, pass through to output」のチェックをはずす。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/c8b1c30d-bb0c-c394-2e00-4e16786d6a53.png)

（３）デプロイします。
（４）GUI画面上で、入力GUI部品を操作すると、対応して slider 、numeric も変化します。

# その他
## プログラムの保存と読み込み
### プログラムをテキストとして保存する
（１）フロー画面を選択し、Ctl-e と入力し（コントロールキーとeキーを同時に押す）、
（２）「フローをクリップボードへ書き出し」画面が開きます。
（３）「現在のタブ」か「全てのタブ」を選択して、保存するフローを選択します。
（４）「インデントのないJSONフォーマット」か「インデント付きのJSONフォーマット」を選択します。
（５）「書き出し」ボタンをクリックします。
　　クリップボードに書き出されます。
（６）任意のテキストエディタを開きます。
（７）テキストエディタにペーストします。
（８）テキストエディタの内容を任意のファイル名で保存します。

### テキストをプログラムとして読み込む

（１）右上の３本横線アイコンをクリックしてドロップリストを表示します。
（２）「読み込み」「クリップボード」を選択します。
（３）「フローをクリップボードから読み込み」画面が開きます。
（４）プログラムテキストをクリップボードに貼り付けます。
（５）読み込み先として「現在のタブ」または「新規のタブ」を選択します。
（６）「読み込み」ボタンをクリックします。


## グローバル変数（代入と参照） 
グローバル変数に値を保存して、後から参照したい時はつぎのようにします。

グローバル変数は、「global.変数名」でアクセスします。

### 「change」ノード（値を変更するノード）
左側の「機能」にある「change」ノードをフロー画面にドロップします。
プロパティ画面を開き、つぎの設定をします。

### フローの値をグローバル変数 foo に代入する
- 「値の代入」欄に　「global.foo」を設定します
- 「対象の値」欄に　「msg.payload」を設定します

### グローバル変数 foo の値をフローに流す
- 「値の代入」に　「msg.payload」を設定します
- 「対象の値」に　「global.foo」を設定します

### 「function」ノード　（Node.js言語でプログラムを記述するノード）
左側の「機能」にある「function」ノードをフロー画面にドロップします。
プロパティ画面を開き、コード欄に、つぎのように記述します。
### フローの値をグローバル変数 foo に代入する
- 「コード」欄に、「global.set("foo",msg.payload);」 を設定します

### グローバル変数 foo の値をフローに流す
- 「コード」欄に、「msg.payload = global.get("foo");」 を設定します

## Node-RED　複数インスタンスの同時起動
複数のNode-REDインスタンスを起動したい場合は、複数のコマンドプロンプトを起動して、
つぎのように別々の環境を指定して、Node-REDを起動します。

node-red -u 作業用ディレクトリパス -p 作業用ポート番号

例えばつぎのように起動します。「node-red -u /work1 -p 1881」
各デフォルト値は、「ホームディレクトリ」と「1880」です。

ブラウザから `http://localhost:作業用ポート番号`
でnode-redにアクセスします。

## functionノード で、var os = require('os')
require('os') をしたい時は、つぎのようにします。

（１）~/.node-red/settings.js の functionGlobalContext にある、「 // os:require('os'),」の「//」を削除する。
  
（２）「function」ノード内で、「var os = global.get('os');」とする。

## コンソールロガー　console.log("abc",var)
functionノードのデバッグ時は、簡単にコンソール出力できて便利です。

# 参考資料

[Node-RED User Group Japan ドキュメント](https://nodered.jp/docs/)

[node-red-dashboard](https://flows.nodered.org/node/node-red-dashboard)

[node-red-dashboardでチャート表示IoTアプリ作成](https://qiita.com/kuraoka/items/2e14bc2fefb9b0183cc7)

[Beebotte のメッセージを Node-RED で受ける](https://qiita.com/HeRo/items/9978bedf353fc790a5b5)

[Node-REDのserialノードを使ってEnOceanのスイッチデータを受信してみた](https://digital-light.jp/2017/10/13/received-enocean-data-by-using-serialport-node/)

[Node-red+JSONataでfunction地獄からの卒業](https://www.slideshare.net/kazuhiroharada2/node-redjso-natafunction)

[Node-RED Official website](https://nodered.org/)

[Node-RED - Wikipedia](https://en.wikipedia.org/wiki/Node-RED)