Posted at
aptpodDay 9

Web Bluetooth(Read/Write/Notifications)の使い方まとめ

公私共に年末に向けてバタバタしながらも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で何ができるのか 積極的にキャッチアップしていければと思います。