Shiftr.ioの画面をNoodlに埋め込んで最強IoTダッシュボードを作る

本記事は、[Noodlもくもく会 ＃0](https://elv.connpass.com/event/148027/)での成果物です。
メンターの@kmaepuさん・@kisaichi07さん、お褒めくださった参加者の皆様ありがとうございました。

---

## TL;DR
**[shiftr.io](https://shiftr.io)の画面を[Noodl](https://tensorx.co.jp/noodl-jp/)に埋め込む**ことができました。
1つの画面で、作ったIoT作品などを操作しながら、通信状況も確認できます。

[サンプルページはこちら](https://kn1cht.github.io/shiftrio-in-noodl-example/)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/4af23f76-ea07-9778-03ba-d946c346f5a9.gif" alt="shiftr.io in noodl" width=320>

## 動機
### [Noodl](https://tensorx.co.jp/noodl-jp/)
Noodlは、ノードを繋いで簡単にUIのプロトタイピングができるスウェーデン発のツールです。
外部との通信も簡単にできてしまうのが凄いところで、MQTTで通信するIoTデバイスとの相性がとても良いです。IoTで使っている例は、@kmaepuさんの[アクアリウム管理IoT](https://speakerdeck.com/maepu/akuarimuguan-li-ribenzibian)などがあります。

筆者は最近入門し、[ESP32](http://akizukidenshi.com/catalog/g/gM-11819/)と通信させたりして遊んでいます。

### [shiftr.io](https://shiftr.io)
無料で使えるMQTTブローカです。別のプログラムやIoTデバイスとNoodlを連携させたい……という願いが数分で叶います。
導入方法については以下の記事をご覧ください。

- [MQTTブローカ"Shiftr.io" 入門](https://qiita.com/kmaepu/items/644b0bf2c3f438e71aa6)

このサービス、シンプルながら通信状況が一目でわかるめちゃくちゃ優秀なダッシュボードが使えます。[shiftr.io/try](https://shiftr.io/try)をご覧になれば分かる通り、どのデバイスが繋がっていてどのtopicにデータを送っているか、リアルタイムで表示されるのです。
動きが面白くてずっと見ていられますし、通信の監視や問題箇所の切り分けにも使えて実用性も十分です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/ae04b5ec-e6bf-73d5-501f-8af3193be087.gif" alt="shiftr.io in noodl" width=400>
無限ループって怖くね？

### 課題：見るべき画面が多すぎる
Noodlとshiftr.ioを組み合わせて何か作ろうとすると、Noodlのエディタ・shiftr.ioの画面・（IoTモノなら）Arduino IDEやシリアル通信のモニタなどを確認しながら作業が進みます。

![many-windows](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/d8b0f036-fbc6-1e36-85ec-9759dfd20dd0.jpeg)


通信できているか確認したいときなどは、Noodlとshiftr.ioを横に並べて見比べなければなりません。割と面倒です。

### shiftr.ioの埋め込み機能を使うと……
ググってもほとんど言及されていませんが、shiftr.ioの画面をよく見るとEmbedなるボタンがあります。
<img width="150" alt="スクリーンショット 0001-10-05 11.00.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/3d926fd2-7d69-d481-f2db-d7eaf6fdc80d.png">
押すと**埋め込みコード**がコピーできる画面に飛びます。
<img width="810" alt="スクリーンショット 0001-10-05 11.01.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/a29b0465-1d68-9cc9-9583-4bd4a6a80cea.png">

ところで、Noodlに`HTML Content`というHTMLを書き込めるノードがあります。
<img width="357" alt="スクリーンショット 0001-10-05 11.03.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/62b3a3d5-3b82-da01-bad0-00c27ab42d0c.png">
これをこうして……
![koushite.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/d6b37928-b927-8056-9c60-ad4f35147794.png)
こうじゃ
( ＾ω＾)
![result-shuchu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/6148e479-f035-6e60-ac42-62515ba96382.png)

## 解説
以降は真面目に解説します。
今回作ったプロジェクトはGitHubで公開しています。

- [リポジトリ（kn1cht/shiftrio-in-noodl-example）](https://github.com/kn1cht/shiftrio-in-noodl-example)
- [サンプルページ（GitHub Pages）](https://kn1cht.github.io/shiftrio-in-noodl-example/)

### HTML Contentにshiftr.ioを表示させる
シンプルなボタンが1つあるだけのプロジェクトを用意しました。Circleを押したとき・離したときに状態が変化し、`/button`トピックにJSONが送信されます。
<img width="1030" alt="スクリーンショット 0001-10-05 11.22.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/75256d9a-6c7e-6546-dcf0-dcce6df5c2a1.png">

HTML Contentを作成して、画面の下半分に配置します。プロパティの`Content > HTML > Edit`からHTMLのエディタが開けるので、shiftr.ioからコピペした埋め込みコードを貼り付けます。

![Oct-05-0001 11-31-02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/8087649c-d36e-7eb7-e489-d31d634f7e9f.gif)


この時点でshiftr.ioの画面が表示され、ブラウザで見るものと同様に表示されているのが分かります。

### 埋め込みコードの修正
生成された埋め込みコードは以下のようになっています。

```html
<!DOCTYPE html>
<iframe src="https://shiftr.io/{user}/{namespace}/embed?zoom=1"
        width="600" height="400" frameborder="0"
        webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
```

`width`と`height`が固定されていますが、Noodlの画面からはみ出してしまったのでそれぞれ100%に修正します。これで`HTML Content`ノード自体のサイズへ従うようになるので、Noodl側だけでレイアウト調整ができます。

また、`webkitallowfullscreen mozallowfullscreen allowfullscreen`の記述があると、埋め込まれた画面内に"Maximize"なるボタンが表示されます。
これを押すとshiftr.ioの画面が最大化されるのですが、Noodl自体がelectron（中身はChromeブラウザ）で作られているため、押すと**Noodlのエディタごと最大化**してしまいます :sweat_smile:

最大化機能が不要であればfullscreen関係の属性は削ってしまいましょう。埋め込まれた画面中にMaximizeボタンが出てこなくなります。

```html
<!DOCTYPE html>
<iframe src="https://shiftr.io/{user}/{namespace}/embed?zoom=1"
        frameborder="0" width="100%" height="100%"></iframe>
```

きちんと画面内に収まっていい感じです。
<img width="240" alt="スクリーンショット 0001-10-05 12.45.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/da6cc0ab-8c5d-3ef6-48f9-ca2b015c16d3.png">

### 完成
これでshiftr.ioでの通信状況をNoodlから閲覧できるようになりました。
背景色や文字色をshiftr.ioに合わせて`#1aaa54`に設定すると統一感が出ます。

<img width="240" alt="スクリーンショット 0001-10-05 12.49.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/b04c3db2-17b8-63bd-b377-2767e5f3dad9.png">

あとは用途に合わせてボタンや表示エリアを作成すればOKです。

### Tips
埋め込んだiframeは、Noodl側で画面サイズを変えても動的にサイズを変えてくれません。
画面サイズを変えたら、**Noodl画面右上の再読み込みボタンを押しましょう**。

![Oct-05-0001 12-55-12.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/589217ec-4493-fc38-77d9-2d8937e9de7a.gif)

埋め込まれたshiftr.io画面でも、本家と同様にデバイスやトピックをドラッグで移動したり、スクロールで拡大縮小したりできます。
![Oct-05-0001 13-00-46.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/a399995a-5ed5-bdb3-72d1-993fb5cf1770.gif)

ただし、何かの弾みで**ドラッグやスクロールが効かなくなる**ことがあります。原因は分かっていませんが、この場合もNoodl側で再読み込みすれば大抵直ります。

## 活用シーン
### 開発や動作確認に
Noodlで作業しながらリアルタイムで繋がっているデバイスや送られているデータを確認できます。
これが想像以上に快適で、動かない時もすぐに原因を把握できる（データが送られてない・マイコンのWi-Fi通信が切れているなど）ので開発がスピードアップすることでしょう。

<img width="1307" alt="スクリーンショット 0001-10-05 13.21.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/f535da54-c43c-aff4-e674-e12bc8c72117.png">

### 勉強会などでのデモに
IoTLTなどで発表していると、いざ壇上でデモしようという時に様々な原因で動かないという「**デモあるある**」が稀によく発生します。特に通信関係でうまくいかないケースは多いので、Noodlで確認できるようにしておくと良さそうです。

Noodlではブラウザでプレビューを表示できますが、同じLANに繋がっていれば他の端末からでもアクセス可能です。
つまり、PCでデモ発表しながら手元のスマホでこっそりモニターするなんてこともできます。

![IMG_4369.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150557/e7416f1a-a19c-38e2-646b-bee41ef37e20.jpeg)

連携がうまく動かない時などの保険として、手動で作品を動かすボタンをつけても面白いと思います。