OKI AE2100 & Node-REDでローコードIoTしてみた。その４ 実践編 2

# Node-REDでMQTT Pub/Sub

# はじめに
本記事はOKIの「AIエッジコンピューター」と呼ばれる AE2100 というゲートウェイ製品にNode-REDを載せて、ローコードIoTのプラットフォームにしようという記事の **その４ 実践編 2「Node-REDでMQTT Pub/Sub」** です。

[その１ 準備編「PythonでRS-485圧力センサーシミュレータ作成」](https://qiita.com/marufumio/items/d3182574e5bed35f94e0)
[その２ 構築編「DockerでローコードIoTプラットフォーム構築」](https://qiita.com/marufumio/items/f6bd3088c9c60e5e7f57)
[その３ 実践編 1「Node-REDでダッシュボード作成」](https://qiita.com/marufumio/items/7e04006f48036cc37f21)
[その４ 実践編 2「Node-REDでMQTT Pub/Sub」](https://qiita.com/marufumio/items/afdae6eb83b7752ce57d)  **(本記事)**

前編では RS-485入力の圧力値をNode-RED でローカルに作ったダッシュボードにリアルタイム表示しました。
もうそこまでで十分なわけですが、いちおうIoT関連の記事なので、ネットワークを利用するところまでやらせてください！

# こんなことやります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/79cc4bd9-3d08-9a0d-e045-aed712951847.png)


本編で行うのは最後の **4 MQTT Pub/Sub** になります。
RS-485で受信した圧力値をクラウドに飛ばしてIoTらしいアプリに仕上げます。
使用するネットワークプロトコルはMQTTです。

# MQTT
Node-RED 経験者なら、ほぼ間違いなくMQTTを使ったことがあるでしょうが、ここではMQTT初心者向けに少しだけ解説します。
MQTTとは、パブリッシュ/サブスクライブ型のメッセージキューです。
サーバーであるMQTTブローカーを仲介者として、複数のクライアントがサブスクライブ（購読）とパブリッシュ（発行）に分かれ、トピック名をキーワードとしてメッセージの送受信を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/5118c801-16cc-6f1a-e0d4-30c481817a39.png)

１つのクライアントがパブリッシュとサブスクライブの両方を行うこともあります。
Node-RED ならば、MQTT、Node-RED 両方の初心者でも、設定だけで簡単に MQTT を試すことができます。

なおMQTTブローカーには、**test.mosquitto.org** を使わせていただきます。 

# Node-RED フロー作成

Node-RED のフローエディタ構成を再掲しました。
ワークスペース内のフローがこれから作成するフローです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/37fc89bd-6326-a986-54a5-74ae7a739ec9.png)

## 流量制限ノード

まず上図のフローの左下に追加した **"1 data/10 sec"** ノードですが、これは毎秒受信する圧力センサーのデータを10秒に1回に流量制限するものです。
無料で使わせていただくMQTTブローカーに毎秒データを送りつけるのは気が引けるので、遠慮して10秒に1回にします。

パレットにあるこの **delay** ノードを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/b66c53fb-7f70-f5c6-ff1c-b8b966c2fee3.png)

これをワークスペースに置いて、ダブルクリックして以下のように設定して完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/fa5a7e54-dd3e-36cb-3375-bcd82772a16d.png)
このように流量の制限が設定だけで簡単にできてしまいます。

## MQTTパブリッシュノード

次に、MQTTブローカーにセンサーデータをパブリッシュするノードを設定します。
パレットからこの **mqtt out** ノードを掴んで、ワークスペースにドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/028a0613-2275-a849-7069-97051836b872.png)

ダブルクリックして設定します。
まずは鉛筆アイコンをクリックして、MQTTブローカーの設定画面に移行します。下の右にある設定画面が開きます。
**名前**はとりあえず **test.mosquitto.org** としておきましょう。
**サーバ**は今回は **test.mosquitto.org** と指定する必要があります。
**ポート**はデフォルトの1883でＯＫです。
**クライアント**名は、何でも良いのですが、ここでは **AE2100** とします。
以上３つ設定したら、更新をクリックして初めの設定画面に戻ります。

**トピック**名はMQTTブローカー内でユニークである必要があります。
今回は **ae2100/pressure** とすればOKでしょう。 
**QoS**は **1** にして、少なくとも1回はMQTTブローカーにデータが届くまで(複数回届く可能性があります）パブリッシュするようにします。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/58833bfe-5f2c-1afc-8cab-07813ec03852.png)

**mqtt out** の設定が完了したら、フローエディタの右上の **デプロイ** をクリックして保存・実行しましょう。
下図のように **test.mosquitto.org** ノードが **接続済** になったでしょうか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/7c12453c-05b3-dfe4-c466-6b57003a12ac.png)

ここでは **接続済** にならなくてもＯＫです。後ほど別の方法をご紹介します。
次の確認にすすみましょう。

