Node-RED MCU EditionでIoTしてみた。

# はじめに

Node-RED MCU Editionの環境構築、簡単なフロー、Lチカ、ネットワーク接続(HTTP, MQTT)まで終わったので、組み合わせと連動(IoT)を試してみます。

環境構築と動作確認については以下を参照してください。

https://qiita.com/kitazaki/items/15cba2f4622bf3682083

GPIOの動作確認については以下を参照してください。

https://qiita.com/kitazaki/items/bac2b860b7d26fb450f4

ネットワーク接続(HTTP, MQTT)については以下を参照してください。

https://qiita.com/kitazaki/items/9b93992f6c342828e8f8

# 前提条件

- Intel MacBook Pro (2017)
- macOS Big Sur (バージョン 11.7)
- M5Stick-C
  - LED(GPIO10)
- HTTPサーバ、ダッシュボード (Node-RED, Dashboard)
- MQTTサーバ (Aedes MQTT broker)

# 構成

クラウド上のNode-REDでダッシュボードを作成し、スマートフォンからアクセスします。
ダッシュボード上の「ON」または「OFF」のボタンを押すとNode-REDのMQTT Broker経由でM5Stick-Cにデータが届きます。
データの内容に応じてM5Stick-CのLEDが点灯または消灯します。

![スクリーンショット 2022-10-13 20.47.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/fa05ce3f-6566-633f-d1a9-5a200be50b6f.png)

# Node-REDフローを作成する (HTTPサーバ, MQTTサーバ)

ダッシュボードとMQTTサーバはノードの追加が必要になります。
右上のメニューから「パレットの管理」→「ノードを追加」タブを選択します。
「ノードを検索」のフォーム入力から以下のノードを入力し、「ノードを追加」ボタンを押します。
ポップアップメッセージが表示されますので、「追加」を選択します。

- node-red-dashboard
- node-red-contrib-aedes

ノードの追加が終わったあと、以下のフローを作成します。
MQTTで送受信するデータは、Node-RED MCU Editionがサポートしているデータタイプに制限があるため、JSONフォーマットを使用します。

![a-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/8f7c4fe2-62d8-a6f1-edd3-6d3164463beb.jpeg)

![スクリーンショット 2022-10-13 20.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/28bd2019-699b-be17-6c50-e13d44fc251c.png)

(サンプルフロー)

