Watson IoT Platform - リアルタイムでIoTデータを表示

初めてWatson IoT Platformを使ってみよう、というかたのためのガイドです。
[Watson IoT Platformを使ってみる](http://qiita.com/egplnt/items/af867711a7191923b2ff)でIoTアプリを準備しました。
[IoTダッシュボードを作ってみる](http://qiita.com/egplnt/items/141bd5d9b17ba02e526b)でIoTデータを可視化するダッシュボードを作っていきます。

# デバイスからのIoTデータをリアルタイムで可視化します
- ここではAlps Smart IoT ModuleからのデータをWatson IoT Platformへ送付している想定で、飛来するデータをリアルタイムで表示してみます
- 下記のフローをコピペします
![スクリーンショット 2017-02-15 18.02.00.png](https://qiita-image-store.s3.amazonaws.com/0/125842/d82ddbca-8c19-7e29-a3ef-f6a6903ddc2a.png)

```lang:デバイスからのIoTデータをリアルタイムで可視化
[{"id":"4b0b70e6.d8b4b","type":"template","z":"b0ed7852.d58f08","name":"test510.htmlを返す","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE HTML>\n<html>\n　<head>\n　　<title>センサーからの情報を表示</title>\n　　<meta charset=\"utf-8\" />\n<script type=\"text/javascript\" src=\"https://www.google.com/jsapi\"></script>\n<script type=\"test/javascript\" src=\"https://www.gstatic.com/charts/loader.js\"></script>\n\n\n<style type=\"text/css\">\n  {{{payload.css}}}\n</style>\n　</head>\n　<body>\n\n  <div id='basic' align=\"center\">\n\n    <div id='a1' align=\"left\">\n      <h2>IoT Sample Dashboard</h2>\n      IoTデータをリアルタイムで可視化します\n    </div>\n    <div id='b1' align=\"left\">\n\n    </div>\n    <div id='d1'>\n      d1\n    </div>\n    <div id='d2'>\n      d2\n    </div>\n    <div id='d3'>\n      d3\n    </div>\n\n    <div id='e1' align=\"left\">\n      <h2 style=\"margin-left:10px;\">照度</h2>\n        <span style=\"text-align:left; font-size:18pt; margin-left:100px;\" id=\"e1data\"></span>lux\n    </div>\n    <div id='e2'>\n      e2\n    </div>\n    <div id='e3'>\n      e3\n    </div>\n\n    <div id='f1'>\n      f1\n    </div>\n    <div id='f2'>\n      f2\n    </div>\n    <div id='f3'>\n      f3\n    </div>\n    <div id='h1' >\n      h1\n    </div>\n    <div id='h2'>\n      h2\n    </div>\n    <div id='h3'>\n      h3\n    </div>\n\n    <div id='j1'>\n      j1\n    </div>\n    <div id='j2'>\n      j2\n    </div>\n    <div id='j3'>\n      j3\n    </div>\n\n    <div id='k1' >\n      k1\n    </div>\n    <div id='k2'>\n      k2\n    </div>\n    <div id='k3'>\n      k3\n    </div>\n\n    <div id='m1'>\n      m1\n    </div>\n    <div id='m2'>\n      m2\n    </div>\n    <div id='m3'>\n      m3\n    </div>\n\n    <div id='v1' align=\"left\">\n      <h2 style=\"margin-left:10px;\">アラート</h2>\n      <span style=\"text-align: left;font-size:18pt; margin-left:100px;\" id=\"alerttext\"></span>\n    </div>\n\n    <div id='x1' align=\"left\">\n      x1\n    </div>\n\n<div id=\"y1\" align=\"left\">\n  参考URL\n  <ul>\n    <li><a href=\"http://qiita.com/egplnt/items/af867711a7191923b2ff\">Watson IoT Platformを使ってみる</a></li>\n    <li><a href=\"https://internetofthings.ibmcloud.com/#/\">Watson IoT Platform</a></li>\n    <li><a href=\"https://developer.ibm.com/recipes/tutorials/use-the-simulated-device-to-experience-the-iot-foundation/\">Recipe - Simulator</a></li>\n  </ul>\n  マニュアル\n  <ul>\n    <li><a href=\"http://ibm.com/iot\">IBM IoT</a></li>\n    <li><a href=\"https://docs.internetofthings.ibmcloud.com/ja/\">Watson IoT Platform資料ページ</a></li>\n    <li><a href=\"https://developer.ibm.com/recipes/\">Recipe</a></li>\n  </ul>\n</div>\n\n<div id=\"z1\">\n\tcopyright (c) abc.com All rights reserved.\n</div>\n</div>\n\n\n<script>\nvar connection = new WebSocket('wss://このIoTアプリの名前.mybluemix.net/wss/flow510');\n\nconnection.onopen = function () {\n  console.log(\"websocket connected\");\n};\n\nconnection.onerror = function (error) {\n  console.log('WebSocket Error ' + error);\n};\n\nconnection.onmessage = function (m) {\n\tdoIt(m);\n};\n\n// ゲージとラインチャートを準備\n// ラインチャートのAPIは　https://developers.google.com/chart/interactive/docs/reference\ngoogle.load('visualization', '1', {packages:['gauge', 'corechart']});\ngoogle.setOnLoadCallback(drawChart);\n\nfunction drawChart() {\n\td1GaugeData = google.visualization.arrayToDataTable([\n\t\t['Label', 'Value'],\n\t\t['照度', 0]\n\t]);\n  d1GaugeOptions = {\n\t\twidth: 500, height: 150,\n\t\tmin: 0, max: 500,\n\t\tyellowFrom:300, yellowTo: 400,\n    redFrom: 400, redTo: 500,\n\t\tminorTicks: 5\n\t};\n  d1Gauge = new google.visualization.Gauge(document.getElementById('d1'));\n\td1Gauge.draw(d1GaugeData, d1GaugeOptions);\n\n\n  f1ChartData = google.visualization.arrayToDataTable(\n    [[\"時刻\",\"照度\"],['10:00:00',300]] );\n  f1ChartData.removeRow(0);\n  f1ChartOptions = {　title: '照度',\n    legend: { position: 'bottom' },\n    backgroundColor: {stroke:'#c1d8ac' ,strokeWidth:10, fill:'#ffffff'}\n  };\n  f1Chart = new google.visualization.LineChart(document.getElementById('f1'));\n  f1Chart.draw(f1ChartData, f1ChartOptions);\n\n};\n\n//websocketからの毎秒のデータを受信してゲージ・チャートへ表示する\nfunction doIt(msg){\n  console.log(\"doit:\" + msg.data);\n\tvar msgs = JSON.parse(msg.data);\n\n  // msgs[4]は二重配列なので\"msgs[4][0]\"で温度の値を取り出してリアルタイム表示する\n  d1GaugeData = google.visualization.arrayToDataTable([\n    ['Label', 'Value'],\n    ['照度', msgs[4][0]]\n  ]);\n  d1Gauge.draw(d1GaugeData, d1GaugeOptions);\n  console.log(\"msgs[4][0] = \" + msgs[4][0]);\n\n  f1ChartData.addRow( [ msgs[0][0], msgs[4][0] ] );\n  if ( f1ChartData.getNumberOfRows() > 9) {\n    f1ChartData.removeRow(0);\n  }\n  f1Chart.draw(f1ChartData, f1ChartOptions);\n\n\t// 各センサー要素を取り出して、画面へ表示\n  target = document.getElementById(\"e1data\"); // 照度 e1に表示\n\ttarget.innerHTML = msgs[4];\n};\n</script>\n\n</body>\n</html>\n","x":510,"y":1560,"wires":[["8d087038.9ea568"]]},{"id":"41ffd7da.a707b","type":"http in","z":"b0ed7852.d58f08","name":"","url":"/test510","method":"get","swaggerDoc":"","x":150,"y":1560,"wires":[["f45b0d3c.ce456"]]},{"id":"8d087038.9ea568","type":"http response","z":"b0ed7852.d58f08","name":"","x":690,"y":1560,"wires":[]},{"id":"775b8847.ee6f4","type":"comment","z":"b0ed7852.d58f08","name":"IoTセンサーデータをリアルタイムに可視化","info":"","x":220,"y":1520,"wires":[]},{"id":"f45b0d3c.ce456","type":"template","z":"b0ed7852.d58f08","name":"css510","field":"payload.css","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"#basic {\n  width: 1200px;\n  margin: auto;\n}\n\n#a1 {\n  background-color:  #98d98e;\n  padding: 20px;\n  height: 100px;\n}\n#b1 {\n  background-color:  #e4de8a;\n  padding-left: 20px;\n  height: 40px;\n  text-align:left;\n  font-size: 18pt\n}\n#d1 {\n  clear: both;\n  float: left;\n  width: 400px;\n  height: 150px;\n  background-color:  #c1d8ac;\n}\n#d2 {\n  float: left;\n  width: 400px;\n  height: 150px;\n  background-color:  #b9d08b;\n}\n#d3 {\n  float: left;\n  width: 400px;\n  height: 150px;\n  background-color:  #badcad;\n}\n\n#e1 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #c1d8ac;\n}\n#e2 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #b9d08b;\n}\n#e3 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #badcad;\n}\n\n#f1 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #c1d8ac;\n}\n#f2 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #b9d08b;\n}\n#f3 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #badcad;\n}\n\n#g1 {\n  float: left;\n  width: 400px;\n  height: 150px;\n  background-color:  #c1d8ac;\n}\n#g2 {\n  float: left;\n  width: 400px;\n  height: 150px;\n  background-color:  #b9d08b;\n}\n#g3 {\n  float: left;\n  width: 400px;\n  height: 150px;\n  background-color:  #badcad;\n}\n\n#h1 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #98d98e;\n}\n#h2 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #c1d8ac;\n}\n#h3 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #93b69c;\n}\n\n#j1 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #98d98e;\n}\n#j2 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #c1d8ac;\n}\n#j3 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #93b69c;\n}\n\n#k1 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #c1d8ac;\n}\n#k2 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #b9d08b;\n}\n#k3 {\n  float: left;\n  width: 400px;\n  height: 120px;\n  background-color:  #badcad;\n}\n\n#m1 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #c1d8ac;\n}\n#m2 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #b9d08b;\n}\n#m3 {\n  float: left;\n  width: 400px;\n  height: 200px;\n  background-color:  #badcad;\n}\n\n#v1 {\n  clear: both;\n  height: 100px;\n  background-color:  #aacf53;\n}\n#x1 {\n  height: 100px;\n\tpadding: 20px;\n  background-color:  #c1d8ac;\n}\n#y1 {\n  background-color: #e4dc8a;\n\tpadding: 20px;\n  height: 250px;\n}\n#z1 {\n  height: 25px;\n  background-color: #8f8667;\n  font-size: 18px;\n  text-align: center;\n}\n","x":320,"y":1560,"wires":[["4b0b70e6.d8b4b"]]},{"id":"85fdcb29.d16d18","type":"ibmiot in","z":"b0ed7852.d58f08","authentication":"quickstart","apiKey":"","inputType":"evt","deviceId":"device_id","applicationId":"","deviceType":"+","eventType":"+","commandType":"","format":"json","name":"IBM IoT","service":"quickstart","allDevices":"","allApplications":"","allDeviceTypes":true,"allEvents":true,"allCommands":"","allFormats":"","qos":0,"x":130,"y":1420,"wires":[["ae7d3c2.115204","350a9ad6.3f5986"]]},{"id":"ae7d3c2.115204","type":"debug","z":"b0ed7852.d58f08","name":"","active":false,"console":"false","complete":"payload","x":290,"y":1460,"wires":[]},{"id":"dbbace37.bb7f9","type":"function","z":"b0ed7852.d58f08","name":"IoTデータを送出","func":"var a0 = msg.payload.d.AccelX;\nvar a1 = msg.payload.d.AccelY;\nvar a2 = msg.payload.d.AccelZ;\nvar a3 = msg.payload.d.AmbientLight;\nvar a4 = msg.payload.d.GeoMagneticX;\nvar a5 = msg.payload.d.GeoMagneticY;\nvar a6 = msg.payload.d.GeoMagneticZ;\nvar a7 = msg.payload.d.Humidity;\nvar a8 = msg.payload.d.Pressure; \nvar a9 = msg.payload.d.UV; \n\nvar hour_org  = JSON.stringify(msg.date.hour);\nvar hour = ( \"0\" + hour_org ).substr( -2 );       // 一桁分の場合、二桁に\n\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\nvar data = [[time],[a0],[a1],[a2],[a3],[a4],[a5],[a6],[a7],[a8],[a9]];\nmsg.payload = data;\nreturn msg;\n","outputs":1,"noerr":0,"x":490,"y":1420,"wires":[["2fec1905.2caa7e","5090aaeb.b08174"]]},{"id":"2fec1905.2caa7e","type":"debug","z":"b0ed7852.d58f08","name":"","active":true,"console":"false","complete":"payload","x":670,"y":1380,"wires":[]},{"id":"350a9ad6.3f5986","type":"function","z":"b0ed7852.d58f08","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();\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":300,"y":1420,"wires":[["dbbace37.bb7f9"]]},{"id":"5090aaeb.b08174","type":"websocket out","z":"b0ed7852.d58f08","name":"","server":"de531545.865b38","client":"","x":710,"y":1420,"wires":[]},{"id":"86419396.311e9","type":"comment","z":"b0ed7852.d58f08","name":"デバイスからのデータをwebsocketへ","info":"","x":210,"y":1380,"wires":[]},{"id":"de531545.865b38","type":"websocket-listener","z":"","path":"/wss/flow510","wholemsg":"false"}]

```

- 「IBM IoT」インプットノードのdevice_idに実際に使用しているデバイスのIDを指定します
- 「test510.htmlを返す」テンプレートノードの１２６行目の`var connection = new WebSocket('wss://このIoTアプリの名前.mybluemix.net/wss/flow510');`をアプリ名に合わせて変更します


- 無事「AmbientLight」(照度）がリアルタイムで表示されました。加速度や気圧など他の値も空いている欄に表示していきます
![スクリーンショット 2017-02-15 17.31.43.png](https://qiita-image-store.s3.amazonaws.com/0/125842/3b137144-a5d6-fc51-b228-f7fe98160d4f.png)