Watson IoT Platform - サンプルフロー - リアルタイムでIoTセンサーからの値を表示

実際のIoTシステムでは、下記のフローの先頭にMQTTなどで接続されたIoTデバイス・センサーからの入力を接続します。
このサンプルのフローでは、IoTセンサーからの値をシミュレートし、websocketで出力した値をリアルタイムで可視化します。ccchartを使用しています。

#サンプル１ センサーからのIoTデータをリアルタイムで表示する

```lang:IoTデータをリアルタイムで表示
[{"id":"48e2ea18.2d831c","type":"websocket-listener","z":"a9346054.4ad1b","path":"/ws/flow20","wholemsg":"false"},{"id":"db1d6d53.85c758","type":"function","z":"a9346054.4ad1b","name":"センサー値を出力","func":"if (msg.payload === 0 ) {\n    context.set(\"i\", 0);\n}\n\nvar i = context.get('i')||0;\ni += 1;\nvar time =[\"10:00\",\"10:01\",\"10:02\",\"10:03\",\"10:04\",\"10:05\",\"10:06\",\"10:07\",\"10:08\",\"10:09\",\"10:10\",\"10:11\",\"10:12\",\"10:13\",\"10:14\",\"10:15\",\"10:16\",\"10:17\",\"10:18\",\"10:19\",\"10:20\",\"10:21\",\"10:22\",\"10:23\",\"10:24\",\"10:25\",\"10:26\",\"10:27\",\"10:28\",\"10:29\",\"10:30\",\"10:31\",\"10:32\",\"10:33\",\"10:34\",\"10:35\",\"10:36\",\"10:37\",\"10:38\",\"10:39\",\"10:40\",\"10:41\",\"10:42\",\"10:43\",\"10:44\",\"10:45\",\"10:46\",\"10:47\",\"10:48\",\"10:49\",\"10:50\",\"10:51\",\"10:52\",\"10:53\",\"10:54\",\"10:55\",\"10:56\",\"10:57\",\"10:58\",\"10:59\"];\nvar sen1 = [2,8,4,6,0,10,8,4,2,6,10,6,4,8,0,2,10,8,2,8,4,6,10,2,0,8,4,6,10,8,4,0,6,2,8,10,6,4,2,0,6,8,2,0,6,10,6,4,8,10,4,2,6,8,4,0,2,8,10,8];\nvar sen2 = [12,10,4,6,14,8,20,12,8,4,0,12,18,6,4,10,6,2,18,14,12,4,0,8,14,16,20,12,8,4,0,12,14,10,8,4,18,12,14,10,4,2,6,12,18,14,10,2,8,4,12,18,10,4,2,0,6,18,20,12];\nvar sen3 = [1,5,3,7,9,7,5,3,7,9,3,1,5,7,3,7,9,1,7,5,3,9,3,1,7,5,9,3,1,7,3,5,9,3,1,7,5,3,1,7,9,3,7,1,5,7,3,7,9,5,3,1,7,9,5,3,3,1,7,9];\nvar sen4 = [7,11,17,3,7,11,1,9,17,13,17,11,3,9,11,3,7,15,13,19,11,7,5,1,13,17,15,5,7,3,11,7,19,13,15,11,9,3,5,9,17,13,11,9,13,15,7,3,5,1,13,17,7,19,3,5,9,1,7,3];\nvar sen5 = [8,2,10,14,8,16,8,12,4,0,12,12,18,14,6,10,4,8,12,14,20,4,14,16,10,12,8,6,2,8,0,10,12,8,4,16,18,12,8,4,2,8,0,12,20,16,12,18,20,8,12,14,8,4,8,16,2,8,14,8];\n\nif (i > time.length-1) return;\ncontext.set('i', i);\nvar data = [[time[i]],[sen1[i]],[sen2[i]],[sen3[i]],[sen4[i]],[sen5[i]]];\nmsg.payload=data;\nreturn msg;\n","outputs":1,"noerr":0,"x":310,"y":120,"wires":[["420ffd32.8c879c","2fdd8414.5770e4"]]},{"id":"9ac1d27b.b5dd7","type":"inject","z":"a9346054.4ad1b","name":"1秒毎","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"x":110,"y":100,"wires":[["db1d6d53.85c758"]]},{"id":"d9ec4e9.7c3203","type":"inject","z":"a9346054.4ad1b","name":"restart","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"x":110,"y":140,"wires":[["db1d6d53.85c758"]]},{"id":"2fdd8414.5770e4","type":"debug","z":"a9346054.4ad1b","name":"出力","active":true,"console":"false","complete":"payload","x":490,"y":100,"wires":[]},{"id":"8fb4da72.9d3278","type":"comment","z":"a9346054.4ad1b","name":"IoTセンサーからの値をシミュレート","info":"","x":200,"y":60,"wires":[]},{"id":"5afa1350.35c85c","type":"http in","z":"a9346054.4ad1b","name":"","url":"/test20","method":"get","swaggerDoc":"","x":130,"y":260,"wires":[["229a6875.3761c"]]},{"id":"229a6875.3761c","type":"template","z":"a9346054.4ad1b","name":"ws用htmlを返す","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE HTML>\n<html>\n\t<head>\n\t\t<title>リアルタイムIoTデータ表示</title>\n\t\t<meta charset=\"utf-8\" />\n\t\t<script src=\"http://ccchart.com/js/ccchart.js\" charset=\"utf-8\"></script>\n<script>\n\nwindow.onload=function(){\n\tcc();\n}\n\nfunction cc() {\n\nvar chartdata87 = {\n\n  \"config\": {\n    \"title\": \"リアルタイムIoTデータ表示\",\n    \"subTitle\": \"IoTデータをリアルタイムで可視化します\",\n    \"type\": \"stackedarea\",\n    \"maxWsColLen\": 12,\n    \"colorSet\": \n          [\"#ffbf7f\",\"#7fff7f\",\"#ff7fff\",\"#7fbfff\",\"#ff7f7f\"],\n    \"useMarker\": \"arc\",\n    \"useVal\": \"yes\",\n    \"roundedUpMaxY\": 100\n  },\n\n  \"data\": [\n    [\"時刻\"],\n    [\"センサー１値\"],\n    [\"センサー２値\"],\n    [\"センサー３値\"],\n    [\"センサー４値\"],\n    [\"センサー５値\"]\n  ]\n};\n\n  ccchart.wsCloseAll();//一旦クリア\n  ccchart\n    .init('id123', chartdata87)\n\t.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow20')\n\t.on('message', myOneColAtATime)\n\t.on('message', ccchart.wscase.oneColAtATime);\n}\n\nfunction myOneColAtATime (msg) {\n\tconsole.log(\"myOneColAtATime entered\");\n\t// 一度に1列ずつ [[\"2013\"],[435],[600]] といった配列で届く場合\n    // e.g. ws.on('message', ccchart.wscase.oneColAtAtime)\n    var msgs = JSON.parse(msg.data);\n\t// 各センサー要素を取り出して、画面へ表示\n\tfor (var i = 0; i < msgs.length; i++) { console.log( i + \" = \" + msgs[i]); }\n\ttarget = document.getElementById(\"output1\");\n\ttarget.innerHTML = msgs[0];\n\ttarget = document.getElementById(\"output2\");\n\ttarget.innerHTML = msgs[1];\n\ttarget = document.getElementById(\"output3\");\n\ttarget.innerHTML = msgs[2];\n\ttarget = document.getElementById(\"output4\");\n\ttarget.innerHTML = msgs[3];\n\ttarget = document.getElementById(\"output5\");\n\ttarget.innerHTML = msgs[4];\n\ttarget = document.getElementById(\"output6\");\n\ttarget.innerHTML = msgs[5];\n\n}\n\n</script>\n\t</head>\n\t<body>\n\n<div id=\"a-box\" style=\"background-color: #87cefa; padding: 20px;\">\n\t<h1>リアルタイムIoTデータ表示</h1>\n\t<br />\n\t<p>\n\t\tIoTセンサーからデータをリアルタイムで可視化します<br />\n\t</p>\n</div>\n\n<div id=\"b-box\" style=\"background-color: #ecf2fe; padding: 20px; \">\n\t<canvas id=\"id123\"></canvas>\n\t\t<h2>時刻</h2>\n\t\t\t<div style=\"text-align:left\" id=\"output0\"></div>\n\t\t\t<div style=\"text-align:left;font-size: 18pt\" id=\"output1\"></div>\n\t\t<h2>センサー１　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output2\"></span>\n\t\t<h2>センサー２　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output3\"></span>\n\t\t<h2>センサー３\t</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output4\"></span>\n\t\t<h2>センサー４\t</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output6\"></span>\n\t\t<h2>センサー５\t</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output5\"></span>\n\t\t<h2>積算\t</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output8\"></span>\n\n\n</div>\n\n<div id=\"c-box\" style=\"background-color: #f0e8fa; padding: 20px; \">\n\t\t<ul>\n\t\t\t<li><a href=\"http://qiita.com/egplnt/items/af867711a7191923b2ff\">Watson IoT Platformを使ってみる</a></li>\n\t\t\t<li><a href=\"https://internetofthings.ibmcloud.com/#/\">Watson IoT Platform</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/tutorials/use-the-simulated-device-to-experience-the-iot-foundation/\">Recipe - Simulator</a></li>\n\t\t</ul>\n\t\t<div class=\"category\">資料ページ</div>\n\t\t<ul>\n\t\t\t<li><a href=\"http://ibm.com/iot\">IBM IoT</a></li>\n\t\t\t<li><a href=\"https://docs.internetofthings.ibmcloud.com/ja/\">Watson IoT Platform資料ページ</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/\">Recipe</a></li>\n\t\t</ul>\n\n\n\t\t\t\n<!---\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n--->\n\n</div>\n<div id=\"d-box\" style=\"clear: both; background-color: #e0ce96; font-size: 18px; padding: 10px; text-align: center;  padding: 20px;\">\n\tcopyright (c) abc.com All right reserved. \n</div>\n\n\t</body>\n</html>\n","x":320,"y":260,"wires":[["63381646.36ce4"]]},{"id":"63381646.36ce4","type":"http response","z":"a9346054.4ad1b","name":"","x":510,"y":260,"wires":[]},{"id":"420ffd32.8c879c","type":"websocket out","z":"a9346054.4ad1b","name":"websocket output","server":"48e2ea18.2d831c","client":"","x":530,"y":140,"wires":[]},{"id":"d7d552a3.6ba1e8","type":"comment","z":"a9346054.4ad1b","name":"リアルタイムIoTセンサー値表示","info":"","x":190,"y":220,"wires":[]}]

```


