スマホブラウザの加速度センサでIoTのマネゴト

# IoTのデモは大変
よく、Node-REDでIoTのデモを見せてと無茶振りされますが、サッとやろうとしても

- センサーとNode-REDのサーバを準備して
- センサーを接続して
- 値を永続化して、可視化するFlow書いて

などという準備が必要で、それ以外にデモ環境のインターネット接続にあわせて調整したりが結構大変です。

# スマホのセンサなら簡単
スマホには加速度センサやジャイロセンサが入っており、モバイルブラウザのJavascriptで使うことができます。またインターネット接続もスマホ単独で実施できます。
モバイルブラウザ向けのHTML5画面を作成し、JavascriptでWebSocket接続することで、スマホのセンサを使って擬似IoTのデモを作れないかと考えました。

# node-red-contrib-metrics で可視化
可視化には [node-red-contrib-metrics](http://flows.nodered.org/node/node-red-contrib-metrics) を使います。FlowEditor内で簡単にグラフ表示できるので、ページ切り替えでデモの流れをさえぎりません。

# Flow
![accl.png](https://qiita-image-store.s3.amazonaws.com/0/25932/f91e1cc2-7d49-91ff-620d-0de45383e840.png)
<pre>[{"id":"6a349e1.be6c2e","type":"template","z":"38edf745.9916a","name":"HTML","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <title>ACCL CHART</title>\n</head>\n<body>\n    <h1>加速度センサーデータ</h1>\n    <script>{{{payload.script}}}</script>\n    <p id=\"datatxt\"></p>\n</body>\n</html>","x":438,"y":135,"wires":[["45ce8e39.9f763"]]},{"id":"551510fc.2aed38","type":"http in","z":"38edf745.9916a","name":"","url":"/acc1","method":"get","swaggerDoc":"","x":125,"y":119,"wires":[["717fc110.3e1048"]]},{"id":"45ce8e39.9f763","type":"http response","z":"38edf745.9916a","name":"","x":597,"y":135.5,"wires":[]},{"id":"717fc110.3e1048","type":"template","z":"38edf745.9916a","name":"script","field":"payload.script","fieldType":"msg","format":"javascript","syntax":"mustache","template":"\nvar encrypted=\"{{{req.connection.encrypted}}}\";\nif(encrypted === \"true\") {\n    var wsUri=\"wss://{{{req.hostname}}}:{{{req.connection.localPort}}}/accl1\";\n}\nelse {\n    var wsUri=\"ws://{{{req.hostname}}}:{{{req.connection.localPort}}}/accl1\";\n}\nvar ws = new WebSocket(wsUri);\n\nvar accx=null;\nvar accy=null;\nvar accz=null;\n\nfunction sendMessage() {\n    // 画面書き換え\n    var txt  = \"x:\"+accx+\"<br>\";\n        txt += \"y:\"+accy+\"<br>\";\n        txt += \"z:\"+accz+\"<br>\";\n        \n    var node=document.getElementById(\"datatxt\");\n    node.innerHTML=txt;\n    \n    // WebSocket送信\n    var payload = {\n        'accx': accx,\n        'accy': accy,\n        'accz': accz,\n    };\n    ws.send(JSON.stringify(payload));\n}\n\nfunction handleMotionEvent(evt){\n    //加速度\n    accx = evt.acceleration.x;\n    accy = evt.acceleration.y;\n    accz = evt.acceleration.z;\n}\n\nwindow.addEventListener(\"devicemotion\", handleMotionEvent, true); //情報変更ごとにイベント発生\nwindow.setInterval(sendMessage, 500); // 500msごとにｈイベント発生\n","x":296.5,"y":130.5,"wires":[["6a349e1.be6c2e"]]},{"id":"50420d19.c46e94","type":"websocket in","z":"38edf745.9916a","name":"","server":"2c9c0117.e3a04e","client":"","x":129,"y":238,"wires":[["77d6f74c.ff639","aad0d132.ed6218"]]},{"id":"77d6f74c.ff639","type":"debug","z":"38edf745.9916![metrics.png](https://qiita-image-store.s3.amazonaws.com/0/25932/9847a007-2973-ed0a-bf41-a5ec7d1b0e1b.png)
a","name":"","active":false,"console":"false","complete":"false","x":361,"y":311.5,"wires":[]},{"id":"aad0d132.ed6218","type":"json","z":"38edf745.9916a","name":"","x":337,"y":256,"wires":[["d687debd.645018","e42294f5.db0008"]]},{"id":"d687debd.645018","type":"debug","z":"38edf745.9916a","name":"","active":false,"console":"false","complete":"false","x":569,"y":309.5,"wires":[]},{"id":"e42294f5.db0008","type":"metrics","z":"38edf745.9916a","name":"スマホ加速度センサ","column":"200","routes":[{"key":"accx","legend":"左右"},{"key":"accy","legend":"上下"},{"key":"accz","legend":"高低"}],"x":598,"y":258.5,"wires":[[]]},{"id":"698ed510.f9fd74","type":"comment","z":"38edf745.9916a","name":"スマホ側(WebSocketクライアント )","info":"","x":203,"y":78,"wires":[]},{"id":"fe264a8a.cade78","type":"comment","z":"38edf745.9916a","name":"サーバ側","info":"","x":118,"y":197,"wires":[]},{"id":"2c9c0117.e3a04e","type":"websocket-listener","z":"","path":"/accl1","wholemsg":"false"}]</pre>

# 詳細
スマホブラウザ(Mobile Safari/Mobile Chrome)でスマホ側URIにアクセスします。(Flowでは /acc1)

![mb2.png](https://qiita-image-store.s3.amazonaws.com/0/25932/8ad804a7-5a32-c0f0-9adf-15e04f29026d.png)

なお、スマホブラウザでないと加速度センサーデータが表示されません。

ブラウザを開くと、サーバ側とWebSocket接続し、常時取得している加速度センサーデータ(x/y/zの軸)をJSONにして、0.5秒おきにサーバに送信します。

サーバは受け取ったデータをnode-red-contrib-metrics nodeでグラフにして表示します。

![metrics.png](https://qiita-image-store.s3.amazonaws.com/0/25932/600c308c-0eba-0313-2ba0-b554590088e4.png)

スマートフォンを揺らすと、グラフが変化します。

# 拡張
あとは、ファイルやDBに永続化するもよし、スマホから取得するデータを増やす（ジャイロなど）もよし、いろいろ拡張して、素敵なデモを作ってください。