概要
ウェアラブルウォッチ「mio FUSE」が計測するリアルタイム心拍数を、Device Web API ManagerによってWebサーバー化したAndroidデバイスを介し、WebSocketで受信する。
Device Web API Managerは「Device Connectシステムをスマートフォン上で実現するアプリケーション1」で、これ
を用いることで、APIが公開されていないスマートデバイスでも、REST API / WebSocketで簡単にデータを取得することができる。
環境
- Mio Fuse
- Android 8.0.0
- Device Web API Manager 2.3.0
- macOS 10.13.6 High Sierra
- Node.js 7.9.0
- websocket-client 0.53.0
Mio FUSEとは
ウェアラブルウォッチ。心拍数を測ることができる。
Device Web API Managerとは
Device Web API Managerは「Device Connectシステムをスマートフォン上で実現するアプリケーション1」。
Device Connectとは
Device Connectはスマートフォン上に仮想のHTTPサーバを立てて、それを介してスマートデバイス(Pebble、THETA、Hue、スマートグラスなどなど)をWeb APIで操作できるGotAPIの一実装です。
NTT docomo社が中心となって開発、啓蒙している技術で、各種デバイスへの接続をDeviceConnectが行い、さらにその操作するAPIをWeb APIとして提供してくれるものです。スマートフォンの中にアプリケーションサーバが立ち上がるので、Web APIを使ってデバイスにデータを送ったり、逆に取り出せるようになります。
hifive x DeviceConnectによるWoT体験ハンズオン!
何が便利なのか
- スマートデバイスへのアクセスを抽象化してくれる。
- APIが公開されていないスマートデバイスでも、REST API / WebSocketで簡単にデータを取得したり、デバイスの操作ができる。
DeviceConnectの情報
- DeviceConnect Users - DeviceConnect WebAPIに関するドキュメントをまとめたページ
- DeviceConnect-Docs Wiki - Wiki。Device Connectの仕様はここで確認できる
- DeviceConnect - GitHub
やってみよう
Device Web API Manager
インストールとビルド
- AndroidデバイスにDevice Web API Managerをインストール
- ビルドマニュアルに沿って、HeartRateプラグインをビルド
プラグインがビルドされると、「MIO GLOBAL-FUSEアイコン」がトップページに表示される。
Mio FUSEとAndroidデバイスをBluetooth接続
AndroidデバイスにMio Goをインストールし、MioFuseとAndroidデバイスをBluetooth接続する。
接続に成功すると、「MIO GLOBAL-FUSEアイコン」が明るくなる。
設定
「トップページ」の右上から「設定」に進み、必要な設定をする。
一部の設定はDevice Web API Managerをオフにしないと変更できないので、オフにする。
変更を終えたら、再びオンにする。
認証
「外部IPを許可」にチェック
「Local OAuth認証」「Origin有効化」のチェックを外し、無効にする(手順を簡略化するための、本記事固有の設定です)。
Host
serviceId
「トップページ」→「MIO GLOBAL-FUSE」→「serviceinfomation」→「GET /gotapi/serviceinfomation/」
と進み、表示されたserviceIdを控えておく。
WebSocketで受信する
macOSデバイスからWebSocketでリアルタイム心拍数を取得する。
macOSデバイスとAndroidデバイスを、あらかじめ同じネットワークに接続しておく。
手順
WebSocketについて - DeviceConnect Users
上記ページにある手順を、簡潔にまとめた。
- 接続
- sessionKeyを送信
- Web APIをコール
- イベントの受信
これをNode.jsで実装したのが下のコードになる。
Node.jsでの実装
a-r-i/deviceconnect_websocket_nodejs - GitHub
WebSocket受信部分
const WebSocket = require('ws');
const hostname = ''; //控えておいたHost
const ws = new WebSocket('ws://'+ hostname +':4035/websocket');
const sessionKey = 'test'; //sessionKeyはなんでもよい
ws.onopen = function () { //1.接続
ws.send('{"sessionKey": "' + sessionKey+ '"}'); //2.sessionKeyを送信
callWebAPI(sessionKey); //3.Web APIをコール
};
ws.onerror = function (error) {
console.log(error);
};
ws.onmessage = function (message) { //4.イベントの受信
try {
var json = JSON.parse(message.data);
var bpm = json['heart']['rate']['value'];
console.log('BPM:' + bpm);
} catch (e) {
console.log('This doesn\'t look like a valid JSON: ',
message.data);
return;
}
};
WebAPIコール部分
const http = require('http');
function callWebAPI(sessionKey) {
const resource = 'health/onheart'; //心拍数APIのパス
const serviceId = ''; //控えたserviceId
const options = {
host: hostname,
port: '4035',
path: '/gotapi/' + resource + '?serviceId=' + serviceId + '&sessionKey=' + sessionKey,
method: 'PUT',
headers: {
'Content-Type': 'application/json'
}
};
const req = http.request(options, function (res) {
var responseString = '';
res.on('data', function (data) {
responseString += data;
try {
var json = JSON.parse(data);
} catch (e) {
console.log('This doesn\'t look like a valid JSON: ',
data);
return;
}
});
res.on('end', function () {
return responseString;
});
});
req.on('error', function (error) {
console.log(error);
});
req.end();
}