2 min read

Web Bluetooth API

The Web Bluetooth API allows websites to communicate with nearby Bluetooth Low Energy (BLE) devices in a secure and privacy-preserving way.

1. The Connection Flow

Connecting to a BLE device involves a specific chain of promises:

  1. Request Device: Ask user to select a device.
  2. Connect to GATT Server: Establish connection.
  3. Get Service: Find the specific service you want (e.g., Battery Service).
  4. Get Characteristic: Find the specific data point (e.g., Battery Level).
  5. Read/Write/Notify: Interact with the data.

2. Requesting a Device

You must request a device in response to a user gesture (like a click). You must also specify which services you intend to use in optionalServices or filters.

const button = document.querySelector('#connect');

button.addEventListener('click', async () => {
  try {
    const device = await navigator.bluetooth.requestDevice({
      filters: [{ services: ['battery_service'] }]
      // or acceptAllDevices: true, optionalServices: ['battery_service']
    });

    console.log('Device selected:', device.name);

    // Connect to the GATT server
    const server = await device.gatt.connect();

    // Get the Battery Service
    const service = await server.getPrimaryService('battery_service');

    // Get the Battery Level Characteristic
    const characteristic = await service.getCharacteristic('battery_level');

    // Read the value
    const value = await characteristic.readValue();
    const percentage = value.getUint8(0);

    console.log(`Battery Level: ${percentage}%`);

  } catch (error) {
    console.error(error);
  }
});

3. Writing Data

To write data to a device (e.g., change the color of a light bulb), you write an ArrayBuffer or TypedArray.

// Assuming we have the 'characteristic' object for a light control
const data = new Uint8Array([1]); // 1 = On
await characteristic.writeValue(data);

4. Notifications (Events)

Instead of polling for data, you can subscribe to notifications to get updates whenever the value changes on the device.

await characteristic.startNotifications();

characteristic.addEventListener('characteristicvaluechanged', (event) => {
  const value = event.target.value;
  // Parse value...
  console.log('New value:', value.getUint8(0));
});

5. Requirements

  • HTTPS: Only works on secure contexts (and localhost).
  • User Gesture: Must be triggered by a user action.
  • Browser Support: Primarily Chromium-based browsers (Chrome, Edge, Opera) and Android. Limited/No support in Firefox/Safari (without flags or polyfills).

programming/javascript/vanilla/javascript programming/javascript/vanilla/promises-async-await programming/javascript/vanilla/typed-arrays