Search code examples
next.jsbluetoothbluetooth-lowenergyweb-bluetooth

How do you declare multiple characteristics in Web Bluetooth?


I have no clue how to implement multiple characteristics:

Currently my code works perfectly when a single characteristic is declared/implemented:

   .then((service) => {
    pushlog("Getting Shutdown Characteristic...");
    shdn = service.getCharacteristic(
      "33ca7a02-c95f-4bca-a8bb-6692930216d0"
    ); return shdn;

However, when I attempt to implement multiple characteristics (the plain-text uuid's work with web bluetooth):

.then((service) => {
    pushlog("Getting Characteristic...");
    heart_rate_measurement = service.getCharacteristic(
      "heart_rate_measurement"
    );
    temperature_measurement = service.getCharacteristic(
      "temperature_measurement"
    );
    shdn = service.getCharacteristic(
      "33ca7a02-c95f-4bca-a8bb-6692930216d0"
    );
    stim = service.getCharacteristic(
      "b71ce29e-7353-40bf-a4dd-b0c03593e0ba"
    );
    battery = service.getCharacteristic("battery_level");

    return (
      shdn, heart_rate_measurement, temperature_measurement, stim, battery
    );
  })

My read/write code doesn't work -

.then((shdn) => {
    pushlog("Writing to Shutdown Characteristic...");

    // Writing 1 is the signal to reset energy expended.
    let resetEnergyExpended = Uint8Array.of(0x01);
    return shdn.writeValue(resetEnergyExpended);
  })

Am I declaring these additional characteristics incorrectly? All the resources I see are for android BLE and not web bluetooth. I saw some solutions using classes, however, I'm using next.js and I'm clueless of how to implement vanilla JS classes into react.


Solution

  • service.getCharacteristic() returns a Promise and so in order to have your program properly wait for all of the promises you return to resolve before executing the callback passed to then() you need to wrap the list in Promise.all(). The callback will get a list which you then need to unpack to get all the individual characteristic objects.

    Destructuring makes this relatively easy to write:

    .then((service) => {
        pushlog("Getting Characteristic...");
        heart_rate_measurement = service.getCharacteristic(
          "heart_rate_measurement"
        );
        temperature_measurement = service.getCharacteristic(
          "temperature_measurement"
        );
        shdn = service.getCharacteristic(
          "33ca7a02-c95f-4bca-a8bb-6692930216d0"
        );
        stim = service.getCharacteristic(
          "b71ce29e-7353-40bf-a4dd-b0c03593e0ba"
        );
        battery = service.getCharacteristic("battery_level");
    
        return Promise.all([
          shdn, heart_rate_measurement, temperature_measurement, stim, battery
        ]);
      })
    .then(([shdn, heart_rate_measurement, temperature_measurement, stim, battery]) => {
        pushlog("Writing to Shutdown Characteristic...");
    
        // Writing 1 is the signal to reset energy expended.
        let resetEnergyExpended = Uint8Array.of(0x01);
        return shdn.writeValue(resetEnergyExpended);
      })