ThingSpeakにNode-Redから接続してみた

IoTの可視化、分析ツールであるThingSpeakについて調べて接続してみましたので手順をまとめました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/8ea6437c-f628-253e-56e9-8cd11fc5d679.png)


###ThingSpeakとは
IoTプラットフォームであり、クラウドでセンサーのデータを収集及び保存したり、IoTアプリ、apiを開発することができるデータ収集及び解析用のプラットフォームです。アクションを起こしたり（ダウンリンク）することもできます。商用利用でなければ、多少の制限付きで無償で使用することができます。

具体的には
・データの収集
・データの分析
・反応をトリガー

を行うことができますが
今回は

・ThingSpeakの登録
・データの送信
・データの可視化
までを行います。

ThingSpeakの推奨ブラウザはGoogleクロームであり、
クッキー、ポップアップ、Javascriptを有効にしておく必要がありますので、設定しておきます。

まずは[ThingSpeak](https://thingspeak.com)の公式ページへアクセスして新しくアカウントを作成します。
トップページにあるGet Started For Freeボタンを押します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/5e059258-2bf9-b0f6-6403-15514a2c2795.png)

メールアドレスの確認画面に行きますので、Create one!を押して新しくメールアドレスを登録していきます。

下のような画面に遷移しますので、メールアドレス、使用する国、名前を入力してContinueボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/731c1285-5bb3-b3ce-d918-1653d2e33218.png)

Gmailなどで登録すると
組織のメールアドレスを入力するように出ますが、個人のアカウントで良いと返事します。

確認用のメールが届きますので、中のリンクをクリックして、新しくパスワードを作成します。

ThingSpeakの中ではチャンネルという単位で操作していきます。
ここでチャンネルとはThingSpeakアプリケーションが収集するすべてのデータが保存されるところです。
各チャンネルには任意のタイプのデータを保持できる8つのフィールドに加えて、位置データ用のフィールドとステータス用の1つのフィールドが含まれています。
チャンネルで収集したデータはThingSpeakアプリを使用してデータを視覚化及び分析をすることができます。
New Channelをクリックして新しくチャンネルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/34473cab-f530-f71d-bb8e-3932ebe88f61.png)

このチャンネルの中ではJSON, XML, CSVのデータが扱え、他にも位置情報を使用すること、チャンネル情報を動画で確認することもできそうです（試していないので定かではありません）。
NewChannelをクリックして新しいチャンネルを作成していってください。

今回は最低限の機能だけ実装していきますので、チャンネルの名前と概要、feildには何のデータを入れていくかを書いてください。
今回は温度と湿度を入れてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/8a3834d6-8a71-7e9d-c58d-4ecce75eaf5a.png)

一番下のsave Channelボタンをクリックするとチャンネルが使用できるようなります。

ここからはデータの送信のための準備をしていきます。
データの送信にはAPIkeyが必要なので確認していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/3145f484-6d2a-0629-af43-cfa8edba4213.png)

タグの右から二番目APIkeysをクリックして入っていきます。
表示されたページで出てくるWrite API keyをデータ送信の際に使用するので確認します。
さらに右側にAPIの使用方法が書いてあるのでコピペして試してみます。Write a Channel Feedを試してみるのが分かりやすいと思います。
GETを除いてコピーして、ブラウザのhttpを入力をするところにペーストをしてエンターを押すとグラフに反映されます。
一応APIの記入例も書いておきます。

```
https://api.thingspeak.com/update?api_key=hogehoge&field1=0
```
※hogehogeのところにAPIkeyが入ります。

このようにグラフに反映されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/03fdfa68-35fc-c621-0a12-0ae1a44450f4.png)
これでAPIを通してデータを送信できることが確認できました。

ここからはNode-Redでの作業になります。
マイコンから直接httpのAPIをたたいてもよいのですが、普段からMQTTを利用して環境データを取得していますので、その構成を流用します。
データの流れとしては
ESP32 -> MQTT -> Node-Red -> ThingSpeak
という風になっていますので参考にされてみてください。
（今回はinjectノードでダミーデータを挿入して動かします）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/2614a7c9-d5b2-3649-9454-e12a5d2f58a4.png)

Node-Redとはビジュアルプログラミングツールです。詳しくは[こちら](https://nodered.jp/docs/)を参考にしてください。
Node-redのノードの中にThingSpeak用のツールがあったのでそれを利用することにします。

Node-Redの画面の右上のハンバーガーメニューからパレットの管理を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/4c0b9572-3510-83db-3f34-5c19df9a42e9.png)
ノードの追加でthingspeakで検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/676dca65-0eb2-167b-81a7-8f767a60e0f9.png)
いくつか出てきますが、node-red-contrib-thingspeak42 を選択してノードを追加してください。
詳しくはこちらを参照してインストールしてください。https://flows.nodered.org/node/node-red-contrib-thingspeak42