```json:flows.json
[{"id":"f2cdbff0e8dc76fd","type":"tab","label":"フロー 1","disabled":false,"info":"","env":[]},{"id":"c2ec89c692ba2f71","type":"inject","z":"f2cdbff0e8dc76fd","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":260,"y":180,"wires":[["81981d58f7d14f69"]]},{"id":"81981d58f7d14f69","type":"debug","z":"f2cdbff0e8dc76fd","name":"debug 1","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":440,"y":180,"wires":[]},{"id":"aa79e518924f43b8","type":"http in","z":"f2cdbff0e8dc76fd","name":"","url":"/status","method":"get","upload":false,"swaggerDoc":"","x":250,"y":60,"wires":[["9a82e00c0cad5ccc","7b415c82f15e924c"]]},{"id":"9a82e00c0cad5ccc","type":"change","z":"f2cdbff0e8dc76fd","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{\"status\":\"ok\",\"message\":\"health endpoint\"}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":60,"wires":[["77a70795471228f6"]]},{"id":"77a70795471228f6","type":"http response","z":"f2cdbff0e8dc76fd","name":"","statusCode":"","headers":{},"x":650,"y":60,"wires":[]},{"id":"7b415c82f15e924c","type":"debug","z":"f2cdbff0e8dc76fd","name":"debug 2","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":440,"y":100,"wires":[]},{"id":"db538d38c6f04527","type":"aedes broker","z":"f2cdbff0e8dc76fd","name":"","mqtt_port":1883,"mqtt_ws_bind":"port","mqtt_ws_port":null,"mqtt_ws_path":"","cert":"","key":"","certname":"","keyname":"","dburl":"","usetls":false,"x":250,"y":260,"wires":[["f3c22c6272ac56da"],["a3238c0710b0a66a"]]},{"id":"f3c22c6272ac56da","type":"debug","z":"f2cdbff0e8dc76fd","name":"debug 3","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":480,"y":240,"wires":[]},{"id":"a3238c0710b0a66a","type":"debug","z":"f2cdbff0e8dc76fd","name":"debug 4","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":480,"y":280,"wires":[]},{"id":"bd60d3fcf2f3eeda","type":"mqtt in","z":"f2cdbff0e8dc76fd","name":"","topic":"/test","qos":"2","datatype":"json","broker":"61e4e665807b8674","nl":false,"rap":true,"rh":0,"inputs":0,"x":290,"y":340,"wires":[["276f14da304fe886","db1a2d121e115ac7"]]},{"id":"b1413c150ea3a010","type":"mqtt out","z":"f2cdbff0e8dc76fd","name":"","topic":"/test","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"61e4e665807b8674","x":530,"y":520,"wires":[]},{"id":"6859c48a64c86d84","type":"inject","z":"f2cdbff0e8dc76fd","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":320,"y":460,"wires":[["b1413c150ea3a010"]]},{"id":"276f14da304fe886","type":"debug","z":"f2cdbff0e8dc76fd","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":480,"y":340,"wires":[]},{"id":"7b4df15ccdaf2ed8","type":"inject","z":"f2cdbff0e8dc76fd","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"data\":0}","payloadType":"json","x":340,"y":520,"wires":[["b1413c150ea3a010"]]},{"id":"49458d781d9a9388","type":"inject","z":"f2cdbff0e8dc76fd","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"data\":1}","payloadType":"json","x":340,"y":560,"wires":[["b1413c150ea3a010"]]},{"id":"db1a2d121e115ac7","type":"change","z":"f2cdbff0e8dc76fd","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.data","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":400,"wires":[["fb747e5f1c083e68"]]},{"id":"fb747e5f1c083e68","type":"debug","z":"f2cdbff0e8dc76fd","name":"debug 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":580,"y":400,"wires":[]},{"id":"d3c6fe6dd47d627a","type":"ui_button","z":"f2cdbff0e8dc76fd","name":"","group":"88f7f89ad10da37a","order":0,"width":0,"height":0,"passthru":false,"label":"ON","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"{\"data\":0}","payloadType":"json","topic":"topic","topicType":"msg","x":350,"y":620,"wires":[["b1413c150ea3a010"]]},{"id":"f393e9b75cdd168a","type":"ui_button","z":"f2cdbff0e8dc76fd","name":"","group":"88f7f89ad10da37a","order":0,"width":0,"height":0,"passthru":false,"label":"OFF","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"{\"data\":1}","payloadType":"json","topic":"topic","topicType":"msg","x":350,"y":660,"wires":[["b1413c150ea3a010"]]},{"id":"61e4e665807b8674","type":"mqtt-broker","name":"","broker":"localhost","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"88f7f89ad10da37a","type":"ui_group","name":"デフォルト","tab":"74089a8bbfc4e126","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"74089a8bbfc4e126","type":"ui_tab","name":"ホーム","icon":"dashboard","disabled":false,"hidden":false}]
```

スマートフォンからアクセスするダッシュボード画面は以下のようになります。

![スクリーンショット 2022-10-13 20.33.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/322e35a1-8d31-def3-aee8-72d259190761.png)

# Node-REDフローを作成する (Node-RED MCU Edition)

以下のフローを作成します。
(「inject」ノードと「delay」ノードと「change」ノードのフロー部分は動作確認の目的です)

![スクリーンショット 2022-10-13 20.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/63c017d8-4f56-5fb5-ad54-35a767f8ee2a.png)

(サンプルフロー)

