manekinekko / angular-web-bluetooth

The missing Web Bluetooth module for Angular
https://manekinekko.github.io/angular-web-bluetooth/
MIT License
196 stars 59 forks source link

How can I subscribe to multiple services (via notify) ble simultaneously with a single click on the button? #70

Closed federicoder closed 1 year ago

federicoder commented 3 years ago

Is your feature request related to a problem? Please describe. I created a common service ble like this:

`import { Injectable } from '@angular/core';
import { BluetoothCore } from '@manekinekko/angular-web-bluetooth';
import { map } from 'rxjs/operators';
@Injectable({
  providedIn: 'root'
})
export class BatteryLevelService {

  constructor(public readonly ble: BluetoothCore) {}

  getDevice() {
    // call this method to get the connected device
    return this.ble.getDevice$();
  }

  stream() {
    // call this method to get a stream of values emitted by the device for a given characteristic
    return this.ble.streamValues$().pipe(
      map((value: DataView) => value.getInt8(0))
    );
  }

  disconnectDevice() {
    // call this method to disconnect from the device. This method will also stop clear all subscribed notifications
    this.ble.disconnectDevice();
  }

  value() {
    console.log('Getting Battery level...');

    return this.ble
      .value$({
        service: 'battery_service',
        characteristic: 'battery_level'
      });
  }}`

and i try to use it on 2 components but i want just to click one time to read 2 values from 2 different charateristics of 2 services of ble.
Thanks in advance for the reply.

manekinekko commented 3 years ago

Hi,

Here is how you can merge multiple streams using RxJS: https://indepth.dev/posts/1114/learn-to-combine-rxjs-sequences-with-super-intuitive-interactive-diagrams

federicoder commented 3 years ago

Hi,

Here is how you can merge multiple streams using RxJS: https://indepth.dev/posts/1114/learn-to-combine-rxjs-sequences-with-super-intuitive-interactive-diagrams

okay thank you very much 👍 and another question : in which way have i to do to make the popup open only once and subscribe to all services (i have 4 service to subscribing) at the same time.

manekinekko commented 3 years ago

We currently don't support batch operations. This is something we are currently exploring (via #65). Please stay tuned.

If you are looking for a workaround, you can try calling discover$() and them combine different streams like so:

this.ble

        // 1) call the discover method will trigger the discovery process (by the browser)
        .discover$({
          acceptAllDevices: true,
          optionalServices: [BatteryLevelService.GATT_PRIMARY_SERVICE]
        })
        .pipe(

          // 2) get that service
          mergeMap((gatt: BluetoothRemoteGATTServer) => {
            return this.ble.getPrimaryService$(gatt, BatteryLevelService.GATT_PRIMARY_SERVICE);
          }),

          // 3) get a specific characteristic on that service
          mergeMap((primaryService: BluetoothRemoteGATTService) => {
            return this.ble.getCharacteristic$(primaryService, BatteryLevelService.GATT_CHARACTERISTIC_BATTERY_LEVEL);
          }),

          // 4) ask for the value of that characteristic (will return a DataView)
          mergeMap((characteristic: BluetoothRemoteGATTCharacteristic) => {
            return this.ble.readValue$(characteristic);
          }),

          // 5) on that DataView, get the right value
          map((value: DataView) => value.getUint8(0))
        )
manekinekko commented 1 year ago

Fixed by https://github.com/manekinekko/angular-web-bluetooth/pull/76