Start · Sprachen · JavaScript · Referenz · BluetoothRemoteGATTCharacteristic.startNotifications()

BluetoothRemoteGATTCharacteristic.startNotifications()

Methode

Abonniert Benachrichtigungen bzw. Indikationen einer GATT-Charakteristik. Das Promise wird mit derselben <code>BluetoothRemoteGATTCharacteristic</code>-Instanz erfüllt, sobald das Abo aktiv ist.

seit JavaScript Chrome 56+, Edge 79+, Opera 43+ (Chromium, nur in Kategorie: webapi

Signatur

BluetoothRemoteGATTCharacteristic.prototype.startNotifications()

Beschreibung

startNotifications() weist ein verbundenes Bluetooth-Low-Energy-Gerät an, Wertänderungen einer Charakteristik von sich aus zu senden (Push). Dafür schreibt der Browser in den Client Characteristic Configuration Descriptor (CCCD, UUID 0x2902) das Bit für Notify oder Indicate. Indikationen werden vom Empfänger bestätigt, Benachrichtigungen nicht. Welches der beiden Verfahren zum Einsatz kommt, hängt davon ab, was die Charakteristik unterstützt.

Die Methode eignet sich für alle Messwerte, die sich laufend ändern, etwa Herzfrequenz, Akkustand, Sensordaten oder Tastendrücke. Ohne sie müsste man den Wert ständig mit readValue() abfragen. Jeder neu eintreffende Wert löst auf der Charakteristik das Event characteristicvaluechanged aus. Der aktuelle Wert steht danach als DataView in characteristic.value.

Voraussetzung ist eine aktive GATT-Verbindung (device.gatt.connect()). Außerdem muss die Charakteristik in properties.notify oder properties.indicate den Wert true haben. Am besten registrieren Sie den Event-Listener vor dem Aufruf, damit kein früher Wert verloren geht. Mit stopNotifications() beenden Sie das Abo wieder.

Rückgabewert

Typ
Promise<BluetoothRemoteGATTCharacteristic>
Beschreibung
Ein Promise, das mit derselben Charakteristik-Instanz erfüllt wird, sobald das Abo aktiv ist. In diesen Fällen wird es mit einer DOMException abgelehnt: NotSupportedError (weder Notify noch Indicate wird unterstützt), NetworkError (GATT-Server nicht verbunden), InvalidStateError (Charakteristik ungültig geworden) oder SecurityError (Zugriff auf eine gesperrte UUID).

Beispiele

Herzfrequenz eines Brustgurts live empfangen

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

button.addEventListener('click', async () => {
  // requestDevice() nur nach einer Nutzeraktion aufrufen
  const device = await navigator.bluetooth.requestDevice({
    filters: [{ services: ['heart_rate'] }]
  });
  const server = await device.gatt.connect();
  const service = await server.getPrimaryService('heart_rate');
  const characteristic = await service.getCharacteristic('heart_rate_measurement');

  // Listener VOR startNotifications() registrieren
  characteristic.addEventListener('characteristicvaluechanged', (event) => {
    const value = event.target.value; // DataView
    const flags = value.getUint8(0);
    // Bit 0 gibt an, ob der Wert 8 oder 16 Bit breit ist
    const bpm = flags & 0x01 ? value.getUint16(1, true) : value.getUint8(1);
    console.log(`Puls: ${bpm} bpm`);
  });

  await characteristic.startNotifications();
  console.log('Benachrichtigungen aktiv');
});
Benachrichtigungen aktiv Puls: 72 bpm Puls: 74 bpm

Unterstützung vorab prüfen und Fehler abfangen

const subscribe = async (characteristic, onValue) => {
  const { notify, indicate } = characteristic.properties;
  if (!notify && !indicate) {
    throw new Error('Charakteristik unterstützt keine Benachrichtigungen');
  }

  const handler = (event) => onValue(event.target.value);
  characteristic.addEventListener('characteristicvaluechanged', handler);

  try {
    await characteristic.startNotifications();
  } catch (err) {
    characteristic.removeEventListener('characteristicvaluechanged', handler);
    console.error(`${err.name}: ${err.message}`);
    throw err;
  }

  // Funktion zum Abmelden zurückgeben
  return async () => {
    characteristic.removeEventListener('characteristicvaluechanged', handler);
    if (characteristic.service.device.gatt.connected) {
      await characteristic.stopNotifications();
    }
  };
};

// Nutzung:
// const unsubscribe = await subscribe(batteryLevel, (v) => console.log(v.getUint8(0) + ' %'));
// später: await unsubscribe();
87 %

Verkettung über den Rückgabewert und Wiederverbindung

const device = await navigator.bluetooth.requestDevice({
  filters: [{ services: ['battery_service'] }]
});

const connectAndSubscribe = async () => {
  const server = await device.gatt.connect();
  const service = await server.getPrimaryService('battery_service');
  const characteristic = await service.getCharacteristic('battery_level');
  // Das Promise wird mit der Charakteristik selbst erfüllt
  const active = await characteristic.startNotifications();
  active.oncharacteristicvaluechanged = (e) =>
    console.log('Akku:', e.target.value.getUint8(0), '%');
};

// Nach einem Verbindungsabbruch ist das Abo verloren und muss neu angelegt werden
device.addEventListener('gattserverdisconnected', () => {
  console.log('Getrennt – verbinde neu …');
  connectAndSubscribe().catch(console.error);
});

await connectAndSubscribe();
Akku: 87 %

// Wichtig · Fallstricke

  • Browser-Unterstützung: Web Bluetooth gibt es nur in Chromium-Browsern (Chrome, Edge, Opera, teils Android). Firefox und Safari/iOS unterstützen die API nicht. Auf Linux kann ein Flag nötig sein. Prüfen Sie die Verfügbarkeit mit 'bluetooth' in navigator.
  • Sicherer Kontext: Die API funktioniert nur über HTTPS oder localhost. requestDevice() braucht eine Nutzeraktion (z. B. einen Klick). In iframes muss die Permissions-Policy bluetooth erlaubt sein.
  • Reihenfolge: Registrieren Sie den Listener für characteristicvaluechanged vor dem Aufruf. Manche Geräte senden sofort nach dem Abonnieren einen Wert.
  • Abo geht bei Trennung verloren: Bei gattserverdisconnected müssen Sie neu verbinden und startNotifications() erneut aufrufen. Alte Charakteristik-Objekte können danach ungültig sein.
  • Nicht parallel aufrufen: Laufen mehrere GATT-Operationen gleichzeitig, schlagen sie oft mit NetworkError („GATT operation already in progress“) fehl. Verketten Sie die Aufrufe deshalb nacheinander mit await.
  • Datenformat: value ist ein DataView. Byte-Reihenfolge und Aufbau legt das jeweilige GATT-Profil fest; bei BLE ist das meist Little Endian.
  • Datenschutz: Einige UUIDs sind auf der Blockliste von Web Bluetooth gesperrt und lösen einen SecurityError aus. Dienste, die nicht in filters stehen, müssen Sie in optionalServices angeben.