1. [Node-REDのフローをコピーする方法](http://qiita.com/egplnt/items/84b244a50d8bdaced324)を参照して、上記のフローをコピペします。
2. 上段のシミュレーターのフローを確認し、左上の「１秒毎」と表記されたInjectノードをダブルクリックで開いて適当なインターバルに設定し、ノード右側から線を引き出して後続のオレンジ色の「センサー値を出力」ノードに接続します。（この線は常時リクエストを送付してしまうので、テスト時以外は切断しておくことをお薦めします。）
3. 下段の「リアルタイムIoTセンサー値表示」フローを確認し、オレンジ色の「ws用htmlを返す」のノードを開き、４２行目の`	.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow20')`のアプリ名部分を更新します。
4. Node-RED画面右上の赤い「Deploy」ボタンを押してクラウド側へ反映します。
5. ブラウザの新しいタブを開き、`IoTアプリ名.bluemix.net/test20`へアクセスすると下記のような画面が表示されます。
6. 上段のシミュレーターのフローの「再起動」を押し、シミュレートされたセンサーデータがHTML画面に表示されるのを確認します。
7. うまく表示されない場合、上段のIoTセンサー値を出力するフローのwebsocket出力ノードを一旦削除して、画面左側のパレットのoutputセクションからwebsocketノードをドラッグ＆ドロップして作り直してみます。出力Pathは`/we/flow20`としてあります（html内の指定と整合すれば何でも構いません）。

![スクリーンショット 2016-08-12 14.16.07.png](https://qiita-image-store.s3.amazonaws.com/0/125842/5f04174f-ffab-852d-6d39-29e34afd4df3.png)

![スクリーンショット 2016-08-12 13.32.26.png](https://qiita-image-store.s3.amazonaws.com/0/125842/86f1a5df-a34a-60d3-e3a4-920ebeb00540.png)

* * *
#サンプル２ 積算値を表示するサンプル
```lang:IoTセンサーからの値を積算して表示
[{"id":"3df0391e.e83cb6","type":"websocket-listener","z":"1413dbbf.96edd4","path":"/ws/flow22","wholemsg":"false"},{"id":"b03e4b77.5aba6","type":"template","z":"1413dbbf.96edd4","name":"ws用htmlを返す","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE HTML>\n<html>\n\t<head>\n\t\t<title>積算値IoTデータ表示</title>\n\t\t<meta charset=\"utf-8\" />\n\t\t<script src=\"http://ccchart.com/js/ccchart.js\" charset=\"utf-8\"></script>\n<script>\n\nwindow.onload=function(){\n\tcc();\n}\n\nfunction cc() {\n\nvar chartdata87 = {\n\n  \"config\": {\n    \"title\": \"積算値IoTデータ表示\",\n    \"subTitle\": \"IoTデータを積算して可視化します\",\n    \"type\": \"stackedarea\",\n    \"maxWsColLen\": 12,\n    \"colorSet\": \n          [\"#ffbf7f\",\"#7fff7f\",\"#ff7fff\",\"#7fbfff\",\"#ff7f7f\"],\n    \"useMarker\": \"arc\",\n    \"useVal\": \"yes\",\n    \"roundedUpMaxY\": 100\n  },\n\n  \"data\": [\n    [\"時刻\"],\n    [\"センサー１値\"],\n    [\"積算値\"]\n  ]\n};\n\n  ccchart.wsCloseAll();//一旦クリア\n  ccchart\n    .init('id123', chartdata87)\n\t.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow22')\n\t.on('message', myOneColAtATime)\n\t.on('message', ccchart.wscase.oneColAtATime);\n}\n\nfunction myOneColAtATime (msg) {\n\tconsole.log(\"myOneColAtATime entered\");\n\t// 一度に1列ずつ [[\"2013\"],[435],[600]] といった配列で届く場合\n    // e.g. ws.on('message', ccchart.wscase.oneColAtAtime)\n    var msgs = JSON.parse(msg.data);\n\t// 各センサー要素を取り出して、画面へ表示\n\tfor (var i = 0; i < msgs.length; i++) { console.log( i + \" = \" + msgs[i]); }\n\ttarget = document.getElementById(\"output1\");\n\ttarget.innerHTML = msgs[0];\n\ttarget = document.getElementById(\"output2\");\n\ttarget.innerHTML = msgs[1];\n\ttarget = document.getElementById(\"output3\");\n\ttarget.innerHTML = msgs[2];\n}\n\n</script>\n\t</head>\n\t<body>\n\n<div id=\"a-box\" style=\"background-color: #87cefa; padding: 20px;\">\n\t<h1>積算値IoTデータ表示</h1>\n\t<br />\n\t<p>\n\t\tIoTセンサーからデータを積算して可視化します<br />\n\t</p>\n</div>\n\n<div id=\"b-box\" style=\"background-color: #ecf2fe; padding: 20px; \">\n\t<canvas id=\"id123\"></canvas>\n\t\t<h2>時刻</h2>\n\t\t\t<div style=\"text-align:left\" id=\"output0\"></div>\n\t\t\t<div style=\"text-align:left;font-size: 18pt\" id=\"output1\"></div>\n\t\t<h2>センサー１　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output2\"></span>\n\t\t<h2>積算値　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output3\"></span>\n</div>\n\n<div id=\"c-box\" style=\"background-color: #f0e8fa; padding: 20px; \">\n\t\t<ul>\n\t\t\t<li><a href=\"http://qiita.com/egplnt/items/af867711a7191923b2ff\">Watson IoT Platformを使ってみる</a></li>\n\t\t\t<li><a href=\"https://internetofthings.ibmcloud.com/#/\">Watson IoT Platform</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/tutorials/use-the-simulated-device-to-experience-the-iot-foundation/\">Recipe - Simulator</a></li>\n\t\t</ul>\n\t\t<div class=\"category\">資料ページ</div>\n\t\t<ul>\n\t\t\t<li><a href=\"http://ibm.com/iot\">IBM IoT</a></li>\n\t\t\t<li><a href=\"https://docs.internetofthings.ibmcloud.com/ja/\">Watson IoT Platform資料ページ</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/\">Recipe</a></li>\n\t\t</ul>\n\n\n\t\t\t\n<!---\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n--->\n\n</div>\n<div id=\"d-box\" style=\"clear: both; background-color: #e0ce96; font-size: 18px; padding: 10px; text-align: center;  padding: 20px;\">\n\tcopyright (c) abc.com All right reserved. \n</div>\n\n\t</body>\n</html>\n","x":360,"y":280,"wires":[["bcf664db.750b"]]},{"id":"56042020.2b7b2","type":"function","z":"1413dbbf.96edd4","name":"センサー値を出力","func":"if (msg.payload === 0 ) {\n    context.set('total',0);\n    context.set(\"i\", 0);\n}\n\nvar i = context.get('i')||0;\ni += 1;\nvar time =[\"10:00\",\"10:01\",\"10:02\",\"10:03\",\"10:04\",\"10:05\",\"10:06\",\"10:07\",\"10:08\",\"10:09\",\"10:10\",\"10:11\",\"10:12\",\"10:13\",\"10:14\",\"10:15\",\"10:16\",\"10:17\",\"10:18\",\"10:19\",\"10:20\",\"10:21\",\"10:22\",\"10:23\",\"10:24\",\"10:25\",\"10:26\",\"10:27\",\"10:28\",\"10:29\",\"10:30\",\"10:31\",\"10:32\",\"10:33\",\"10:34\",\"10:35\",\"10:36\",\"10:37\",\"10:38\",\"10:39\",\"10:40\",\"10:41\",\"10:42\",\"10:43\",\"10:44\",\"10:45\",\"10:46\",\"10:47\",\"10:48\",\"10:49\",\"10:50\",\"10:51\",\"10:52\",\"10:53\",\"10:54\",\"10:55\",\"10:56\",\"10:57\",\"10:58\",\"10:59\"];\nvar sen1 = [2,8,4,6,0,10,8,4,2,6,10,6,4,8,0,2,10,8,2,8,4,6,10,2,0,8,4,6,10,8,4,0,6,2,8,10,6,4,2,0,6,8,2,0,6,10,6,4,8,10,4,2,6,8,4,0,2,8,10,8];\n\nif (i > time.length-1) return;\ncontext.set('i', i);\nvar total = context.get('total')||0;\ntotal += sen1[i];\ncontext.set('total', total);\nvar data = [[time[i]],[sen1[i]],[total]];\nmsg.payload=data;\nreturn msg;\n","outputs":1,"noerr":0,"x":350,"y":140,"wires":[["1fe22eb.a3ff551","63658ed5.e6482"]]},{"id":"db370290.0c588","type":"inject","z":"1413dbbf.96edd4","name":"1秒毎","topic":"","payload":"","payloadType":"date","repeat":"2","crontab":"","once":false,"x":150,"y":120,"wires":[[]]},{"id":"75be76f7.2d5158","type":"inject","z":"1413dbbf.96edd4","name":"restart","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"x":150,"y":160,"wires":[["56042020.2b7b2"]]},{"id":"63658ed5.e6482","type":"debug","z":"1413dbbf.96edd4","name":"出力","active":true,"console":"false","complete":"payload","x":530,"y":120,"wires":[]},{"id":"723e138a.c57bb4","type":"comment","z":"1413dbbf.96edd4","name":"IoTセンサーからの値をシミュレート","info":"","x":240,"y":80,"wires":[]},{"id":"653274ab.54234c","type":"http in","z":"1413dbbf.96edd4","name":"","url":"/test22","method":"get","swaggerDoc":"","x":170,"y":280,"wires":[["b03e4b77.5aba6"]]},{"id":"bcf664db.750b","type":"http response","z":"1413dbbf.96edd4","name":"","x":550,"y":280,"wires":[]},{"id":"1fe22eb.a3ff551","type":"websocket out","z":"1413dbbf.96edd4","name":"websocket output","server":"3df0391e.e83cb6","client":"","x":570,"y":160,"wires":[]},{"id":"d772f570.d1207","type":"comment","z":"1413dbbf.96edd4","name":"IoTセンサーからの値を積算して表示","info":"","x":240,"y":240,"wires":[]}]

```

1. [Node-REDのフローをコピーする方法](http://qiita.com/egplnt/items/84b244a50d8bdaced324)を参照して、上記のフローをコピペします。
2. 上段のシミュレーターのフローを確認し、左上の「１秒毎」と表記されたInjectノードをダブルクリックで開いて適当なインターバルに設定し、ノード右側から線を引き出して後続のオレンジ色の「センサー値を出力」ノードに接続します。（この線は常時リクエストを送付してしまうので、テスト時以外は切断しておくことをお薦めします。）
3. 下段の「リアルタイムIoTセンサー値表示」フローを確認し、オレンジ色の「ws用htmlを返す」のノードを開き、３９行目の`	.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow22')`のアプリ名部分を更新します。
4. Node-RED画面右上の赤い「Deploy」ボタンを押してクラウド側へ反映します。
5. ブラウザの新しいタブを開き、`IoTアプリ名.bluemix.net/test22`へアクセスすると下記のような画面が表示されます。
6. 上段のシミュレーターのフローの「再起動」を押し、シミュレートされたセンサーデータがHTML画面に表示されるのを確認します。
7. うまく表示されない場合、上段のIoTセンサー値を出力するフローのwebsocket出力ノードを一旦削除して、画面左側のパレットのoutputセクションからwebsocketノードをドラッグ＆ドロップして作り直してみます。出力Pathは`/we/flow22`としてあります（html内の指定と整合すれば何でも構いません）。

![スクリーンショット 2016-08-12 14.37.43.png](https://qiita-image-store.s3.amazonaws.com/0/125842/071ad1c7-fca7-b6a9-4b7b-0e3aa87a9e0d.png)

![スクリーンショット 2016-08-12 14.38.44.png](https://qiita-image-store.s3.amazonaws.com/0/125842/f645296c-1375-9231-8e28-a8a8763512f1.png)


* * *

#サンプル３ センサー値と直近１０件の平均値を表示するサンプル
```lang:センサー値と直近１０件の平均値を表示
[{"id":"68c5eaa7.793bec","type":"websocket-listener","z":"985cc25a.9014","path":"/ws/flow24","wholemsg":"false"},{"id":"eb8f68e9.a6598","type":"template","z":"985cc25a.9014","name":"ws用htmlを返す","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE HTML>\n<html>\n\t<head>\n\t\t<title>センサー値と直近１０件の平均値を表示</title>\n\t\t<meta charset=\"utf-8\" />\n\t\t<script src=\"http://ccchart.com/js/ccchart.js\" charset=\"utf-8\"></script>\n<script>\n\nwindow.onload=function(){\n\tcc();\n}\n\nfunction cc() {\n\nvar chartdata87 = {\n\n  \"config\": {\n    \"title\": \"センサー値と直近１０件の平均値を表示\",\n    \"subTitle\": \"IoTセンサーからの値と直近１０件の平均値を表示します\",\n    \"type\": \"stackedarea\",\n    \"maxWsColLen\": 12,\n    \"colorSet\": \n          [\"#ff7fff\",\"#7fffbf\",\"#ff7fff\",\"#7fbfff\",\"#ff7f7f\"],\n    \"useMarker\": \"arc\",\n    \"useVal\": \"yes\",\n    \"roundedUpMaxY\": 100\n  },\n\n  \"data\": [\n    [\"時刻\"],\n    [\"センサー１値\"],\n    [\"平均値\"]\n  ]\n};\n\n  ccchart.wsCloseAll();//一旦クリア\n  ccchart\n    .init('id123', chartdata87)\n\t.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow24')\n\t.on('message', myOneColAtATime)\n\t.on('message', ccchart.wscase.oneColAtATime);\n}\n\nfunction myOneColAtATime (msg) {\n\tconsole.log(\"myOneColAtATime entered\");\n\t// 一度に1列ずつ [[\"2013\"],[435],[600]] といった配列で届く場合\n    // e.g. ws.on('message', ccchart.wscase.oneColAtAtime)\n    var msgs = JSON.parse(msg.data);\n\t// 各センサー要素を取り出して、画面へ表示\n\tfor (var i = 0; i < msgs.length; i++) { console.log( i + \" = \" + msgs[i]); }\n\ttarget = document.getElementById(\"output1\");\n\ttarget.innerHTML = msgs[0];\n\ttarget = document.getElementById(\"output2\");\n\ttarget.innerHTML = msgs[1];\n\ttarget = document.getElementById(\"output3\");\n\ttarget.innerHTML = msgs[2];\n}\n\n</script>\n\t</head>\n\t<body>\n\n<div id=\"a-box\" style=\"background-color: #87cefa; padding: 20px;\">\n\t<h1>センサー値と直近１０件の平均値を表示</h1>\n\t<br />\n\t<p>\n\t\tIoTセンサーからの値と直近１０件の平均値を表示します<br />\n\t</p>\n</div>\n\n<div id=\"b-box\" style=\"background-color: #ecf2fe; padding: 20px; \">\n\t<canvas id=\"id123\"></canvas>\n\t\t<h2>時刻</h2>\n\t\t\t<div style=\"text-align:left\" id=\"output0\"></div>\n\t\t\t<div style=\"text-align:left;font-size: 18pt\" id=\"output1\"></div>\n\t\t<h2>センサー１　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output2\"></span>\n\t\t<h2>平均値　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output3\"></span>\n</div>\n\n<div id=\"c-box\" style=\"background-color: #f0e8fa; padding: 20px; \">\n\t\t<ul>\n\t\t\t<li><a href=\"http://qiita.com/egplnt/items/af867711a7191923b2ff\">Watson IoT Platformを使ってみる</a></li>\n\t\t\t<li><a href=\"https://internetofthings.ibmcloud.com/#/\">Watson IoT Platform</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/tutorials/use-the-simulated-device-to-experience-the-iot-foundation/\">Recipe - Simulator</a></li>\n\t\t</ul>\n\t\t<div class=\"category\">資料ページ</div>\n\t\t<ul>\n\t\t\t<li><a href=\"http://ibm.com/iot\">IBM IoT</a></li>\n\t\t\t<li><a href=\"https://docs.internetofthings.ibmcloud.com/ja/\">Watson IoT Platform資料ページ</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/\">Recipe</a></li>\n\t\t</ul>\n\n\n\t\t\t\n<!---\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n--->\n\n</div>\n<div id=\"d-box\" style=\"clear: both; background-color: #e0ce96; font-size: 18px; padding: 10px; text-align: center;  padding: 20px;\">\n\tcopyright (c) abc.com All right reserved. \n</div>\n\n\t</body>\n</html>\n","x":320,"y":280,"wires":[["7d36338b.49d68c"]]},{"id":"fee016c.b7d29e8","type":"function","z":"985cc25a.9014","name":"センサー値を出力","func":"if (msg.payload === 0 ) {\n    context.set(\"i\", 0);\n}\nif ( !context.array ) {\n    context.array = new Array (10);\n}\nvar sum = 0, average = 0;\n\nvar time =[\"10:00\",\"10:01\",\"10:02\",\"10:03\",\"10:04\",\"10:05\",\"10:06\",\"10:07\",\"10:08\",\"10:09\",\"10:10\",\"10:11\",\"10:12\",\"10:13\",\"10:14\",\"10:15\",\"10:16\",\"10:17\",\"10:18\",\"10:19\",\"10:20\",\"10:21\",\"10:22\",\"10:23\",\"10:24\",\"10:25\",\"10:26\",\"10:27\",\"10:28\",\"10:29\",\"10:30\",\"10:31\",\"10:32\",\"10:33\",\"10:34\",\"10:35\",\"10:36\",\"10:37\",\"10:38\",\"10:39\",\"10:40\",\"10:41\",\"10:42\",\"10:43\",\"10:44\",\"10:45\",\"10:46\",\"10:47\",\"10:48\",\"10:49\",\"10:50\",\"10:51\",\"10:52\",\"10:53\",\"10:54\",\"10:55\",\"10:56\",\"10:57\",\"10:58\",\"10:59\"];\nvar sen1 = [2,8,4,6,0,10,8,4,2,6,10,6,4,8,0,2,10,8,2,8,4,6,10,2,0,8,4,6,10,8,4,0,6,2,8,10,6,4,2,0,6,8,2,0,6,10,6,4,8,10,4,2,6,8,4,0,2,8,10,8];\n\nvar i = context.get('i')||0;\ni += 1;\nif (i > time.length-1) return;\ncontext.set('i', i);\n\nvar shifted = context.array.shift();\ncontext.array.push(sen1[i]);\n\nvar length = context.array.length;\n\nfor (k=0; k<length; k++) {\n        sum = sum + context.array[k];\n}\n\naverage = sum / length;\nvar data = [[time[i]],[sen1[i]],[average]];\nmsg.payload=data;\nreturn msg;\n","outputs":1,"noerr":0,"x":310,"y":140,"wires":[["e4f47cb2.6de238","fe4e3fb1.158d78"]]},{"id":"adb5d728.25e47","type":"inject","z":"985cc25a.9014","name":"1秒毎","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"x":110,"y":120,"wires":[[]]},{"id":"d6cf08c7.c7249","type":"inject","z":"985cc25a.9014","name":"restart","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"x":110,"y":160,"wires":[["fee016c.b7d29e8"]]},{"id":"fe4e3fb1.158d78","type":"debug","z":"985cc25a.9014","name":"出力","active":true,"console":"false","complete":"payload","x":490,"y":120,"wires":[]},{"id":"cd5d6cc2.d31e7","type":"comment","z":"985cc25a.9014","name":"IoTセンサーからの値をシミュレート","info":"","x":200,"y":80,"wires":[]},{"id":"a8c5dde3.129678","type":"http in","z":"985cc25a.9014","name":"","url":"/test24","method":"get","swaggerDoc":"","x":130,"y":280,"wires":[["eb8f68e9.a6598"]]},{"id":"7d36338b.49d68c","type":"http response","z":"985cc25a.9014","name":"","x":510,"y":280,"wires":[]},{"id":"e4f47cb2.6de238","type":"websocket out","z":"985cc25a.9014","name":"websocket output","server":"68c5eaa7.793bec","client":"","x":530,"y":160,"wires":[]},{"id":"e2ee57c.4c2db28","type":"comment","z":"985cc25a.9014","name":"IoTセンサーからの値と直近１０件の平均値を表示","info":"","x":250,"y":240,"wires":[]}]

```

1. [Node-REDのフローをコピーする方法](http://qiita.com/egplnt/items/84b244a50d8bdaced324)を参照して、上記のフローをコピペします。
2. 上段のシミュレーターのフローを確認し、左上の「１秒毎」と表記されたInjectノードをダブルクリックで開いて適当なインターバルに設定し、ノード右側から線を引き出して後続のオレンジ色の「センサー値を出力」ノードに接続します。（この線は常時リクエストを送付してしまうので、テスト時以外は切断しておくことをお薦めします。）
3. 下段の「リアルタイムIoTセンサー値表示」フローを確認し、オレンジ色の「ws用htmlを返す」のノードを開き、３９行目の`	.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow24')`のアプリ名部分を更新します。
4. Node-RED画面右上の赤い「Deploy」ボタンを押してクラウド側へ反映します。
5. ブラウザの新しいタブを開き、`IoTアプリ名.bluemix.net/test24`へアクセスすると下記のような画面が表示されます。
6. 上段のシミュレーターのフローの「再起動」を押し、シミュレートされたセンサーデータがHTML画面に表示されるのを確認します。
7. うまく表示されない場合、上段のIoTセンサー値を出力するフローのwebsocket出力ノードを一旦削除して、画面左側のパレットのoutputセクションからwebsocketノードをドラッグ＆ドロップして作り直してみます。出力Pathは`/we/flow24`としてあります（html内の指定と整合すれば何でも構いません）。
8. 必要に応じ、 「センサー値を出力」ノード内の５行目の`context.array = new Array (10);`の配列（Array）の要素数を増減して直近の平均値を算出する対象のエントリー数を調整します。
9. 参考：[Watson IoT Platform - Node-RED - 直近10件の平均や標準偏差を求める](http://qiita.com/egplnt/items/af3b9e69c94728ac6083)

![スクリーンショット 2016-08-12 15.24.42.png](https://qiita-image-store.s3.amazonaws.com/0/125842/21359267-f047-0908-5854-ecb04b04ea2d.png)

![スクリーンショット 2016-08-12 15.24.59.png](https://qiita-image-store.s3.amazonaws.com/0/125842/5d4f0151-c77a-0e88-0805-daeee8d211b0.png)

* * *

#サンプル４ 指定した間隔でセンサー値と直近１０件の平均値を表示するサンプル
```lang:センサー値と直近１０件の平均値を表示
[{"id":"70e4d0da.5629b","type":"websocket-listener","z":"9caf5f2d.ee644","path":"/ws/flow26","wholemsg":"false"},{"id":"7b5b76f2.ebdbd8","type":"function","z":"9caf5f2d.ee644","name":"センサー値を出力","func":"//var sampling_min_interval = 1;\nvar sampling_sec_interval = 60;     // データを出力する間隔\n\nvar sum = 0, average = 0;\nvar sen1 = Math.floor(Math.random () * 10) + 1;　// センサー値を生成（シミュレート）\n\nif ( !context.array ) {\n    context.array = new Array (10); //直近１０件分を保持\n}\nvar shifted = context.array.shift();\ncontext.array.push(sen1);           // 最新の値を保存\nvar length = context.array.length;\n\nfor (k=0; k<length; k++) {\n        sum = sum + context.array[k];   // 合計を算出\n}\n\nvar hour = JSON.stringify(msg.date.hour);\nvar min_org  = JSON.stringify(msg.date.minute);\nvar min = ( \"0\" + min_org ).substr( -2 );       // 一桁分の場合、二桁に\nvar sec_org  = JSON.stringify(msg.date.second);\nvar sec = ( \"0\" + sec_org ).substr( -2 );       // 一桁秒の場合、二桁に\nvar time = hour + \":\" + min + \":\" + sec;\n\naverage = sum / length;\nvar data = [[time],[sen1],[average]];\nmsg.payload = data;\nif ( ( msg.date.second % sampling_sec_interval ) !== 0 ) return;\n//if ( ( msg.date.minute % sampling_min_interval ) !== 0 ) return;\nreturn msg;\n","outputs":1,"noerr":0,"x":470,"y":160,"wires":[["88545406.3f6818","2c25b12a.092b4e","35aab970.8f3be6"]]},{"id":"a7ab6090.c965a","type":"template","z":"9caf5f2d.ee644","name":"ws用htmlを返す","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE HTML>\n<html>\n\t<head>\n\t\t<title>指定した間隔でセンサー値と直近１０件の平均値を表示</title>\n\t\t<meta charset=\"utf-8\" />\n\t\t<script src=\"http://ccchart.com/js/ccchart.js\" charset=\"utf-8\"></script>\n<script>\n\nwindow.onload=function(){\n\tcc();\n}\n\nfunction cc() {\n\nvar chartdata87 = {\n\n  \"config\": {\n    \"title\": \"センサー値と直近平均値をインターバル表示\",\n    \"subTitle\": \"指定した間隔でIoTセンサーからの値と直近１０件の平均値を表示します\",\n    \"type\": \"stackedarea\",\n    \"maxWsColLen\": 12,\n    \"colorSet\": \n          [\"#bf7fff\",\"#ffbf7f\",\"#ff7fff\",\"#7fbfff\",\"#ff7f7f\"],\n    \"useMarker\": \"arc\",\n    \"useVal\": \"yes\",\n\t\"autoReConnect\": \"yes\",\n\t\"autoReConnectInterval\": 500,\n\t\"wsReCnt\": 5000,\n    \"roundedUpMaxY\": 100\n  },\n\n  \"data\": [\n    [\"時刻\"],\n    [\"センサー１値\"],\n    [\"平均値\"]\n  ]\n};\n\n  ccchart.wsCloseAll();//一旦クリア\n  ccchart\n    .init('id123', chartdata87)\n\t.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow26', autoReConnectInterval = 5000)\n\t.on('message', myOneColAtATime)\n\t.on('message', ccchart.wscase.oneColAtATime);\n}\n\nfunction myOneColAtATime (msg) {\n\tconsole.log(\"myOneColAtATime entered\");\n\t// 一度に1列ずつ [[\"2013\"],[435],[600]] といった配列で届く場合\n    // e.g. ws.on('message', ccchart.wscase.oneColAtAtime)\n    var msgs = JSON.parse(msg.data);\n\t// 各センサー要素を取り出して、画面へ表示\n\tfor (var i = 0; i < msgs.length; i++) { console.log( i + \" = \" + msgs[i]); }\n\ttarget = document.getElementById(\"output1\");\n\ttarget.innerHTML = msgs[0];\n\ttarget = document.getElementById(\"output2\");\n\ttarget.innerHTML = msgs[1];\n\ttarget = document.getElementById(\"output3\");\n\ttarget.innerHTML = msgs[2];\n}\n\n</script>\n\t</head>\n\t<body>\n\n<div id=\"a-box\" style=\"background-color: #87cefa; padding: 20px;\">\n\t<h1>指定した間隔でセンサー値と直近１０件の平均値を表示</h1>\n\t<br />\n\t<p>\n\t\t指定した間隔でIoTセンサーからの値と直近１０件の平均値を表示します<br />\n\t</p>\n</div>\n\n<div id=\"b-box\" style=\"background-color: #ecf2fe; padding: 20px; \">\n\t<canvas id=\"id123\"></canvas>\n\t\t<h2>時刻</h2>\n\t\t\t<div style=\"text-align:left\" id=\"output0\"></div>\n\t\t\t<div style=\"text-align:left;font-size: 18pt\" id=\"output1\"></div>\n\t\t<h2>センサー１　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output2\"></span>\n\t\t<h2>直近１０件の平均値　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output3\"></span>\n</div>\n\n<div id=\"c-box\" style=\"background-color: #f0e8fa; padding: 20px; \">\n\t\t<ul>\n\t\t\t<li><a href=\"http://qiita.com/egplnt/items/af867711a7191923b2ff\">Watson IoT Platformを使ってみる</a></li>\n\t\t\t<li><a href=\"https://internetofthings.ibmcloud.com/#/\">Watson IoT Platform</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/tutorials/use-the-simulated-device-to-experience-the-iot-foundation/\">Recipe - Simulator</a></li>\n\t\t</ul>\n\t\t<div class=\"category\">資料ページ</div>\n\t\t<ul>\n\t\t\t<li><a href=\"http://ibm.com/iot\">IBM IoT</a></li>\n\t\t\t<li><a href=\"https://docs.internetofthings.ibmcloud.com/ja/\">Watson IoT Platform資料ページ</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/\">Recipe</a></li>\n\t\t</ul>\n\n\n\t\t\t\n<!---\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n--->\n\n</div>\n<div id=\"d-box\" style=\"clear: both; background-color: #e0ce96; font-size: 18px; padding: 10px; text-align: center;  padding: 20px;\">\n\tcopyright (c) abc.com All right reserved. \n</div>\n\n\t</body>\n</html>\n","x":320,"y":300,"wires":[["30f8039c.a85bd4"]]},{"id":"a34bbc54.711aa8","type":"inject","z":"9caf5f2d.ee644","name":"1秒毎","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"x":110,"y":140,"wires":[["cef961b7.c12238"]]},{"id":"35276ce4.1d332c","type":"inject","z":"9caf5f2d.ee644","name":"restart","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"x":110,"y":180,"wires":[["cef961b7.c12238"]]},{"id":"88545406.3f6818","type":"debug","z":"9caf5f2d.ee644","name":"出力","active":true,"console":"false","complete":"payload","x":650,"y":140,"wires":[]},{"id":"e4b92c19.4c359","type":"comment","z":"9caf5f2d.ee644","name":"IoTセンサーからの値をシミュレート","info":"","x":200,"y":100,"wires":[]},{"id":"62aeaebe.acc14","type":"http in","z":"9caf5f2d.ee644","name":"","url":"/test26","method":"get","swaggerDoc":"","x":130,"y":300,"wires":[["a7ab6090.c965a"]]},{"id":"30f8039c.a85bd4","type":"http response","z":"9caf5f2d.ee644","name":"","x":510,"y":300,"wires":[]},{"id":"3265f51e.f1e4e2","type":"comment","z":"9caf5f2d.ee644","name":"指定されたインターバルでIoTセンサーからの値と直近１０件の平均値を表示","info":"","x":330,"y":260,"wires":[]},{"id":"cef961b7.c12238","type":"function","z":"9caf5f2d.ee644","name":"日付時刻の追加","func":"var d = new Date();\nvar localTime = d.getTime();\nvar localOffset = d.getTimezoneOffset() * 60000;\nvar utc = localTime + localOffset;\nvar offset = -9.0;\nvar result = utc - (3600000 * offset);\nvar date = parseInt(new Date(result) / 1000);\nvar dt = new Date(result);\n\nvar year = dt.getFullYear();\nvar month = dt.getMonth()+1;\nvar day = dt.getDate();\nvar hour = dt.getHours();\nvar minute = dt.getMinutes();\nvar second = dt.getSeconds();\n//if (!msg.payload) {\n//    msg.payload = { \"initial\": \"value\" };\n//}\nif (!msg.date) {\n    msg.date = { \"initial\": \"value\" };\n}\nmsg.date = {\n        \"date\": date,\n        \"year\": year,\n        \"month\": month,\n        \"day\": day,\n        \"hour\": hour,\n        \"minute\": minute,\n        \"second\": second\n};\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":160,"wires":[["7b5b76f2.ebdbd8","2c25b12a.092b4e"]]},{"id":"2c25b12a.092b4e","type":"debug","z":"9caf5f2d.ee644","name":"時刻の表示","active":false,"console":"false","complete":"date","x":670,"y":100,"wires":[]},{"id":"35aab970.8f3be6","type":"websocket out","z":"9caf5f2d.ee644","name":"","server":"70e4d0da.5629b","client":"","x":670,"y":200,"wires":[]}]

```

1. センサーから１秒毎など頻繁に送付されてくるデータを全部画面に表示すると画面が見にくくなって大変なので、飛来したデータを内部で配列に保持して直近の平均値などの算出は続けておいて、指定した時間インターバルが経過したらその時飛来したセンサー値とその直前までの平均値を表示する、というサンプルです。
2. [Node-REDのフローをコピーする方法](http://qiita.com/egplnt/items/84b244a50d8bdaced324)を参照して、上記のフローをコピペします。
3. 上段のシミュレーターのフローを確認し、左上の「１秒毎」と表記されたInjectノードをダブルクリックで開いて適当なインターバルに設定し、ノード右側から線を引き出して後続のオレンジ色の「センサー値を出力」ノードに接続します。（この線は常時リクエストを送付してしまうので、テスト時以外は切断しておくことをお薦めします。）
4. 下段の「リアルタイムIoTセンサー値表示」フローを確認し、オレンジ色の「ws用htmlを返す」のノードを開き、３９行目の`	.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow26')`のアプリ名部分を更新します。
5. Node-RED画面右上の赤い「Deploy」ボタンを押してクラウド側へ反映します。
6. ブラウザの新しいタブを開き、`IoTアプリ名.bluemix.net/test26`へアクセスすると下記のような画面が表示されます。
7. 上段のシミュレーターのフローの「再起動」を押し、シミュレートされたセンサーデータがHTML画面に表示されるのを確認します。
8. うまく表示されない場合、上段のIoTセンサー値を出力するフローのwebsocket出力ノードを一旦削除して、画面左側のパレットのoutputセクションからwebsocketノードをドラッグ＆ドロップして作り直してみます。出力Pathは`/we/flow26`としてあります（html内の指定と整合すれば何でも構いません）。
9. 必要に応じ、 「センサー値を出力」ノード内の１行目の`var sampling_interval = 60;`のサンプリング間隔秒数を変更します。また５行目の`context.array = new Array (10);`の配列（Array）の要素数を増減して直近の平均値を算出する対象のエントリー数を調整します。
10. 参考：[Watson IoT Platform - Node-RED - 直近10件の平均や標準偏差を求める](http://qiita.com/egplnt/items/af3b9e69c94728ac6083)、[Watson IoT Platform - Node-RED - 日付・時刻の追加](http://qiita.com/egplnt/items/74d65518cac9fc334efe)

![スクリーンショット 2016-08-12 16.05.55.png](https://qiita-image-store.s3.amazonaws.com/0/125842/96bd8f2e-8a89-9eaa-35f8-f50fc23a21ea.png)

![スクリーンショット 2016-08-12 16.06.10.png](https://qiita-image-store.s3.amazonaws.com/0/125842/85c83d76-213b-cf66-2f80-0e3ea6399071.png)


- クライアントのサンプルです。`Inject`ノードの代わりに`IBM IoT`インプットノードを使用し、`Device ID`欄に`0123456789ab`を指定して接続します。

```py:pubTemp.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import logging
import os
import os.path
import sys
import codecs
import time
import paho.mqtt.client as mqtt
import json
import threading
import random

MQTT_BROKER="quickstart.messaging.internetofthings.ibmcloud.com"

MQTT_PORT=1883
MQTT_TIMEOUT=60

MQTT_PUB_TOPIC="iot-2/evt/status/fmt/json"

def on_connect(client, userdata, flags, rc):
	print("on connect")
	#client.subscribe(MQTT_SUB_TOPIC)
	#client.subscribe(MQTT_SUB_TOPIC + "#") 

def on_disconnect(client, userdata, rc):
	print("on disconnect")
	client.unsubscribe(MQTT_SUB_TOPIC)

def on_message(client, userdata, msg):
	print("on message: " + msg.topic + " " + str(msg.payload))

def mqttConnect():
	print("mqttConnect")
	try:
		global client
		client = mqtt.Client("d:quickstart:myThing:0123456789ab")
		client.on_connect = on_connect
		client.on_message = on_message
		client.on_disconnect = on_disconnect
		client.connect(MQTT_BROKER,MQTT_PORT,MQTT_TIMEOUT)
		print("connected")
	except KeyboardInterrupt, kex:
		sys.exit()
	except Exception, ex:
		print("mqttConnect error")

def mqttPublishCycle():
	while client.loop() == 0:
		try:
			temp = 10 + random.randrange(250,450)/100.0
			humid = 40 + random.randrange(500,1000)/100.0
			print "temp = " + str(temp) + ", humid = " + str(humid) 
			msg = " {\"d\": {\"Temperature\": " + str(temp) +",\"Humidity\": " + str(humid) + "} }";
			client.publish(MQTT_PUB_TOPIC, msg, 0, True)
			time.sleep(2)
		except Exception, ex:
			print("mqttPublish error")


def testHello():
	print "hello"

if __name__ == "__main__":
	print("--- started ---")
	mqttConnect()
	mqttPublishCycle()
	testHello()

	print("--- program ended ---")


```

* * *
#サンプル５ 指定した間隔でセンサー値と直近１０件の平均値と標準偏差を表示するサンプル

```lang:センサー値と直近１０件の平均値と標準偏差を表示
[{"id":"a7d8276f.0b198","type":"template","z":"b82d7fcb.a73958","name":"ws用htmlを返す","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE HTML>\n<html>\n\t<head>\n\t\t<title>センサー値と直近１０件の平均値、標準偏差を表示</title>\n\t\t<meta charset=\"utf-8\" />\n\t\t<script src=\"http://ccchart.com/js/ccchart.js\" charset=\"utf-8\"></script>\n<script>\n\nwindow.onload=function(){\n\tcc();\n}\n\nfunction cc() {\n\nvar chartdata87 = {\n\n  \"config\": {\n    \"title\": \"センサー値と直近平均値、標準偏差を表示\",\n    \"subTitle\": \"IoTセンサーからの値と直近１０件の平均値、標準偏差を表示します\",\n    \"type\": \"stackedarea\",\n    \"maxWsColLen\": 8,\n    \"colorSet\": \n          [\"#bf7fff\",\"#ffbf7f\",\"#ff7fff\",\"#7fbfff\",\"#ff7f7f\"],\n    \"useMarker\": \"arc\",\n    \"useVal\": \"yes\",\n\t\"autoReConnect\": \"yes\",\n\t\"autoReConnectInterval\": 500,\n\t\"wsReCnt\": 5000,\n    \"roundedUpMaxY\": 100\n  },\n\n  \"data\": [\n    [\"時刻\"],\n    [\"センサー１値\"],\n    [\"直近１０件の平均値\"],\n    [\"標準偏差\"],\n  ]\n};\n\n  ccchart.wsCloseAll();//一旦クリア\n  ccchart\n    .init('id123', chartdata87)\n\t.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow40', autoReConnectInterval = 5000)\n\t.on('message', myOneColAtATime)\n\t.on('message', ccchart.wscase.oneColAtATime);\n}\n\nfunction myOneColAtATime (msg) {\n\tconsole.log(\"myOneColAtATime entered\");\n\t// 一度に1列ずつ [[\"2013\"],[435],[600]] といった配列で届く場合\n    // e.g. ws.on('message', ccchart.wscase.oneColAtAtime)\n    var msgs = JSON.parse(msg.data);\n\t// 各センサー要素を取り出して、画面へ表示\n\tfor (var i = 0; i < msgs.length; i++) { console.log( i + \" = \" + msgs[i]); }\n\ttarget = document.getElementById(\"output1\");\n\ttarget.innerHTML = msgs[0];\n\ttarget = document.getElementById(\"output2\");\n\ttarget.innerHTML = msgs[1];\n\ttarget = document.getElementById(\"output3\");\n\ttarget.innerHTML = msgs[2];\n\ttarget = document.getElementById(\"output4\");\n\ttarget.innerHTML = msgs[3];\n}\n\n</script>\n\t</head>\n\t<body>\n\n<div id=\"a-box\" style=\"background-color: #87cefa; padding: 20px;\">\n\t<h1>センサー値と直近１０件の平均値、標準偏差を表示</h1>\n\t<br />\n\t<p>\n\t\tIoTセンサーからの値と直近１０件の平均値、標準偏差を表示します<br />\n\t</p>\n</div>\n\n<div id=\"b-box\" style=\"background-color: #ecf2fe; padding: 20px; \">\n\t<canvas id=\"id123\"></canvas>\n\t\t<h2>時刻</h2>\n\t\t\t<div style=\"text-align:left\" id=\"output0\"></div>\n\t\t\t<div style=\"text-align:left;font-size: 18pt\" id=\"output1\"></div>\n\t\t<h2>センサー１　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output2\"></span>\n\t\t<h2>直近１０件の平均値　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output3\"></span>\n\t\t<h2>直近１０件の標準偏差　</h2>\n\t\t\t<span style=\"text-align:left;font-size: 18pt\" id=\"output4\"></span>\n</div>\n\n<div id=\"c-box\" style=\"background-color: #f0e8fa; padding: 20px; \">\n\t\t<ul>\n\t\t\t<li><a href=\"http://qiita.com/egplnt/items/af867711a7191923b2ff\">Watson IoT Platformを使ってみる</a></li>\n\t\t\t<li><a href=\"https://internetofthings.ibmcloud.com/#/\">Watson IoT Platform</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/tutorials/use-the-simulated-device-to-experience-the-iot-foundation/\">Recipe - Simulator</a></li>\n\t\t</ul>\n\t\t<div class=\"category\">資料ページ</div>\n\t\t<ul>\n\t\t\t<li><a href=\"http://ibm.com/iot\">IBM IoT</a></li>\n\t\t\t<li><a href=\"https://docs.internetofthings.ibmcloud.com/ja/\">Watson IoT Platform資料ページ</a></li>\n\t\t\t<li><a href=\"https://developer.ibm.com/recipes/\">Recipe</a></li>\n\t\t</ul>\n\n\n\t\t\t\n<!---\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n\t\t<h3>h3 見出し</h3>\n\t\t<p>テキスト　（省略）</p>\n--->\n\n</div>\n<div id=\"d-box\" style=\"clear: both; background-color: #e0ce96; font-size: 18px; padding: 10px; text-align: center;  padding: 20px;\">\n\tcopyright (c) abc.com All right reserved. \n</div>\n\n\t</body>\n</html>\n","x":300,"y":480,"wires":[["1e84eada.9e7035"]]},{"id":"46e3c36c.9fbc64","type":"inject","z":"b82d7fcb.a73958","name":"1秒毎","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"x":110,"y":260,"wires":[[]]},{"id":"56226a7b.5927bc","type":"inject","z":"b82d7fcb.a73958","name":"restart","topic":"","payload":"0","payloadType":"num","repeat":"","crontab":"","once":false,"x":110,"y":300,"wires":[["be56004d.1f1c78"]]},{"id":"696338dd.cff878","type":"http in","z":"b82d7fcb.a73958","name":"","url":"/test40","method":"get","swaggerDoc":"","x":110,"y":480,"wires":[["a7d8276f.0b198"]]},{"id":"1e84eada.9e7035","type":"http response","z":"b82d7fcb.a73958","name":"","x":490,"y":480,"wires":[]},{"id":"26a0b136.cc6476","type":"comment","z":"b82d7fcb.a73958","name":"可視化","info":"","x":90,"y":440,"wires":[]},{"id":"be56004d.1f1c78","type":"function","z":"b82d7fcb.a73958","name":"配列に格納","func":"/*if (msg.payload.d.ambientLight ) {\n    msg.sen1 = Math.round(msg.payload.d.ambientLight*100)/100;　// Alpsセンサーから温度を取得\n} else {\n    return 0;\n}\n*/\nmsg.sen1 = Math.floor(Math.random () * 10) + 1;　// センサー値を生成（シミュレート）\n\nif ( !context.global.array ) {\n    context.global.array = new Array (10);\n}\nvar shifted = context.global.array.shift();\n\ncontext.global.array.push(msg.sen1);\n\nmsg.array = context.global.array;\nmsg.length = context.global.array.length;\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":280,"wires":[["cc3d1348.dc0758"]]},{"id":"cc3d1348.dc0758","type":"function","z":"b82d7fcb.a73958","name":"平均","func":"var sum = 0, average = 0;\n    for (i=0; i<msg.length; i++) {\n        sum = sum + msg.array[i];\n}\nmsg.sum = sum;\naverage = sum / msg.length;\nmsg.average = Math.round(average*100)/100;\nreturn msg;\n","outputs":1,"noerr":0,"x":430,"y":280,"wires":[["a6b18687.ca6d5","5563095.e6dc878"]]},{"id":"a6b18687.ca6d5","type":"debug","z":"b82d7fcb.a73958","name":"","active":false,"console":"false","complete":"average","x":550,"y":240,"wires":[]},{"id":"5563095.e6dc878","type":"function","z":"b82d7fcb.a73958","name":"分散","func":"var variance = 0;\nfor (i=0; i<msg.length; i++) {\n    variance = variance + Math.pow(msg.array[i] - msg.average, 2);\n}\nvariance = variance / msg.length;\nmsg.variance = Math.round(variance*100)/100;\nreturn msg;\n","outputs":1,"noerr":0,"x":570,"y":280,"wires":[["2a869a6a.73e3a6"]]},{"id":"2a869a6a.73e3a6","type":"function","z":"b82d7fcb.a73958","name":"標準偏差","func":"var standard_deviation = 0;\nstandard_deviation = Math.sqrt(msg.variance);\nmsg.std = Math.round(standard_deviation*100)/100;\nreturn msg;","outputs":1,"noerr":0,"x":260,"y":340,"wires":[["5043c9ff.86b608","ef01efdc.e4535"]]},{"id":"5043c9ff.86b608","type":"debug","z":"b82d7fcb.a73958","name":"","active":false,"console":"false","complete":"std","x":440,"y":380,"wires":[]},{"id":"ef01efdc.e4535","type":"function","z":"b82d7fcb.a73958","name":"時刻を設定","func":"var d = new Date();\nvar localTime = d.getTime();\nvar localOffset = d.getTimezoneOffset() * 60000;\nvar utc = localTime + localOffset;\nvar offset = -9.0;\nvar result = utc - (3600000 * offset);\nvar date = parseInt(new Date(result) / 1000);\nvar dt = new Date(result);\n\nvar year = dt.getFullYear();\nvar month = dt.getMonth()+1;\nvar day = dt.getDate();\nvar hour = dt.getHours();\nvar minute = dt.getMinutes();\nvar second = dt.getSeconds();\n//if (!msg.payload) {\n//    msg.payload = { \"initial\": \"value\" };\n//}\nif (!msg.date) {\n    msg.date = { \"initial\": \"value\" };\n}\nmsg.date = {\n        \"date\": date,\n        \"year\": year,\n        \"month\": month,\n        \"day\": day,\n        \"hour\": hour,\n        \"minute\": minute,\n        \"second\": second\n};\n\nvar hour = JSON.stringify(msg.date.hour);\nvar min_org  = JSON.stringify(msg.date.minute);\nvar min = ( \"0\" + min_org ).substr( -2 );       // 一桁分の場合、二桁に\nvar sec_org  = JSON.stringify(msg.date.second);\nvar sec = ( \"0\" + sec_org ).substr( -2 );       // 一桁秒の場合、二桁に\nvar time = hour + \":\" + min + \":\" + sec;\n\n//average = sum / length;\nvar data = [[time],[msg.sen1],[msg.average],[msg.std]];\nmsg.payload = data;\nreturn msg;\n","outputs":1,"noerr":0,"x":450,"y":340,"wires":[["9f156ff1.f937b","c63f01cc.a45b4"]]},{"id":"9f156ff1.f937b","type":"debug","z":"b82d7fcb.a73958","name":"","active":true,"console":"false","complete":"false","x":630,"y":320,"wires":[]},{"id":"c63f01cc.a45b4","type":"websocket out","z":"b82d7fcb.a73958","name":"","server":"aad83d48.43cde8","client":"","x":670,"y":380,"wires":[]},{"id":"cb8e5723.18e778","type":"comment","z":"b82d7fcb.a73958","name":"IoTセンサーからの値と直近１０件の平均値、標準偏差を出力","info":"","x":260,"y":200,"wires":[]},{"id":"aad83d48.43cde8","type":"websocket-listener","z":"b82d7fcb.a73958","path":"/ws/flow40","wholemsg":"false"}]

```

1. 前項のサンプル４に加えて標準偏差も出力するサンプルです。
2. [Node-REDのフローをコピーする方法](http://qiita.com/egplnt/items/84b244a50d8bdaced324)を参照して、上記のフローをコピペします。
3. 上段のシミュレーターのフローを確認し、左上の「１秒毎」と表記されたInjectノードをダブルクリックで開いて適当なインターバルに設定し、ノード右側から線を引き出して後続のオレンジ色の「センサー値を出力」ノードに接続します。（この線は常時リクエストを送付してしまうので、テスト時以外は切断しておくことをお薦めします。）
4. 下段の「リアルタイムIoTセンサー値表示」フローを確認し、オレンジ色の「ws用htmlを返す」のノードを開き、４３行目の`	.ws('ws://このIoTアプリの名前.mybluemix.net/ws/flow40')`のアプリ名部分を更新します。
5. Node-RED画面右上の赤い「Deploy」ボタンを押してクラウド側へ反映します。
6. ブラウザの新しいタブを開き、`IoTアプリ名.bluemix.net/test40`へアクセスすると下記のような画面が表示されます。
7. 上段のシミュレーターのフローの「再起動」を押し、シミュレートされたセンサーデータがHTML画面に表示されるのを確認します。
8. うまく表示されない場合、上段のIoTセンサー値を出力するフローのwebsocket出力ノードを一旦削除して、画面左側のパレットのoutputセクションからwebsocketノードをドラッグ＆ドロップして作り直してみます。出力Pathは`/we/flow40`としてあります（html内の指定と整合すれば何でも構いません）。
9. 必要に応じ、 「センサー値を出力」ノード内の１行目の`var sampling_interval = 60;`のサンプリング間隔秒数を変更します。また５行目の`context.array = new Array (10);`の配列（Array）の要素数を増減して直近の平均値を算出する対象のエントリー数を調整します。

![スクリーンショット 2016-10-16 16.18.51.png](https://qiita-image-store.s3.amazonaws.com/0/125842/75c08c32-d6e6-0ca2-777a-62e4611618e3.png)

![スクリーンショット 2016-10-16 16.25.06.png](https://qiita-image-store.s3.amazonaws.com/0/125842/22eada83-2ec4-a8df-3ed6-8cb533b1d8e9.png)