公私共に年末に向けてバタバタしながらもaptpod Advent Calendar 2018の9日目。
2018年もブラウザの進化が止まらない1年でしたね。その中でもWebBluetoothがWindows 10のChromeでも使えるようになった
のはインパクトでかかったです。仕事でも実際に導入していろいろいじくり倒しました(その時の記事「Web Bluetoothを実戦投入すると意外と使えたメモ」)。
今回はWeb BluetoothでBLEデバイスとデータ通信する際のRead/Write/Notificationsをシンプルなコードで紹介します。
ソースコード
データ通信する前の下準備
BLEデバイスとデータ通信する前に、ブラウザからBLEデバイスをスキャンし接続する必要があります。スキャン時は、デバイス名・サービスUUIDでフィルタリングすることができます。
// Service UUID
const SERVICE_UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
// Characteristic UUID
const CHARACTERISTIC_UUID = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
// Scan
navigator.bluetooth.requestDevice({
// 全てのBLEデバイスをスキャン対象とする場合はtrue
// フィルタリングしたい場合はfalse
acceptAllDevices: false,
// デバイス名, デバイス名のプレフィックス, ServiceのUUID
filters: [
{name: 'デバイス名'},
{namePrefix: 'デバイス名のプレフィックス'},
{services: [SERVICE_UUID]}
}],
// 接続するService
optionalServices: [SERVICE_UUID]
})
.then(device => {
// 接続
return device.gatt.connect()
}))
.then(server => {
// Service取得
return server.getPrimaryService(SERVICE_UUID)
})
.then(service => {
// Characteristic取得
return service.getCharacteristic(CHARACTERISTIC_UUID)
})
.then(characteristic => {
// characteristicに対してRead/Write/Notificationsの処理を記述
})
.catch(error => console.error(error))
Read
characteristic.readValue()
.then(response => {
// データがStringの場合
const decoder = new TextDecoder('utf-8')
const str = decoder.decode(response)
console.log(str)
// データがnumberの場合
const num = getUintN(response)
console.log(num)
})
.catch(error => console.error(error))
// 数値変換
const getUintN = (dataView) => {
switch(dataView.byteLength) {
case 0:
return 0
case 1:
return dataView.getUint8(0)
case 2:
return dataView.getUint16(0)
case 4:
return dataView.getUint32(0)
case 8: {
const top = dataView.getUint32(0) * Math.pow(2, 32)
const bottom = dataView.getUint32(4)
return top + bottom
}
default:
return 0
}
}
Write
const num = 1
characteristic.writeValue(new Uint8Array([num]));
Notifications
// Add Event
characteristic.addEventListener('characteristicvaluechanged', handler)
characteristic.startNotifications()
.catch(error => {
// Remove Event
characteristic.removeEventListener('characteristicvaluechanged', handler)
console.error(error)
})
const handler = (event) => {
const value = event.target.value
// データがStringの場合
const decoder = new TextDecoder('utf-8')
const str = decoder.decode(value)
console.log(str)
// データがnumberの場合
const num = getUintN(value)
console.log(num)
}
手元にBLEデバイスがないけど試してみたい場合は
iOSアプリ「LightBlue® Explorer」で仮想のBLEデバイスを作成して試してみてください。無料で使えるので気軽に雰囲気がつかめると思います。
まとめ
普段の開発でWeb Bluetoothに触れる機会は少ないと思います。ですが、ブラウザの進化とともにJSでできることがこれからも広がっていくでしょう。ブラウザが限定されてしまうこともありますが、 次のWebで何ができるのか
積極的にキャッチアップしていければと思います。