今度はデータを送信する準備をします。
インストールされたThingSpeakのノードをフローに配置して設定を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/b9486c0b-6743-8c4f-ffa6-119e0bfaefc4.png)
ここでいうdelayとはデータの待ち合わせのために、データをThingSpeakに送るまでの待ち時間と考えてください。設定できますので自分が妥当だと思われる時間に設定してください。
APIURLにはThingSpeakのURLであるhttps://thingspeak.com　を入力します。
APIKeyには先ほど確認したWrite API keyを書き込みます。
TopicというのはThingSpeakで設定したfeedに相当しますので、齟齬が出ないように番号を設定してください。
これでThingSpeakにNode-Redからデータを送信する準備が整いました。
送信するデータですが、今回はわかりやすいようにchangeノードで温度、湿度別々に取り出しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/95749ea2-8fd6-d695-3b89-4f539c4c38de.png)

そこからThingSpeakに送信できるように整形します。
ThingSpeakノードの中ではtopicで判定されるので、送信データにtopic情報を付加します。
私の場合はfunctionノードで情報を付加しました。
参考までにfunctionノードの中身です

```
msg.topic =1
var newMsg = 
{ 
    topic:msg.topic,
    payload: msg.payload
    
 };
return newMsg;
```
これで送信する準備が整いました。
フローの状態はこのようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/2a53ffa3-1e73-243f-62ea-993b857faa1b.png)

inject nodeを利用してダミーデータ(JSON)を入れます。
(例)　{"temp":22.5,"humi":65}

これでThingSpeakにNode-Redからデータを送信することが出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244155/0f25f464-1831-0006-f08a-b42e5d8c595b.png)

最後にフロー作成用のJSONを置いておきます。JSONを読み込む前にThingSpeakのノードをインストールしておくことを強く推奨します。

```
[{"id":"7fc43a1b.5d1944","type":"change","z":"f9032024.b21a2","name":"温度","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.temp","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":200,"wires":[["4645f814.f49a28"]]},{"id":"339c943d.83ff2c","type":"change","z":"f9032024.b21a2","name":"湿度","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.humi","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":510,"y":240,"wires":[["d119a149.b0d59"]]},{"id":"4645f814.f49a28","type":"function","z":"f9032024.b21a2","name":"topiictest_mono_1","func":"//msg.payload = 10\nmsg.topic =1\nvar newMsg = \n{ \n    topic:msg.topic,\n    payload: msg.payload\n    \n };\nreturn newMsg;","outputs":1,"noerr":0,"x":680,"y":200,"wires":[["2fe3b24f.1d2bde","183d9bdc.ed4694"]]},{"id":"d119a149.b0d59","type":"function","z":"f9032024.b21a2","name":"topiictest_mono_2","func":"//msg.payload = 10\nmsg.topic =2\nvar newMsg = \n{ \n    topic:msg.topic,\n    payload: msg.payload\n    \n };\nreturn newMsg;","outputs":1,"noerr":0,"x":680,"y":240,"wires":[["2fe3b24f.1d2bde","183d9bdc.ed4694"]]},{"id":"d9dc909d.27282","type":"inject","z":"f9032024.b21a2","name":"","topic":"","payload":"{\"temp\":22.5,\"humi\":65}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":260,"y":220,"wires":[["7fc43a1b.5d1944","339c943d.83ff2c"]]},{"id":"2fe3b24f.1d2bde","type":"debug","z":"f9032024.b21a2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":990,"y":180,"wires":[]},{"id":"183d9bdc.ed4694","type":"thingspeak42","z":"f9032024.b21a2","name":"","delay":"5","topic1":"1","topic2":"2","topic3":"3","topic4":"4","topic5":"5","topic6":"","topic7":"","topic8":"","endpoint":"https://thingspeak.com","x":990,"y":240,"wires":[]},{"id":"36f5da03.20db16","type":"comment","z":"f9032024.b21a2","name":"ダミーデータの投入","info":"","x":250,"y":140,"wires":[]},{"id":"1c8a6a65.67ef36","type":"comment","z":"f9032024.b21a2","name":"データを分割して整形する","info":"","x":570,"y":140,"wires":[]},{"id":"b2712b30.6aaba8","type":"comment","z":"f9032024.b21a2","name":"デバッグ用の表示","info":"","x":1010,"y":140,"wires":[]}]
```

###参考サイト
[公式ドキュメント](https://jp.mathworks.com/help/thingspeak/index.html)
[iwathiの/var/log](http://iwathi3.hatenablog.com/entry/Data-to-Graph-ThingSpeak)
https://flows.nodered.org/node/node-red-contrib-thingspeak