```json:flows.json
[{"id":"7d57cd6fa229428c","type":"tab","label":"フロー 5","disabled":false,"info":"","env":[],"_mcu":{"mcu":true}},{"id":"2194d6f189522a96","type":"rpi-gpio out","z":"7d57cd6fa229428c","name":"LED","pin":"10","set":true,"level":"1","freq":"","out":"out","bcm":true,"_mcu":{"mcu":true},"x":610,"y":180,"wires":[]},{"id":"ed1b1cd7c316e93f","type":"inject","z":"7d57cd6fa229428c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"0","payloadType":"num","_mcu":{"mcu":true},"x":250,"y":180,"wires":[["ed98c4f37b36ddf1","2194d6f189522a96","aa7c6f65ee4d2981"]]},{"id":"ed98c4f37b36ddf1","type":"delay","z":"7d57cd6fa229428c","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"_mcu":{"mcu":true},"x":300,"y":280,"wires":[["16ab8af91fd8ddd3"]]},{"id":"16ab8af91fd8ddd3","type":"change","z":"7d57cd6fa229428c","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"_mcu":{"mcu":true},"x":500,"y":280,"wires":[["2194d6f189522a96","aa7c6f65ee4d2981"]]},{"id":"9604dd20272e3d2a","type":"debug","z":"7d57cd6fa229428c","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","_mcu":{"mcu":true},"x":620,"y":60,"wires":[]},{"id":"94daa6e677673297","type":"mqtt in","z":"7d57cd6fa229428c","name":"","topic":"/test","qos":"2","datatype":"json","broker":"665ff2e6a0788b07","nl":false,"rap":true,"rh":0,"inputs":0,"_mcu":{"mcu":true},"x":250,"y":60,"wires":[["9604dd20272e3d2a","92c5af5e2d3d9224"]]},{"id":"aa7c6f65ee4d2981","type":"debug","z":"7d57cd6fa229428c","name":"debug 6","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","_mcu":{"mcu":true},"x":700,"y":240,"wires":[]},{"id":"92c5af5e2d3d9224","type":"change","z":"7d57cd6fa229428c","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.data","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"_mcu":{"mcu":true},"x":420,"y":120,"wires":[["2194d6f189522a96","9604dd20272e3d2a"]]},{"id":"665ff2e6a0788b07","type":"mqtt-broker","name":"","broker":"host01.norahack.tk","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":"","_mcu":{"mcu":false}}]
```

### 「mqtt in」ノード

- サーバ → 編集ボタン(鉛筆マーク)を押して、MQTTサーバ(Aedes MQTT broker)のホスト名とポート番号を入力します
- トピック → /testを入力します (MQTTサーバのトピックと合わせます)
- 出力 → JSONオブジェクトを選択します

![b-1_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/94982929-2598-d87e-7aa0-82498deefb05.png)

![b-2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/8e011593-64c6-c743-4947-9d65656ccba0.png)

### 「change」ノード

- 値の代入 → msg.payloadを入力します。
- 対象の値 → msg.payload.dataを入力します。

![スクリーンショット 2022-10-13 21.26.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/6b0b0f68-00fe-c9d0-b26d-142d51ed11c9.png)

### 「rpi - gpio out」ノード

- BCM GPIO → 10を入力します
- 出力形式 → デジタル出力を選択します
- 端子の状態を初期化 → チェックボックスにチェックを入れます
- 名前 → LEDと入力します

![スクリーンショット 2022-10-13 21.28.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/cb099b59-2dce-5252-c78a-a2019c5aeb2d.png)

# M5Stick-Cへインストールする

以下のページの手順とおりです。

- M5Stick-Cへインストールする
  - node-red-mcu-pluginを使用する場合
  - Node-RED MCU Editionを使用する場合

https://qiita.com/kitazaki/items/9b93992f6c342828e8f8

# 動作確認

スマートフォンからNode-REDのダッシュボードにアクセスし、「ON」または「OFF」ボタンを押すと、M5Stick-CのLEDが点灯または消灯することを確認します。

https://youtu.be/8vf48MHLg_0