Node-REDでModbus TCP通信してInfluxDBにデータを蓄積する

# はじめに
[前回の記事](https://qiita.com/Yokogawa_Ishino/items/c3467efb83e7fa342734)ではPythonでModbus通信を行ってInfluxDBにデータを蓄積しました。
今回はNode-REDを使ってModbus通信を行い、InfluxDBにデータを蓄積してみたいと思います。
Node-REDを使うことで視覚的にデータの処理を行うことができます。

# 構成
以下の構成でデータの収集～蓄積を行います。
1. データ収集
    Node-REDでModbus TCP通信を行ってエッジデバイスが装置からデータを収集します。

1. データ蓄積
    収集したデータをInfluxDBに蓄積します。
    
![nodered-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/ce617fb1-7bc2-3c69-51aa-417908b42cb4.png)

# 動作確認済みデバイス
動作確認済デバイス（OS）
- e-RT3 Plus F3RP70-2L[^ert3]（Ubuntu 18.04 32bit）
- Raspberry Pi 4 Model B （Ubuntu Server 20.04 32bit）

これらのデバイスでは armhf アーキテクチャのパッケージが動作します。

# 準備
## Node-REDの準備
### Node.jsとNode-REDのインストール
エッジデバイスで以下のコマンドを実行してNode.jsをインストールします[^nodejs]。

```bash
curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
```

>**Note**
>エッジデバイスがproxy環境下にある場合は[proxy設定](https://qiita.com/Yokogawa_Mita/items/f7996d539b29618d7159#proxy%E8%A8%AD%E5%AE%9A)が必要です。

以下のコマンドを実行してNode-REDをインストールします[^nodered]。

```bash
sudo npm install -g --unsafe-perm node-red
```

以下のような出力が表示されたら成功です。

```bash
+ node-red@2.2.0
added 286 packages from 375 contributors in 142.031s
```

>**Note**
>エッジデバイスがproxy環境下にある場合は[npmのproxy設定](#npmのproxy設定)が必要です。

### ノードのインストール
Node-REDで使用するノードのインストールを行います。

エッジデバイスで以下のコマンドを実行してNode-REDを起動します。

```bash
node-red
```

起動したらPCのブラウザで`http://<IP_ADDRESS_OF_EDGE_DEVICE>:1880`にアクセスしてNode-REDの画面を開きます。`<IP_ADDRESS_OF_EDGE_DEVICE>`の部分はエッジデバイスのIPアドレスで置き換えてください。

画面右上のメニューアイコンをクリックして「パレットの管理」をクリックします。
![nodered-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/53a09e6e-e12e-11e5-cafc-0e5e3fbca3fd.png)

「ノードを追加」タブの検索窓に`node-red-contrib-influxdb`と入力し、該当するノードをインストールします。
![nodered-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/d70ab563-134d-6fa7-335f-51c71c04f20c.png)

同様の手順で`node-red-contrib-modbus`もインストールします。　
![nodered-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/de434580-d4a2-3582-258b-a34bbe38a905.png)

## InfluxDBの準備
[こちらの手順](https://qiita.com/Yokogawa_Ishino/items/c3467efb83e7fa342734#influxdb%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)でInfluxDBをインストールします。(Pythonパッケージのインストールは不要です。)
また、[こちらの手順](https://qiita.com/Yokogawa_Ishino/items/c3467efb83e7fa342734#%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E6%BA%96%E5%82%99)を参考にして`noderedDB`という名前でデータベースを作成します。

# データ収集
## Modbusサーバーの準備
今回は装置の代わりにPC上でModbusサーバーを起動します。
PCで[こちらのプログラム](https://qiita.com/Yokogawa_Ishino/items/c3467efb83e7fa342734#modbus%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E6%BA%96%E5%82%99)を起動してModbusサーバーを立ち上げます。

## Node-REDフローの作成
5秒おきにModbusサーバーからデータを取得するフローを作成します。今回はサーバーの保持レジスタに格納されている2つの時系列データを収集します。

左側のメニューから「Modbus-Read」ノードをドラッグ&ドロップし、ダブルクリックして設定画面を開きます。
Modbusサーバーの保持レジスタ2から2つの値を5秒おきに読み取るように設定を行います。
![nodered-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/bf225edc-8a3c-5d6f-2c5a-554ac1cac1e3.png)

| 項目名    | 設定値                       |
| --------- | ---------------------------- |
| 名前      | read_holding_register        |
| FC        | FC 3: Read Holding Registers |
| Address   | 2                            |
| Quantity  | 2                            |
| Poll Rate | 5 seconds                    | 

Serverの設定では、右側のペンのボタンをクリックしてPCで起動しているModbusサーバーの情報を入力します。

![nodered-6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/b3c345fa-bad2-49fa-03ec-1a12b98fbd94.png)

| 項目名 | 設定値                                     |
| ------ | ------------------------------------------ |
| 名前   | serverPC                                   |
| Type   | TCP                                        |
| Host   | Modbusサーバーを起動しているPCのIPアドレス |
| Port   | 5020                                       |

設定が完了したら「完了」ボタンをクリックします。

データが収集されていることを確認するために、「debug」ノードをドラッグ＆ドロップして「read_holding_register」ノードの上側の端子と接続し、デプロイボタンをクリックします。
![nodered-7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/fe1dd98f-e597-3dd7-f913-4912e9533d1d.png)

右側のデバッグタブをクリックして、以下のように収集したデータが表示されていれば成功です。
![nodered-8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/5c69d715-ba5f-3416-ed8d-b675259dae90.png)

# データ蓄積
収集したデータを加工してInfluxDBに格納します。

右側のメニューから「function」ノードをドラッグ&ドロップしてダブルクリックします。
「コード」タブを開き、収集したデータの配列をjson形式に加工する以下のプログラムを作成して「完了」をクリックします。

```javascript
const data = msg.payload

payload = {
    "holding_register_2": data[0],
    "holding_register_3": data[1]
}

msg["payload"] = payload

return msg;
```
![nodered-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/7fa9a97f-10d3-0bb4-a3a0-e7f2d5618922.png)

次に、データをInfluxDBに格納する「influxdb out」ノードをドラッグ&ドロップしてダブルクリックし、以下のように設定を行います。
![nodered-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/362da612-6c03-75a4-da4f-7a4b5f97f0dc.png)

| 項目名 | 設定値   |
| ------ | -------- |
| 名前   | To_noderedDB |
|   Measurement     |    nodered_measurement      |

Serverの設定では、右側のペンのボタンをクリックしてエッジデバイスで起動しているInfluxDBの情報を入力します。
![nodered-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/b88b53c2-b12a-8312-e5df-d7972c771724.png)

| 項目名   | 設定値    |
| -------- | --------- |
| 名前     | noderedDB |
| Host     | localhost |
| Port         |8086           |
| Database | noderedDB |

すべての設定が完了したら以下のようにノードを接続し「デプロイ」ボタンをクリックします。
![nodered-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682603/b03596ee-0251-45d6-d677-846cb78d645c.png)

しばらく待ってからエッジデバイスで以下のコマンドを実行してデータベースの中身を確認します。データが格納されていたら成功です。

```bash
username@ubuntu:~$ influx
Connected to http://localhost:8086 version 1.8.10
InfluxDB shell version: 1.8.10
> USE noderedDB
Using database noderedDB
> SELECT * FROM "nodered_measurement" LIMIT 3
name: nodered_measurement
time                holding_register_2 holding_register_3
----                ------------------ ------------------
1643782593448526154 93                 24
1643782598683263519 99                 22
1643782603803351763 100                20
```
# まとめ
今回はNode-REDでModbus通信を行ってデータをInfluxDBに格納する方法を紹介しました。
少ないプログラム量で視覚的にデータ収集アプリケーションを作成することができました。
[前回の記事の可視化の手順](https://qiita.com/Yokogawa_Ishino/items/c3467efb83e7fa342734#%E5%8F%AF%E8%A6%96%E5%8C%96%E3%81%A8%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0)を行えば、今回蓄積したデータをGrafanaで可視化することも可能です。是非お試しください。

# 補足
## npmのproxy設定
デバイスがproxy環境下にある場合は、以下のコマンドを実行してnpmのproxy設定を行います。

```bash
sudo npm -g config set proxy http://{username}:{password}@{proxy-server-url}:{port}
sudo npm -g config set https-proxy https://{username}:{password}@{proxy-server-url}:{port}
```

[^ert3]: [産業用AIプラットフォーム | 横河電機株式会社](https://www.yokogawa.co.jp/solutions/products-platforms/control-system/real-time-os-controller/ert3-ai-platform/)
[^nodejs]: [distributions/README.md at master · nodesource/distributions · GitHub](https://github.com/nodesource/distributions/blob/master/README.md)
[^nodered]: [ローカルでNode-REDを実行する : Node-RED日本ユーザ会](https://nodered.jp/docs/getting-started/local)