## フローの改造

**RS485**ノードと **test.mosquitto.org** ノードが接続済みになったので、1秒ごとにRS-485で入力される圧力データが10秒ごとにMQTTブローカーに送信されているはずです。

MQTTサブスクライブしてそのデータを受信してみましょう。
一度、MQTTブローカーにサブスクライブしておくと、以降パブリッシュがある度に、MQTTブローカーがパブリッシュされたデータを転送してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/c303654f-7f4f-06f2-7ee7-f666e10a0607.png)

本来、サブスクライブは別クライアントで行うべきでしょうが、今回は Node-RED での説明を兼ねて、今まで使ってきたフローを２つに分けて、上の図のMQTTクライアント １と２を Node-RED の１つのワークスペース上に実装します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/b898dabe-c8eb-114f-19b5-d4071255b113.png)

上のフローはセンサーデータを収集してクラウドにアップロードするエッジゲートウェイを想定しています。

RS485ノードからの圧力データはそのままダッシュボードに表示せず、MQTTブローカーにパブリッシュするだけにします。

そして下のフローは、エッジからのデータを受信してダッシュボード表示するWebアプリケーションを想定しています。
MQTTブローカーから転送された圧力データを受信してダッシュボードに表示します。

作業内容としては **mqtt in** ノードを新規に追加して、**gauge** と **chart** ノードをこちらにつなぎ替えるだけです。

ダッシュボードのプロットが10秒に1回になれば、MQTTサブスクライブが確認できるはずです。

## MQTTサブスクライブノード

それでは**mqtt in** ノードを追加・設定しましょう。
パレットから下図のノードをワークスペースにおいて、ダブルクリックです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/cd5da030-6903-89dc-45ad-bf40163ddeac.png)

**サーバ**にはすでに **test.mosquitto.org:1883** と入っているはずです。
（違う場合、ドロップダウンメニューで選択してください。）
**トピック**名にはパブリッシュ側の **mqtt out** ノードに設定した **ae2100/pressure** を入力します。
**出力**はデフォルトの自動判定のままにして、文字列として受信するようにします。
**名前**は **test.mosquitto.org** とでもしておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/ef3de124-6864-f3a8-c40b-603163c28dde.png)

最後に、RS485ノードに接続している **gauge** と **chart** のワイヤーを削除して、以下のように今追加した **mqtt in** ノードの右に置き、接続し直します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/644d3d90-03db-905e-6e82-3d7f753e6d3e.png)


以上で設定は終わりです。**デプロイ** をクリックして、保存・実行してみてください。
ダッシュボードに10秒に1回、圧力値がプロットされるはずです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192538/84640c21-c600-9f93-c25a-445e53d8fc7b.png)

## test.mosquitto.org に接続できない！

実はこの無料サーバーは時々つながらない事があります。
このサーバーはMQTTブローカーのリファレンス実装を公開している **mosquitto.org** により運用されているのですが、我々MQTTクライアント側がテストのために使用する目的だけでなく、MQTTブローカー自体をテストする目的でも使われており、不安定になったり、ダウンすることがあるそうです。

運悪くちょうどダウンしている場合、2,3日待ってトライしてみてください。
いや、今すぐ試してみたい！場合、[このサービス](https://mqtt.uko.jp/)はいかがでしょうか。
毎日パスワードを変更する必要がありますが、登録なしに無料で使えます。
もしくは **node-red-contrib-mqtt-broker** ライブラリを追加して、[Node-RED上でMQTTブローカーを立ち上げる](https://qiita.com/zuhito/items/d8ac0f602e0f09b02eac)方法もあります。

# さいごに

AE2100 によるローコードIoT開発、いかがだったでしょうか。
今回のサンプルアプリはローコードどころか、ノーコードでできてしまいました。

インタラクティブにアクセスする手段がSSHクライアントかXサーバー経由くらいしかないAE2100の使い方として、他のマシンでコンテナ内にアプリを作って、AE2100にそれをデプロイして実行するのが通常だと思います。

しかしNode-REDが動くと、AE2100で直接開発しても全く苦にならず、特に今回のシリアル通信のようなAE2100のハードウェアを使う場合、AE2100で直接開発することになるので、Node-RED は大きな助けになるはずです。

確かにNode-REDはメモリ食いだし、処理速度も速いとは言えないのですが、1秒くらいのレスポンスなら十分ではないでしょうか。
（まずNode-REDでぱぱっと作ってみて、処理速度が足りなさそうだったら、Node.jsやC言語で作り直す、というやり方もあるでしょう。）

これで4編にわたる記事もようやく終わりになります。
こんなに長くなるとは思わなかったのですが、AE2100 のユーザーのみなさんに少しでもお役に立てば幸いです。
最後の最後にお約束ですが、本記事に関してOKIは何も関知しないので、記事の内容に関してOKIに問い合わせることがないようにお願いいたします。