Node-RED MCUで Kintoneに直接SSL/TLSを使ったセキュアな通信を行う

　Node-RED MCUでSSL/TLSを使った認証と暗号化の仕組みを使ってセキュアな通信ができるようになりました。事例にもよりますが、これまでマイコンデバイスから一旦エッジサーバを介してセキュアな通信を行っていたケースでもマイコンデバイスから直接セキュアな通信を行うといったように、システムをシンプルにできる可能性があります。
 
<img width="780" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/d9cb8062-3021-901f-901b-09c702a68781.png">

 ・この記事は、実際の事例としてマイコンデバイスからSSL/TLSを使用してKintoneにセンサーデータを蓄積する事例を紹介するものです。以下の取り組みの概要の記事からの実例の紹介です。

https://qiita.com/mshioji/private/00dd35a14e20df84c0d4

これに使用した、[Node-RED MCU Editionについてはこちら](https://github.com/phoddie/node-red-mcu/blob/main/readme.md)をご覧ください。

https://github.com/phoddie/node-red-mcu/

また、この内容は@kitazakiさんの記事で紹介されている書籍、補足書とも連動しています。

https://qiita.com/kitazaki/items/0768eb7484ee3c27f6e1

http requestノードについては@utaaniさんの記事が詳細な所まで丁寧に解説されています。

https://qiita.com/utaani/items/a4ea0cba414f63adf09f

上記の記事で紹介されているNode-REDのhttp requestノードがNode-RED MCUで小さなマイコンデバイスで動作するように変換されますが、それを使用してセキュアな通信を実行している事例を紹介しているのがこの記事という形になります。

:::note info
ここではコンピュータ上で操作するコマンド等はUbuntuを事例として紹介します。お試しの場合は、お使いのシステムに応じて読み替えてください。
:::

## KintoneにM5Stackデバイスから直接アクセスする
　デバイスからセンサデータを送信するクラウドサービスとしてCybozu社のKintoneを使います。Kintoneではtokenを取得するとAPIを使ってデータを送ることができます。M5 StackのようなマイコンデバイスからWiFiでネットワークに接続してkintoneのデータベースに直接センサデータを保存してみましょう。

### Kintone側の準備
　Kintoneのアカウントがない場合は次のリンクから新規作成します。
30日間の無料お試し期間も用意されています。https://kintone.cybozu.co.jp/
#### 1. Kintone アプリの作成
　Kintoneではコードを書かずに必要項目を設定するだけでアプリを作成します。
「環境モニタ」という名称で、送られてきた温度と湿度のデータを保存するアプリを作成してみます。
  ・ドメインを指定してCybozu社のサービスにログインし、Kintoneに入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/50558983-b0af-ec5e-08ca-71c7598c38e0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/3694d0dd-4b14-7518-554a-66694fa9ba81.png)
ClickしてKintoneに入ります。

Kintoneに入ったら、「アプリ」の(＋)ボタンを押してアプリストアに入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/7bc50b37-461c-ee04-7235-0c016bd2d014.png)

アプリストアで「新しくアプリを作る」の中の「はじめから作成」をクリックしてアプリを新規作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/18aa8a93-72a1-0047-0f44-5192a2312246.png)

新しいアプリの設定画面でフィールドを作成していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/2a367e98-60ff-4810-da47-30c50f81e660.png)
フィールドをドラッグアンドドロップする事で、アプリを作成する事ができます。

・アプリ名称を「環境モニタ」にします。好みのアイコンを付けることもできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/703246d1-7752-96a4-f75a-2c9b10287e06.png)

　・「日時」フィールドを配置して、日付と時刻を記録する設定にします。
　　一番下の「フィールドコード」に ”datetime”を設定します。この名称でデータの格納場所を判断しますので、送信側の名称と合わせる必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/a6276133-2d51-c017-c3f9-51ef15f44613.png)

・「文字列（１行）」フィールドに「module_id」を保存する設定にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/514cbba9-0c47-f796-b99e-67a5ce5ed7e3.png)
一番下の「フィールドコード」にも ”module_id”を設定します。　

・「数値」フィールドを配置し、「Temperature」を保存する設定にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/dd3815ca-68cb-fec6-3ab9-efee71b90a99.png)
フィールドコードには”temp”を設定します。
お好みに応じて、小数点以下の表示桁数や単位記号を設定します。

・「数値」フィールドを配置し、「Humidity」を保存する設定にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/26d5b30a-cc3c-0abd-1fc0-2d6ceff146aa.png)
同様に、フィールドコードには”humid”、表示桁数と単位記号を設定します。

ここまでの設定ができると、フィールドは以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/0ac8a4c6-e27e-b4e0-4099-05cc8eeea620.png)

・設定ができたら右上の「アプリを公開」ボタンで公開します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/3a9e02a5-4200-cf10-7e2c-ea4af53dff7d.png)

#### 2. APIトークンの作成
　続いて、KintoneにAPIを使ってアクセスするためにAPIトークンを作成します。
・「アプリ設定」の中の「設定」タブから「APIトークン」に入ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/ccd06417-cb11-311a-ebdb-bd107cbc618b.png)

