さくらIoT x node-RED on Bluemix で会議室の空き状況を表示させるまでの3日間(2日目)

[1日目](http://qiita.com/kkoiwai/items/196cf8136c5a633493c0) では、IBM BluemixにNode-REDを導入し、WebSocketでデータを受信して、Ambientというグラフ表示サービスにデータを連係するところまで進みました。
まだIoT　Platformが届いていないので、2日目では、受信したデータをDBにとりあえず保存するのと、Webサイトを作るところまで行きたいと思います。

目次

- 受信したデータをとりあえずCloudantに保存する
- 今の状態を表示するWebサイトを作る

---
##受信したデータをとりあえずCloudantに保存する

これはもう超簡単です。Cloudantノードを追加して、WebSocket受信ノードから線を引っ張るだけ。Cloudantノードは2つありますが、アイコンが後ろ（右）についているのがCloudantに保存ずるノードです。
<img width="745" alt="スクリーンショット 2017-01-06 18.52.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/135431/7103f48e-dd9f-32cf-a398-8200caffd6f1.png">
ダブルクリックして、設定を開くと、ServiceにはNode-REDの設定が保存されているCloudant DBが自動でセットされているはずです。Database名は、適当につけてください。ただし大文字はだめみたいです。（Databaseが存在しなければ、自動で作成されます。）
<img width="525" alt="スクリーンショット 2017-01-06 19.09.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/135431/085e60d8-d636-8d23-69b4-115b741267e3.png">



---
##今の状態を表示するWebサイトを作る

###画像ファイルの追加
現在の会議室の状態は、1日目でグローバル変数に保存しました。その状態を、Webサイトから簡単に参照できるようにしたいと思います。
画像で見せた方が一覧性がよいと思ったので、今回は[いらすとやさんからドアの画像](http://www.irasutoya.com/2016/07/blog-post_832.html)を使わせていただきます。
まず、今回利用する画像をサーバにアップします。1日目にpackage.jsonを編集したときと同じように、GitHubに作成したレポジトリ上の、/public/imagesディレクトリに、画像ファイルをアップします。
<img width="1011" alt="スクリーンショット 2017-01-06 19.02.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/135431/b7e52aec-565a-cc58-10b5-34d5a7401b10.png">
コミットすると、自動でデプロイが走るので、数分待ちます。

---

###html作成部分
実際にhtmlを表示する部分も、ノードの組み合わせで簡単に作れます。Inputの中のhttpから、outputの中のhttpにノードをつなげていくと、inputに指定したURLへのリクエストを出力できます。
<img width="729" alt="スクリーンショット 2017-01-06 19.11.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/135431/72495ba9-9bac-e0f0-6179-e2c9369c8321.png">

``` json
[{"id":"b216fb73.727028","type":"http in","z":"396465eb.1d8e22","name":"index (\"/\")","url":"/","method":"get","swaggerDoc":"","x":104,"y":1049,"wires":[["20622690.51ddba"]]},{"id":"fa304d55.42125","type":"template","z":"396465eb.1d8e22","name":"index ページのHTML","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"<head>\n    <meta charset=\"utf-8\" />\n    <title>会議室状況表示</title>\n    <!-- Latest compiled and minified CSS -->\n    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css\" integrity=\"sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u\" crossorigin=\"anonymous\">\n    \n    <!-- Optional theme -->\n    <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css\" integrity=\"sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp\" crossorigin=\"anonymous\">\n    \n    <!-- Latest compiled and minified JavaScript -->\n    <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js\" integrity=\"sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa\" crossorigin=\"anonymous\"></script>\n    <style type=\"text/css\">\n\n</style>\n</head>\n<body>\n    <div class=\"container\">\n\n      <div class=\"page-header\">\n        <h1>会議室状況表示</h1>\n      </div>\n     \n     <h2>現在の空き状況</h2>\n      <table class=\"table table-bordered\">\n            <thead>\n              <tr>\n                <th>会議室A</th>\n                <th>会議室B</th>\n                <th>会議室C</th>\n                <th>会議室D</th>\n                <th>会議室E</th>\n                <th>会議室F</th>\n              </tr>\n            </thead>\n            <tbody>\n\n              <tr>\n                <td><img src=\"/images/{{payload.img_0}}\" class=\"img-responsive\" /></td>\n                <td><img src=\"/images/{{payload.img_1}}\" class=\"img-responsive\" /></td>\n                <td><img src=\"/images/{{payload.img_2}}\" class=\"img-responsive\" /></td>\n                <td><img src=\"/images/{{payload.img_3}}\" class=\"img-responsive\" /></td>\n                <td><img src=\"/images/{{payload.img_4}}\" class=\"img-responsive\" /></td>\n                <td><img src=\"/images/{{payload.img_5}}\" class=\"img-responsive\" /></td>\n              </tr>\n\n              <tr>\n                <td>{{payload.status_0}}</td>\n                <td>{{payload.status_1}}</td>\n                <td>{{payload.status_2}}</td>\n                <td>{{payload.status_3}}</td>\n                <td>{{payload.status_4}}</td>\n                <td>{{payload.status_5}}</td>\n                \n              </tr>\n           \n            </tbody>\n          </table>\n   \n   </div>\n</body>","x":496.4285583496094,"y":1049.3214111328125,"wires":[["e53ef283.a18638"]]},{"id":"bca1b030.f372a8","type":"comment","z":"396465eb.1d8e22","name":"indexページ","info":"","x":93.375,"y":1003.9999961853027,"wires":[]},{"id":"20622690.51ddba","type":"function","z":"396465eb.1d8e22","name":"Arrayから値を取得","func":"var pdata = {};\nfor(var i = 0; i < 6; i++) { \n    \n    var img = \"img_\" + i;\n    var stat = \"status_\" + i;\n    \n    if(context.global.data[i]>0){\n        pdata[img] = \"room_closed.png\";\n        pdata[stat] = \"満室\";\n    }else{\n         pdata[\"img_\"+i] = \"room_open.png\";\n         pdata[\"status_\"+i] = \"空室\";\n    }\n}\n\n\nmsg.payload = pdata;\nreturn msg;","outputs":1,"noerr":0,"x":284.4285888671875,"y":1048.857177734375,"wires":[["fa304d55.42125"]]},{"id":"e53ef283.a18638","type":"http response","z":"396465eb.1d8e22","name":"","x":670.1428833007812,"y":1049.0714111328125,"wires":[]}]
```

こちらを例のごとくコピペしてみてください。
たぶん説明が必要になるのはfunctionノードとtemplateノードです。

---

functionノードでは、Global変数を参照して、html内で動的に変わる部分をmsg.payloadに格納しています。
後でも出てきますが、Node-REDでは、ノード間の連携はmsgオブジェクトを送り合うことで実現しているようです。特に重要なのがmsg.payloadというオブジェクトで、このpayloadオブジェクトにほとんどの情報が入っています。msgの中には、payload以外の情報も任意に格納できます。たとえばurl取得ノードには、msg.urlとmsg.methodを指定してあげるといった使い方をします。また、payload以外は、明示的に値を変更しなければ後ろのノードにどんどん引き継がれるので、複数のノード間で情報を連携したいときにはpayload以外の部分に情報を格納するといった使い方ができるようです。
詳しくは私もまだよく分からないので、ググっていただければ。
<img width="516" alt="スクリーンショット 2017-01-06 19.16.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/135431/ec2619ab-50f8-1465-1175-41037fd05673.png">

---

templateノードでは、送られてきたmsg.payloadの中身を参照して、テンプレートに当てはめることができます。見ていただけると分かるとおり、波括弧2つで囲った中に変数名を指定すると、変数が展開されます。下にあるFormatをPlain textにすると変数が展開されないので要注意。
<img width="762" alt="スクリーンショット 2017-01-06 19.17.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/135431/1e90903d-9c34-2e22-e380-c8bcea0b20df.png">

---

以上で、Node-REDのURLにアクセスしてみてください。
こんな感じで、サイトが作成できたと思います。
<img width="799" alt="スクリーンショット 2017-01-06 19.27.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/135431/2ee337bf-1be7-ff03-3d1e-2b38a8d0deb7.png">

ちなみに、Node-REDの設定画面に飛べなくなったと困った方、安心してください。
URLの後ろに /red/ をつければ大丈夫です。 

3日目では、Arduinoの接続と、統計情報の更新まで行きたいのですが、果たしてIoT Platformは届くのでしょうか・・・

(ちゃんと届きました。）

---

##[2.5日目](http://qiita.com/kkoiwai/items/d058c47ef75101088f93)に続く