IBM Bluemix を 使 って モバイルのセンサーデータ を 利 用 する 2015 年 8 月 27 日 1
IoTの 時 代 が 到 来 家 電 や 車 ビルや 工 場 橋 など 世 界 中 の 様 々なモノがインターネットにつ ながり 始 めています HealthCare Smart Scales Connected car Container Tracking Smart Deliveries Vending Machine Smart Meter Mobile Heating and Air Conditioning Building Security 2
2020 年 にネット 接 続 するデバイスは 500 億 を 超 える 3
クラウドサービスを 使 ったIoT アプリの 構 成 例 例 : ビーコンを 活 用 した 新 しい 顧 客 体 験 センサ デバイス 検 知 デバイス クラウド サービス IBM Bluemix ibeacon (BLEデバイス) Bluetooth OpenBlocks (BLE 検 知 デバイス) 接 続 DB バック エンド 連 携 分 析 モバイル 通 知 IoT Foundation Cloudant 4 最 適 な 接 客 クーポン
IoTを 支 える 次 世 代 の 通 信 プロトコル MQTTとは? M2MやIoTの 実 現 に 適 したシンプルで 軽 量 なプロトコル 双 方 向 1 対 Nの 通 信 プロトコルヘッダーは 最 小 2バイト(HTTPだと50バイト~ HTTPの1/10のトラフィック) 省 電 力 Publish/Subscribe 型 であり 同 期 処 理 が 必 要 となるHTTPより 処 理 が 高 速 不 安 定 な 環 境 での 通 信 に 強 い 5 Topicに 投 稿 購 読 者 に 配 信 Topicを 購 読
Bluemix 上 で 利 用 出 来 るMQTT 関 連 サービス IoT Foundation クラウド 上 で 提 供 される MQTTサーバーサービス (MQTT Broker) 認 証 なしで 誰 でも 使 用 出 来 る Quick Start Service が 使 える! Bluemix IoT Service MQTTサーバー 上 へのデータへのアクセスサービス(MQTT Subscriber) IoT Foundation Bluemix IoT Service 6
ハンズオンで 作 成 するアプリケーション スマホをセンサとみなし スマホからMQTTで 送 信 される 位 置 情 報 をリアルタイムで Google Mapに 表 示 する MQTT Broker アプリケーション IoT Foundationサービスは センサーデータを 仲 介 IBM IoT Foundatio n 位 置 情 報 をSubscribeし Google Map 上 に 表 示 デバイス IBM Bluemix スマホのセンサーで 計 測 した 位 置 情 報 を MQTT BrokerにPublish 7
最 終 形 のイメージ1 : スマホのセンサーデータの 取 得 下 記 のQRコードから センサーデータ 取 得 & MQTT 送 信 を 行 うWebページにアクセ スし Device ID / 位 置 情 報 / 傾 きのデータがリアルタイムで 取 得 されていることを 確 認 Geo Location API で 位 置 情 報 を 取 得 (Javascript) Bluemix 上 で 稼 働 http://goo.gl/dkfqvm MQTTで 位 置 情 報 を MQTTサーバに 送 信 (Javascript) 8
最 終 形 のイメージ2 : Node-Red アプリケーション MQTT Subscribe (センサデータ 取 得 ) 位 置 情 報 を 抽 出 Web Socketで 位 置 情 報 をリアルタイム 通 信 HTTP GET Requestの 待 ち 受 け ResponseするHTML Google Map API 使 用 Http Response 9
最 終 形 のイメージ3 : Google Mapでスマホの 位 置 を 表 示 スマホの 位 置 情 報 がリアル タイムに 反 映 動 くと 追 随 する 10
1. スマホセンサデータ 取 得 ページの 作 成 11
Webアプリケーション サーバー 作 成 (Node-RED Starter) スマホセンサーを 取 得 するWebページをホストするサーバーを 作 成 単 純 なHTML + Javascriptであり どのランタイム( 言 語 )でも 良 い 今 回 はMQTT SubscribeするアプリをNode-Redで 作 成 するため Node-RED Starterを 使 用 することとする 12 1カタログから Node-RED Starterを 選 択 2アプリ 名 を 指 定 して Create Bluemix 上 でユニークな 名 前 と する
Node-RED スターターコードのダウンロード Node-REDを 含 むWebアプリケーションのひな 形 をLocal PCにダウンロードします ひな 形 に スマホのセンサーデータを 取 得 するHTML / Javascriptを 加 え 再 度 Bluemixにデプロイします 13
スターターコードを 作 業 フォルダに 配 置 作 業 フォルダを 作 成 し スターターコードをフォルダごとCopy フォルダ 名 や 場 所 は 任 意 14
Githubからソースコードを 取 得 1. Githubにアクセスし ソースコードをダウンロード https://github.com/masayafujita/phone_sensor 2. ファイルを 解 凍 し スターターコードの public フォルダの 中 にCopy 解 凍 した 中 身 のsensor_mqtt_htmlとjs フォ ルダを スターターコードのpublic 下 にCopy ダウンロード 15
ソースコードの 概 要 sensor_mqtt.html スマホからアクセスすると 位 置 情 報 や 傾 き 等 のセンサーデータを 取 得 し 表 示 する HTML js/sensor_mqtt.js Geolocation API 等 を 用 いて センサー 情 報 を 取 得 MQTT Broker(IoT Foundation)にデータを 送 信 js/mqttws31.js Paho MQTT Javascript client library JavascriptでMQTT Client(Publisher, Subscriber)を 構 成 する 際 に 必 要 な Library 16
HTML : sensor_mqtt.html head 要 素 でPaho MQTT Javascript ClientのJS Fileを 読 み 込 む jquery 17 センサ 値 取 得 & MQTT 送 信 を 行 うJavascript
Geolocation API Geolocation API javascriptでユーザーの 位 置 情 報 を 扱 うためのAPI 主 要 ブラウザでサポートされている 無 線 LAN WiFi 携 帯 電 話 基 地 局 GPS IPアドレスなどから 位 置 情 報 を 取 得 位 置 情 報 を 含 むpositionオブジェクトが 渡 され コールバック 関 数 が 実 施 される position オブジェクトから 緯 度 経 度 等 の 値 を 取 得 jqueryでhtmlに 表 示 18
Paho MQTT Javascript client: 概 要 Paho MQTT Javascript Client WebsocketでMQTT Brokerとデータを 双 方 向 通 信 するためのJavascript Library http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.javascript.git/plain/src/mqtt ws31.js データはJSON 形 式 で 送 受 信 する User 情 報 MQTT Broker 情 報 を 指 定 し 接 続 用 Objectを 生 成 MQTTサーバへ 接 続 Topic: /WorldをSubscribe データをTopic: /WorldへPublish 19 上 記 はPahoのホームページのガイドより 抜 粋
Paho MQTT Javascript client: コード 説 明 デバイスを 識 別 するID IoT FoundationのQuickstart (MQTTサーバ)のアドレス 接 続 Object 作 成 送 信 データObjectの 作 成 JSONに 変 換 して 送 信 MQTT Publish 20
cf コマンドのインストール Local PC 上 のソースコードをBluemixにデプロイするツールである cf コマンド をインスト ールする 1. Githubにアクセス(https://github.com/cloudfoundry/cli)し ダウンロード 2. コマンドプロンプト(OS Xではターミナル)で 動 作 確 認 :cf -v バージョンが 無 事 表 示 さ れればOK 21 Macで 開 発 元 が 未 確 認 のため 開 けません と 表 示 される 場 合 は システム 環 境 設 定 >> セキュリティーと プライバシーにて ダウンロードしたアプリケーションの 実 行 許 可 にて すべてのアプリケーションを 許 可 するように 設 定 を 変 更 して 下 さい
cf コマンドでBluemixへログイン 1. コマンドプロンプトでルートフォルダへ 移 動 (package.jsonが 存 在 するフォルダ) 2. cf login コマンドでBluemix 環 境 へログイン > cf login -a https://api.ng.bluemix.net Bluemix IDとPass 22
Bluemixにアプリケーションをデプロイ 1. cf push コマンドでBluemixにアプリケーションをPush > cf push (アプリケーション 名 ) 23
スマホセンサーの 稼 働 確 認 スマートフォンからデプロイしたWebページにアクセス http://(アプリ 名 ).mybluemix.net/sensor_mqtt.html 24
2. 位 置 情 報 をGoogle Mapに 表 示 するアプリをNode- REDで 作 成 する 25
Node-RED について IBM 英 国 Hursley 研 究 所 の Emerging Technology Teamで 開 発 されたソ フトウェア 2013 年 社 内 ハッカソンで 堂 々 一 位 GitHub に 登 録 2014 年 Qcon で 発 表 オープンソースプロジェクトとして 提 供 26
Node-REDの 特 徴 ハードウェアデバイス,API,オンラインサービスが 画 期 的 な 方 法 で 結 合 された" 仮 想 環 境 をブラウザ 上 で 実 現 ブラウザベース UI node.js で 動 作 軽 量 Bluemixでなくて も 使 用 可 能 です 機 能 をカプセル 化 してNodeと して 利 用 独 自 Nodeを 作 成 追 加 可 能 Bluemixの 様 々なサービスを 簡 単 に 利 用 可 能 27
Node-RED 画 面 シート 実 装 UI 表 示 情 報 の 切 り 替 え デプロイ 実 行 ノード 処 理 フロー ノードパレット Node Infomation または デバッグコンソール 28
Node-RED 実 装 方 法 Node-RED 画 面 4Deployを 選 択 1ノードを 選 択 し ドラッグ&ドロップ 2ノード 間 を 接 続 3ノードプロパティ 設 定 29
Node-RED 搭 載 ノードの 紹 介 ( 代 表 的 なもの) Node 分 類 Input Output Function Social Storage Analysis Advanced 機 能 イベントの 起 動 条 件 の 設 定 外 部 アプリへの 送 信 イベント 分 岐 受 信 データの 変 換 一 時 停 止 等 Twitter/Mail/ircの 送 受 信 DBへの 保 存 DB 検 索 分 析 RSS/atomの 更 新 受 信 時 にイベント 起 動 コネクタが 右 側 に 存 在 1イベントの 起 動 イベント 起 動 条 件 を 満 たし たとき その 情 報 を 送 信 す る コネクタが 左 右 に 存 在 2データ 変 換 / 分 岐 左 からデータ 受 信 それを 変 換 / 分 岐 させ 右 側 に 結 果 を 返 す コネクタが 左 側 に 存 在 3 外 部 アプリ 起 動 /DB 保 存 左 からデータを 受 信 し それを 送 信 / 保 存 30
1イベントの 起 動 Node 名 称 イベント 開 始 条 件 後 続 フローに 送 信 する 内 容 Inject 定 期 起 動 orノードのクリック 指 定 文 字 列 or 現 在 時 刻 or 情 報 なし( 起 動 のみ) デバック 向 けの 機 能 http Mail Twitter コネクタが 右 側 に 存 在 するもの http://[xxxxxxx].mybluemix.net/[ノードのurl]リクエスト 送 信 時 メール 受 信 時 または 未 読 メール 存 在 時 定 期 起 動 指 定 メッセージのTweet 時 に 自 動 起 動 Feedparse RSS/atomの 更 新 受 信 時 - リクエスト 情 報 メール 本 文 (text/plain) Tweet 情 報 ( 本 文 発 言 場 所 国 ) 31
2データ 変 換 / 分 岐 コネクタが 左 右 に 存 在 するもの Node 名 称 機 能 後 続 フローに 送 信 する 内 容 Function 受 領 データの 更 新 更 新 済 データ Switch 条 件 に 応 じて フローを 分 岐 させる 受 信 データ Delay フローを 待 機 受 信 データ http request 指 定 サイトに 接 続 接 続 サイトのソース Cloudant DB 検 索 DBの 検 索 結 果 Sentiment 受 信 データをセンチメント 分 析 評 価 情 報 を 追 加 した 受 信 データ Html HTMLソースのうち 指 定 タグをすべ て 取 得 指 定 したタグの 情 報 32
3 外 部 アプリ 起 動 /DB 保 存 コネクタが 左 側 に 存 在 するもの Node 名 称 Debug http response Cloudant Mail 機 能 フロー 上 に 流 れている 情 報 を 画 面 表 示 http requestを 返 す DBへのデータ 保 存 メール 送 信 33
プログラミング JavaScriptで 記 述 します 簡 易 エディターが 付 属 非 同 期 処 理 も 可 能 より 複 雑 な 処 理 は node の 作 成 をお 勧 めします function は 最 後 に return msg; をいれる と 次 のnode に 送 信 してくれます 詳 細 ドキュメント: http://nodered.org/docs/writing-functions.html 34
覚 えておくNode-RED 固 有 変 数 context.global context msg msg オブジェクト: node 間 を 流 れるメッセージを 表 す JSON オブジェクト msg.payload はかならず 存 在 する msg.<string> で 新 しい 属 性 を 追 加 できる context オブジェクト: node 内 部 で 保 存 される 任 意 の JSON オブジェクト context.global オブジェクト: node 間 で 共 有 されるグローバルオブジェクト 35
Node-REDの 起 動 Bluemixのダッシュボードに 記 載 されているLinkより Node-REDを 起 動 36
IoT Foundation(MQTTサーバー)からのデータ 取 り 出 し ibmiot ノードをドラッグ & ドロップ MQTTサーバー 上 のDevice IDに 紐 づくデー タをSubscribeする MQTTサーバー 上 にスマホの 位 置 情 報 が 届 い たら 取 り 出 す ドラッグ&ドロップ ibmiot ノードの 設 定 1. ノードをダブルクリック 2. Quickstartを 選 択 3. スマホの 画 面 に 表 示 されている Device IDを 入 力 スマホに 表 示 され ているDevice ID 37
データ 受 信 ができているかどうかの 確 認 debugウィンドウに 受 信 データを 表 示 1. debug ノードを ibmiot と 接 続 2. Deploy ボタンをを 押 し Node-REDアプ リケーションをDeploy 3. debugウィンドウにjson 形 式 でセンサーデ ータが 流 れてきていればOK 38
データの 絞 り 込 み 1 秒 に1Messageのみ 処 理 する 1. delay ノードを 接 続 2. Actionを Limit rate to に 設 定 3. Rateを 1 msg(s) per Secondに 設 定 4. drop intermediate messageをチ ェック ( 余 計 なデータを 廃 棄 する) 5. Deploy 6. 1 秒 間 でdebugウィンドウにメッセージ が 流 れてくることを 確 認 39
緯 度 経 度 情 報 の 抜 き 出 し function ノードで センサーデータから 緯 度 経 度 データのみを 抜 き 出 す 1. function ノードを 接 続 2. function に 下 記 のjavascript コードを 記 載 msg.payloadに MQTTサーバーから 取 得 したJSONデータが 含 まれる 緯 度 経 度 のみをmsg.payloadに 設 定 し 次 のノードに 流 す 3. Deployし 結 果 を 確 認 var latitude = msg.payload.d.location.lat; var longitude = msg.payload.d.location.lng; msg.payload = '[{"lat":"' + latitude + '","lng":"' + longitude + '"}]'; return msg; 40
Google Map APIを 使 った 位 置 情 報 の 可 視 化 1 WebSocketの 通 信 チャネルの 構 成 位 置 情 報 をリアルタイムで 送 信 /locationにて HTTP GET リ クエストを 待 ち 受 け Google Mapを 表 示 するHTML 位 置 情 報 はWebSocketで 受 け 取 る HTTPレスポンス を 返 す 41
Google Map APIを 使 った 位 置 情 報 の 可 視 化 2 NodeフローのImport 1. 次 のページのJSON 形 式 のデータをクリップ ボードにCopy 2. 右 上 のMenuボタンからImport 画 面 を 表 示 3. 入 力 ボックスにペーストしてImport 4. 既 存 のNodeと 接 続 する 接 続 する JSON 形 式 のNodeフローをペースト 42
ImportするNodeフローの 情 報 [{"id":"9457624.f6ba8a","type":"websocketlistener","path":"/ws/phone_location","wholemsg":"false"},{"id":"e0e0edd5.1f1f1","type":"function","name":"function 1","func":"// The received message is stored in 'msg' n// It will have at least a 'payload' property: n// console.log(msg.payload); n// The 'context' object is available to store state n// between invocations of the function n// context = {}; ncontext.global.location = msg.payload; n nreturn msg;","outputs":1,"noerr":0,"x":460,"y":178,"z":"b92fcfc3.46d03","wires":[["79854d92.867ab4"]]},{"id":"e2cc9f01.1d336","type":"function","name":"function 2","func":"// The received message is stored in 'msg' n// It will have at least a 'payload' property: n// console.log(msg.payload); n// The 'context' object is available to store state n// between invocations of the function n// context = {}; n nmsg.payload = context.global.location; n nreturn msg;","outputs":1,"noerr":0,"x":446.9999694824219,"y":239,"z":"b92fcfc3.46d03","wires":[["79854d92.867ab4"]]},{"id":"79854d92.867ab4","type":"websock et out","name":"","server":"9457624.f6ba8a","client":"","x":662.9999847412109,"y":239,"z":"b92fcfc3.46d03","wires":[]},{"id":"d38b4a94.2c74b8","type":"http response","name":"","x":648.9999847412109,"y":315,"z":"b92fcfc3.46d03","wires":[]},{"id":"9280276.f6d7fd8","type":"template","name":"google Map HTML","field":"","template":"<!DOCTYPE html> n<html> n<head> n <title>phone Location</title> n <script type= "text/javascript " src= "http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js "></script> n <script type= "text/javascript " src= "http://maps.google.com/maps/api/js?sensor=true "></script> n <script type= "text/javascript " src= "http://yourjavascript.com/4594301102/gmaps.js "></script> n n <style type= "text/css " media= "screen "> n #map { n position:absolute; n top: 0; bottom: 0; left: 0; right: 0; n } n </style> n</head> n<body> n n <div id= "map "></div> n <script type= "text/javascript "> n var socketaddy = "ws://phonefujita.mybluemix.net/ws/phone_location "; n var map; n var sock; n $(document).ready(function(){ n map = new GMaps({ n div: '#map', n lat: -12.043333, n lng: -77.028333 n }); n sock = new WebSocket(socketaddy); n sock.onopen = function(){ console.log( "Connected websocket "); n console.log( "Sending ping.. "); n sock.send( "Ping! "); n console.log( "Ping sent.. "); n }; n sock.onerror = function(){ console.log( "Websocket error "); }; n sock.onmessage = function(evt){ n var latlng = JSON.parse(evt.data); n var array = $.map(latlng, function(el) { n return [[el.lat, el.lng]]; n }); n n map.removemarkers(); n map.removepolylines(); n console.log( "Got marker at " + latlng[0].lat + ", " + latlng[0].lng, latlng); n map.setzoom(17); n map.setcenter(latlng[0].lat, latlng[0].lng); n map.addmarkers(latlng); n map.drawpolyline({ n path: array, n strokecolor: '#131540', n strokeopacity: 0.6, n strokeweight: 6 n }); n } n }); n </script> n</body> n</html>","x":431,"y":316,"z":"b92fcfc3.46d03","wires":[["d38b4a94.2c74b8"]]},{"id":"19638c78.e69c74","type":"http in","name":"","url":"/location","method":"get","swaggerdoc":"","x":207.99998474121094,"y":315,"z":"b92fcfc3.46d03","wires":[["9280276.f6d7fd8"]]},{"id":"fd 0f1e9b.02f0e","type":"websocket in","name":"","server":"9457624.f6ba8a","client":"","x":239.99998474121094,"y":239,"z":"b92fcfc3.46d03","wires":[["e2cc9f01.1d336"]]}] 43
Google Map APIを 使 った 位 置 情 報 の 可 視 化 3 WebSocketサーバーのアドレスの 変 更 1. Google Map HTMLと 書 かれたNodeをダブルクリック 2. HTML Fileをテキストエディタにコピー 3. WebSocketのアドレスを 修 正 ws://(アプリ 名 ).mybluemix.net/ws/phone_location 4. HTMLが 記 載 されたNodeに 修 正 後 のHTMLをCopy 5. Deploy 44
稼 働 確 認 スマホの 位 置 情 報 が MQTTサーバーに 送 付 され それがGoogle Map 上 にプロット されていることを 確 認 1. Debugウィンドウに 位 置 情 報 が 一 秒 に1 回 の 頻 度 で 流 れてくることを 確 認 2. ブラウザで Google Mapを 表 示 するWeb Pageにアクセス(/LocationにHTTP GET Request) http://(アプリ 名 ).mybluemix.net/location 3. 正 しい 位 置 情 報 がGoogle Mapに 反 映 されていることを 確 認 4. Chromeの 場 合 は 要 素 の 検 証 Console で 位 置 情 報 が1 秒 毎 にブラウザで 処 理 されていることが 確 認 できます 45
まとめ IoTアプリケーションを 構 築 する 際 には IoTでデファクトスタンダードとなりつつある 通 信 プロ トコルであるMQTTの 知 識 スキルが 必 要 IBMはクラウドサービスとしてMQTTサーバーを 提 供 (IoT Foundation) Node-REDは 直 感 的 な 操 作 で 簡 単 にIoTアプリケーションを 作 成 することが 可 能 Javascriptが 動 く 環 境 でMQTTサーバーにデータをリアルタイムに 送 信 する 場 合 WebSocketを 利 用 してMQTTサーバーに 接 続 するライブラリであるPahoが 便 利 46
一 般 のWEBサービスの 呼 び 出 し http request node を 利 用 する 事 前 に 呼 び 出 しパラメータを 設 定 する msg.url : WEBサービスURL msg.method: GET, PUT 等 msg.header: 必 要 があればヘッダーセット msg.payload: リクエストの body msg.topic: URL の <url>?<params>? 以 下 のパラメータ 47
例 : 楽 天 トラベル 施 設 検 索 API https://webservice.rakuten.co.jp/api/simplehotelsearch/ 48
参 考 フローのImport/Export Node-REDでは 作 成 したフローを 別 Node-RED 環 境 に 簡 単 に 移 すことができます 別 Node-RED 環 境 に 処 理 記 述 を 移 す 手 順 1 画 面 右 上 からExportを 選 択 2ポップアップのコードをコピー Node-REDでは 実 装 内 容 をText 形 式 で 保 持 49 3 画 面 右 上 からImportを 選 択 4 2でコピーしたTextを 貼 り 付 ける
Appendix - Nodeの 追 加 独 自 Nodeの 追 加 既 存 のノードでは 機 能 が 不 足 する 場 合 独 自 のノードも 容 易 に 追 加 可 能 記 述 ルールに 従 い nodesディレクトリ 配 下 にHTMLファイルとjsファイル 作 成 しデプロイ HTMLファイル:Nodeの 体 裁 を 定 義 ( 色 やアイコン 入 力 項 目 など) jsファイル:nodeでの 処 理 内 容 を 記 述 記 述 ルールやサンプル http://nodered.org/docs/creating-nodes/first-node.html 作 成 デプロイ 50
( 参 考 )lower-case.html, lower-case.js lower-case.html lower-case.js http://nodered.org/docs/creating-nodes/first-node.html 51
https://github.com/node-red http://flows.nodered.org 様 々な node や flow が 公 開 されています 52