react-native-ble-managerでRead/Write/Notify

前回react-native-ble-managerでコネクトまでしてみたという記事を書きました。

今回はbleデバイスに対してRead/Write/Notifyをやってみました。ライブラリの仕様がわからずちょっと苦戦しましたが、大体ios, androidのbluetoothの仕組みを理解していればすんなり実装できます。

Bluetooth接続の検証用デバイスには今回もtoio core cubeを使用しました。
toioをお持ちの方はtoio controllerを是非インストールしてみてください!

コード

Read/Write/Notify全てにおいてretrieveServicesを呼び出している必要があります。

呼び出しを忘れるとperipheralに対しての操作が全くできないので注意してください。

BleManager.retrieveServices(peripheral.id)

Read

toio core cubeのバッテリーをreadで取得するサンプルです。

(async()=>{
      await BleManager.connect(peripheral.id);

      const serviceUUID = '10B20100-5B3B-4571-9508-CF3EFCD7BBAE'
    const batteryUUID = '10B20108-5B3B-4571-9508-CF3EFCD7BBAE'

      await BleManager.retrieveServices(peripheral.id)

      // バッテリーのread
      const vattery = await BleManager.read(peripheral.id, serviceUUID, batteryUUID);
      console.log(`バッテリ-: ${vattery}`)
    })();

Write

writeにはwriteWithoutResponseとwriteの2種類のメソッドが用意されています。

デバイスへの書き込みの成功の有無の取得です。

writeWithoutResponse

toioのモーターへの書き込みはresponseが帰ってこないのでこちらのメソッドを使用します。

(async()=>{
      await BleManager.connect(peripheral.id);

      const serviceUUID = '10B20100-5B3B-4571-9508-CF3EFCD7BBAE'
      const moterUUID = '10B20102-5B3B-4571-9508-CF3EFCD7BBAE'

      await BleManager.retrieveServices(peripheral.id)

      // モーターへの書き込みresponseなしのwrite
      await BleManager.writeWithoutResponse(
        peripheral.id,
        serviceUUID,
        moterUUID,
        [0x01, 0x01, 0x01, 0x30, 0x02, 0x01, 0x30]);
    })();

write

toio core cubeのランプへの書き込みはresponseを受け取ります。maxNumberは省略できないので必ずしていしてください。

(async()=>{
      await BleManager.connect(peripheral.id);

      const serviceUUID = '10B20100-5B3B-4571-9508-CF3EFCD7BBAE'
      const lightUUID = '10B20103-5B3B-4571-9508-CF3EFCD7BBAE'

      const peripheralInfo = await BleManager.retrieveServices(peripheral.id)
   
      await BleManager.write(peripheral.id,
        serviceUUID,
        lightUUID,
        [0x03, 0x00, 0x01, 0x01, 0xFF, 0x00, 0x00],
        10) 
        .then(()=>{ console.log('成功'); })
        .catch((err)=>{ console.log(`エラー: ${err}`); })

    })();

Notify

Notifyを受け取るにはscanの時同様NativeEventEmitterでハンドラーを用意する必要があります。

公式のExampleを真似して以下の様にイベントエミッターを設定します。

constructor(){
    super()
    this.handleUpdateValueForCharacteristic = this.handleUpdateValueForCharacteristic.bind(this);
  }
//notificationの受け取り
handleUpdateValueForCharacteristic(data) {
    console.log('Received data from ' + data.peripheral + ' characteristic ' + data.characteristic, data.value);
}
componentDidMount() {
    //リスナーを登録
    this.handlerUpdate = bleManagerEmitter.addListener('BleManagerDidUpdateValueForCharacteristic', this.handleUpdateValueForCharacteristic );
}

cubeのconfigurationにNotifyが用意されていたので適当な値を書いてみます。

writeされるとwritehandleUpdateValueForCharacteristicメソッドに処理が帰ってきます。

(async()=>{
      await BleManager.connect(peripheral.id);

      const serviceUUID = '10B20100-5B3B-4571-9508-CF3EFCD7BBAE'
      const configurationUUID = '10B201FF-5B3B-4571-9508-CF3EFCD7BBAE'

      const peripheralInfo = await BleManager.retrieveServices(peripheral.id)
      
      //Notifyを設定しておく
      await BleManager.startNotification(peripheral.id,serviceUUID,configurationUUID);
      await BleManager.write(peripheral.id, serviceUUID, configurationUUID, [0x01, 0x00]);
      
    })();

参考文献

react-native-ble-manager