IoTのデモは大変
よく、Node-REDでIoTのデモを見せてと無茶振りされますが、サッとやろうとしても
- センサーとNode-REDのサーバを準備して
- センサーを接続して
- 値を永続化して、可視化するFlow書いて
などという準備が必要で、それ以外にデモ環境のインターネット接続にあわせて調整したりが結構大変です。
スマホのセンサなら簡単
スマホには加速度センサやジャイロセンサが入っており、モバイルブラウザのJavascriptで使うことができます。またインターネット接続もスマホ単独で実施できます。
モバイルブラウザ向けのHTML5画面を作成し、JavascriptでWebSocket接続することで、スマホのセンサを使って擬似IoTのデモを作れないかと考えました。
node-red-contrib-metrics で可視化
可視化には node-red-contrib-metrics を使います。FlowEditor内で簡単にグラフ表示できるので、ページ切り替えでデモの流れをさえぎりません。
Flow
[{"id":"6a349e1.be6c2e","type":"template","z":"38edf745.9916a","name":"HTML","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"\n\n\n \n \n \n ACCL CHART\n\n\n 加速度センサーデータ\n \n \n\n","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+\"\";\n txt += \"y:\"+accy+\"\";\n txt += \"z:\"+accz+\"\";\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ごとにhイベント発生\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"}]
詳細
スマホブラウザ(Mobile Safari/Mobile Chrome)でスマホ側URIにアクセスします。(Flowでは /acc1)
なお、スマホブラウザでないと加速度センサーデータが表示されません。
ブラウザを開くと、サーバ側とWebSocket接続し、常時取得している加速度センサーデータ(x/y/zの軸)をJSONにして、0.5秒おきにサーバに送信します。
サーバは受け取ったデータをnode-red-contrib-metrics nodeでグラフにして表示します。
スマートフォンを揺らすと、グラフが変化します。
拡張
あとは、ファイルやDBに永続化するもよし、スマホから取得するデータを増やす(ジャイロなど)もよし、いろいろ拡張して、素敵なデモを作ってください。