・「生成する」ボタンでトークンを生成し、レコード閲覧、追加、編集を許可します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/14a4338c-5c60-91b3-d817-e81629d0a7b3.png)

・この画面に表示されている「APIを使ったアクセス例」と「APIトークン」を見ると、必要な情報が揃っていますので、Node-RED MCUでの設定のために控えておきます。
１) ドメインを含むアクセス先： https://\< my_domain \>.cybozu.com/k/v1/record.json
２）アプリID :  app= < my_APP_id > 
３）APIトークン：< my_access_token >

・APIトークンの設定ができたら「保存」ボタンを押して設定を終了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/4b97420d-352e-155f-0772-303791af6c19.png)

・アプリ設定画面に戻るので、「アプリを更新」ボタンで設定を反映します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/7f1f0815-ab26-f7f0-0c00-8e39a5df2e20.png)

以上でKintone側の設定は完了です。
次に、控えておいた設定情報を使ってNode-RED MCU側の設定を行います。

### デバイス側の準備
　ターゲットデバイスとしてM5Stack Grayを使用しました。前面パネルに３つのボタンがあるので、中央を手動でのセンサデータ取得、右側をチャートのクリアに割り当てて、以下のようなフローを作成しました。

M5Stack ENV2モジュールのSHT30(温度湿度センサ)からデータを取得し、M5StackのLCDディスプレイにチャート表示するとともに、フロー図の一番下にある「function」ノードを使ってkintone APIの設定とレコード追加の設定を行います。そして、それに続く「HTTP Request」ノードを使ってSSL/TLSを有効にしたセキュアな通信を行い、Kintoneにデータを送信します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/b6bf14ab-e80c-617b-818c-f1c527dc7ed6.png)
　このフローの中でKintoneAPIでのアクセスに関するノードは上図の赤枠で囲んだ部分です。この部分を詳しく解説します。

 「function」ノード　”Kintone API”
```
let access_token = "< my_access_token >";
let application_id = "< my_APP_id >";

let token = {
    "X-Cybozu-API-Token": access_token
}

let record = {
    "app": application_id,
    "record":
    {
        "datetime": { "value": msg.payload.datetime },
        "module_id": { "value": msg.payload.module_id },
        "temp": { "value": msg.payload.thermometer.temperature },
        "humid": { "value": msg.payload.hygrometer.humidity },
    }
}

msg.headers = token;
msg.payload = record;

return msg;
```
１行目と２行目にさきほど控えた< my_access_token >と< my_APP_id >をセットします。通常、Node-REDではAPIキーを含むアクセス権の類の情報は「書き出し」の時にエクスポートされませんが、この例のように「function」ノードに記述すると、APIキーやドメインも一緒に書き出されます。意図しない拡散にはご注意ください。

「HTTP Request」ノードの設定は以下のようになります。
　・メソッドをPOSTに設定
　・URLにkintoneでAPIトークン生成時に控えたドメインを含むアクセス先を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/c1c96619-4e30-d59d-6164-9f13103d5e54.png)

・「SSL/TLS接続を有効化」にチェックを入れて、TLS設定のフィールドの右側にある鉛筆アイコンで設定を作成します。この図では「ローカルファイルの秘密鍵と証明書を使用」にチェックを入れてCA証明書のフィールドに証明書ファイルのパスを設定していますが、このチェックを外して表示されるアップロードアイコンで証明書ファイルをアップロードしても動作します。

・どのCA証明書を指定すれば良いかわからないとき
最も簡単な方法は一旦ビルドして動作させてデバッガxs-bugのエラーメッセージを確認します。
```
$MODDABLE/modules/files/resource/Resource.c (44) 
# Break: Resource: Resource not found: ca176.der!
```
メッセージでは「.der」ファイルが無いと表示されますが、Node-RED側で設定するファイルは同じ名称の「.pem」ファイルを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/f1671154-95d5-3312-6514-d42bf99f3904.png)

これでデバイス側のフローもできました。デプロイして、Node-RED MCUからビルドしてみましょう。

　Kintone上に作成したアプリでは以下のように温度と湿度が保存されています。
デバイスで取得したデータが書き込まれた場合は、そのIDがmodule_idフィールドに記録されます。PC上のNode-REDでデバッグの際にシミュレーション値を送信した場合はmodule_idフィールドには「simulated」と記録されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/23962836-7137-3b27-9dc9-ca4b00d1b2f4.png)

デバイス側ではM5Stackの画面上に温度と湿度のチャートを並べて表示しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/22d6ec54-0188-54d7-1ac1-e4e865173830.png)

筐体をミニ百葉箱に入れるとこのような感じになります。
(Bonito Bonsai大好き”さん設計のミニ百葉箱とのコラボレーション）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3012948/0a1f2233-4f10-0826-8598-3056e0566675.png)

この記事で紹介したフローファイルはGitHubでも公開しています。
https://github.com/mshioji/examples_node-red-mcu

## 関連記事
お待たせしました、Node-RED アドベントカレンダー2023の進行に沿って、各記事へのリンクを更新しました。

https://qiita.com/mshioji/private/bbdd3be9deca253e8267

https://qiita.com/mshioji/items/2d333826570f41009447