Raspberry Pi & Node-REDのnode-red-contrib-ui-heatmapを試してみた

この記事は[Node-RED Advent Calendar 2021](https://qiita.com/advent-calendar/2021/node-red) 18日目の記事です。

# はじめに
今回はヒートマップ表示が気になったのでnode-red-contrib-ui-heatmapを試してみました。

<img width="300px" alt="2020-12-17 21.48.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/8dd79fc9-3c84-306f-83a0-598dada78629.png">


# 利用するデバイス
- Raspberry Pi 3 (2021-10-30 Bullseye をインストール） 2021/12/17現時点で最新

### Raspberry OSのインストール方法が変わっていたのでメモ
https://www.indoorcorgielec.com/resources/raspberry-pi/raspberry-pi-osのインストール/#about-raspberry-pi-os

# 使用したノード
node-red 2.1.4   やったーー最新を試しました。
node-red-contrib-ui-heatmap 2.2.1
node-red-dashboard 3.1.2
node-red-node-base64 0.3.0

# heatmapノードに使われているheatmap.jsはどういうものか
ヒートマップを簡単に作成することができる JavaScript のライブラリです。
昔からあったみたいです。知らなかったw

[詳細は、heatmap.jsのHPを参照してみてね](https://www.patrick-wied.at/static/heatmapjs/)

# フローの全体は次の通りです。（公式のサンプルを流用）
![スクリーンショット 2021-12-16 21.10.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/fa7da391-c834-e4f2-5896-bc971da6db3a.png)


「heat map」の名前のノード箇所がheatmapノードになります。
<img width="260px" alt="cc5260bf-2ef8-f07d-a42f-d89f6cffaccf.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/cc5260bf-2ef8-f07d-a42f-d89f6cffaccf.png">


実行方法の流れはこんな感じです。
- Show heatmapノードのボタンをクリックすることで実行されます。
- Show backgroundノードのボタンをクリックして画像を読み込ませます。
- ヒートマップ表示をダッシュボードでみます。（ここが大事）

heatmapの表示はダッシュボードのWebで確認します。

node-red-dashboardをインストールしていないとheatmapの表示が何も表示しませんし、サンプルを読み込ませると「ノードが無いよ」のエラーが表示されるのでご注意を。

ダッシュボードの表示場所は、heatmapノードの設定を見て、どこに表示されるかGroupの設定を確認します。

<img width="340px" alt="5dea5b07-96d0-7f4b-a9c9-282ff1fe3312.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/5dea5b07-96d0-7f4b-a9c9-282ff1fe3312.png">

ダッシュボードの場所は、デバッグ表示横にあるメニューを開き、ダッシュボードの項目をクリックします。

<img width="340px" alt="2904dcfe-03c4-dce6-af47-0454ae2226a0.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/2904dcfe-03c4-dce6-af47-0454ae2226a0.png">

ダッシュボードの表示に移り、矢印の場所をクリックすると、ダッシュボードのブラウザが表示されます。○の箇所が先程確認したGroupの設定の場所になります。

<img width="340px" alt="38074f90-0976-cb31-2e11-b4b38817c574.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/38074f90-0976-cb31-2e11-b4b38817c574.png">


## 実行するとこのような結果になります
![2021-12-16 20-50-21.2021-12-16 21_31_07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/10a5e94e-fb5a-34cf-9a69-1a79179cb2d0.gif)

# サンプルの方も試してみました。
フローの全体は次の通りです。
![スクリーンショット 2021-12-16 21.39.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/33f9da73-008a-245e-9d9d-01fb9249deb6.png)

実行方法の流れはこんな感じです。
- Show heatmapノードのボタンをクリックすることで実行されます。
- ヒートマップ表示をダッシュボードでみます。（ここが大事）


# 実行するとこのような結果になります
![2021-12-16 20-33-36.2021-12-16 20_34_15.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/a3c2d5a2-2621-9f88-3304-50c2f17cee83.gif)

試したら、Gridの設定と表示するデータの組み合わせが大事だとわかりました。
みなさんもいろんな画像の変更とヒートマップのデータを調整し、試してはいかがでしょうか？

# フローのソースコードです。
```json-doc
[{"id":"84c142151a77ec1c","type":"tab","label":"フロー 1","disabled":false,"info":"","env":[]},{"id":"7938d15ab1e1d76c","type":"function","z":"84c142151a77ec1c","name":"Generate random matrix between limits","func":"// Generate some random data\n// See https://www.patrick-wied.at/static/heatmapjs/example-minimal-config.html\nvar len = 200;\n\nmsg.payload = [];\n\nwhile (len--) {\n    // Generate a random number between min and max (both included)\n    var value = Math.floor(Math.random() * (msg.maximum - msg.minimum + 1) ) + msg.minimum;\n    msg.payload.push(value);\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":580,"y":1040,"wires":[["476733cbdde3a1c7"]]},{"id":"c9401f80d4884529","type":"inject","z":"84c142151a77ec1c","name":"Show heatmap","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"5","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":140,"y":1040,"wires":[["b91a2422efbfdc38"]]},{"id":"476733cbdde3a1c7","type":"ui_heat_map","z":"84c142151a77ec1c","group":"9edbe6bb.223538","order":0,"width":"6","height":"5","name":"","rows":"20","columns":"10","minMax":false,"minimumValue":0,"maximumValue":0,"backgroundType":"color","backgroundColor":"#ffffff","image":"never","radius":40,"opacity":0.6,"blur":0.85,"showValues":false,"gridType":"none","valuesDecimals":0,"showLegend":false,"legendType":"none","legendDecimals":0,"legendCount":2,"x":840,"y":1040,"wires":[[]]},{"id":"b91a2422efbfdc38","type":"change","z":"84c142151a77ec1c","name":"Set limits","rules":[{"t":"set","p":"minimum","pt":"msg","to":"10","tot":"num"},{"t":"set","p":"maximum","pt":"msg","to":"90","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":1040,"wires":[["7938d15ab1e1d76c"]]},{"id":"3871c674f0cc04b8","type":"function","z":"84c142151a77ec1c","name":"Generate room pattern","func":"// Generate some random data\n// See https://www.patrick-wied.at/static/heatmapjs/example-minimal-config.html\nmsg.payload = [];\n\nconst values = [4, 15, 22, 29, 36, 43, 46];\n\nvar index = context.get('value_index') || 0;\n\nif (index >= 8) {\n    index = 0;\n}\n\nfor (var i = 0; i < 49; i++) {\n    if ( i === values[index]) {\n        msg.payload.push(100);\n    }\n    else {\n        msg.payload.push(0);\n    }\n}\n\nindex += 1;\ncontext.set('value_index', index);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":720,"y":640,"wires":[["12531a039b1c30f6"]]},{"id":"1a44add7a7bda89a","type":"inject","z":"84c142151a77ec1c","name":"Show heatmap","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"1","crontab":"","once":true,"onceDelay":0.1,"topic":"","payloadType":"date","x":460,"y":640,"wires":[["3871c674f0cc04b8"]]},{"id":"f94c06e360700d56","type":"inject","z":"84c142151a77ec1c","name":"Show background","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payloadType":"date","x":170,"y":580,"wires":[["b8b908838cd4a625"]]},{"id":"b8b908838cd4a625","type":"http request","z":"84c142151a77ec1c","name":"Download image","method":"GET","ret":"bin","paytoqs":"ignore","url":"https://www.roomsketcher.com/wp-content/uploads/2016/10/1-Bedroom-Floor-Plans.jpg","tls":"","persist":false,"proxy":"","authType":"basic","senderr":false,"x":390,"y":580,"wires":[["2ddd24a3ccab8929"]]},{"id":"f3b5199377d92128","type":"change","z":"84c142151a77ec1c","name":"","rules":[{"t":"move","p":"payload","pt":"msg","to":"image","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":770,"y":580,"wires":[["12531a039b1c30f6"]]},{"id":"2ddd24a3ccab8929","type":"base64","z":"84c142151a77ec1c","name":"","action":"","property":"payload","x":580,"y":580,"wires":[["f3b5199377d92128"]]},{"id":"12531a039b1c30f6","type":"ui_heat_map","z":"84c142151a77ec1c","group":"143de3c.3c1901c","order":0,"width":"7","height":"6","name":"","rows":"7","columns":"7","minMax":false,"minimumValue":0,"maximumValue":0,"backgroundType":"image","backgroundColor":"#ff80c0","image":"never","radius":40,"opacity":"0","blur":0.85,"showValues":false,"gridType":"keys","valuesDecimals":0,"showLegend":false,"legendType":"none","legendDecimals":0,"legendCount":2,"x":960,"y":620,"wires":[[]]},{"id":"9edbe6bb.223538","type":"ui_group","name":"TEST3","tab":"b80caa8e49688817","order":1,"disp":true,"width":"6","collapse":false,"className":""},{"id":"143de3c.3c1901c","type":"ui_group","name":"Heatmap","tab":"4e49ccae.5e3364","order":1,"disp":true,"width":"21","collapse":false,"className":""},{"id":"b80caa8e49688817","type":"ui_tab","name":"ホーム","icon":"dashboard","disabled":false,"hidden":false},{"id":"4e49ccae.5e3364","type":"ui_tab","name":"Heatmap","icon":"dashboard","disabled":false,"hidden":false}]
```

### heatmapノードの設定で気になった箇所。エラーのように表示していますがデプロイはできます。

<img width="600px" alt="415cec3f-c531-0d86-fb36-430970159897.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/415cec3f-c531-0d86-fb36-430970159897.png">

## 公式サンプルは
「フロー読み込み 」画面を開き、左メニューのサンプルをクリックするとインストールしたnode-red-contrib-ui-heatmapが表示されます。あとは試したいサンプルを選択し、読み込みボタンをクリックするればサンプルのノードが表示されます。

<img width="500px" alt="3fb62890-5c39-441f-9fc2-b4f44c220309.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171737/3fb62890-5c39-441f-9fc2-b4f44c220309.png">