Start · Sprachen · JavaScript · Referenz · BluetoothRemoteGATTDescriptor.readValue()

BluetoothRemoteGATTDescriptor.readValue()

Methode

Liest den aktuellen Wert eines GATT-Deskriptors vom verbundenen Bluetooth-Gerät und gibt ein Promise zurück, das mit einem <code>DataView</code> erfüllt wird.

seit JavaScript Web Bluetooth API: Chrome/Edge 56+, Opera; nicht i Kategorie: webapi

Signatur

BluetoothRemoteGATTDescriptor.prototype.readValue()

Beschreibung

readValue() fordert den aktuellen Wert eines Deskriptors direkt vom entfernten Bluetooth-Low-Energy-Gerät an. Deskriptoren sind Metadaten zu einer Characteristic. Beispiele sind die Characteristic User Description (0x2901, ein lesbarer Name), die Client Characteristic Configuration (0x2902, der Status von Benachrichtigungen) oder das Presentation Format (0x2904).

Ist der Lesevorgang erfolgreich, wird das Promise mit einem DataView erfüllt. Gleichzeitig aktualisiert der Browser die Eigenschaft descriptor.value mit einer Kopie der gelesenen Daten. Wie die Bytes zu deuten sind, hängt vom Deskriptor ab: Texte liest man z. B. mit TextDecoder, Zahlen mit getUint16(0, true) (Little Endian, wie in der Bluetooth-Spezifikation üblich).

Die Methode funktioniert nur, wenn eine GATT-Verbindung besteht (device.gatt.connected === true) und der Deskriptor Lesezugriff erlaubt. Den Deskriptor bekommt man vorher über characteristic.getDescriptor() oder characteristic.getDescriptors().

Rückgabewert

Typ
Promise<DataView>
Beschreibung
Ein Promise, das mit einem DataView erfüllt wird. Der DataView enthält die Rohdaten des Deskriptors. Bei einem Fehler wird das Promise mit einer DOMException abgelehnt, z. B. NetworkError (keine Verbindung), NotSupportedError (Lesen nicht erlaubt), InvalidStateError (Deskriptor ungültig) oder SecurityError (Deskriptor steht auf der Sperrliste).

Beispiele

Benutzerbeschreibung (0x2901) einer Characteristic lesen

// Muss durch eine Nutzeraktion ausgelöst werden, z. B. einen Klick
const button = document.querySelector('#connect');

button.addEventListener('click', async () => {
  try {
    const device = await navigator.bluetooth.requestDevice({
      filters: [{ services: ['battery_service'] }]
    });
    const server = await device.gatt.connect();
    const service = await server.getPrimaryService('battery_service');
    const characteristic = await service.getCharacteristic('battery_level');

    const descriptor = await characteristic.getDescriptor(
      'gatt.characteristic_user_description'
    );
    const dataView = await descriptor.readValue();
    const text = new TextDecoder('utf-8').decode(dataView);
    console.log(`Beschreibung: ${text}`);
  } catch (error) {
    console.error(`Fehler: ${error.name} – ${error.message}`);
  }
});
Beschreibung: Akkustand

Prüfen, ob Benachrichtigungen aktiv sind (CCCD 0x2902)

const isNotifying = async (characteristic) => {
  const cccd = await characteristic.getDescriptor(
    'gatt.client_characteristic_configuration'
  );
  const value = await cccd.readValue();
  // Bit 0 = Notifications, Bit 1 = Indications (Little Endian)
  const flags = value.getUint16(0, true);
  return {
    notifications: Boolean(flags & 0x01),
    indications: Boolean(flags & 0x02)
  };
};

// Aufruf, nachdem characteristic.startNotifications() gelaufen ist
const status = await isNotifying(characteristic);
console.log(status);
{ notifications: true, indications: false }

Alle Deskriptoren einer Characteristic auslesen

const dumpDescriptors = async (characteristic) => {
  const descriptors = await characteristic.getDescriptors();
  for (const descriptor of descriptors) {
    try {
      const view = await descriptor.readValue();
      const bytes = [...new Uint8Array(view.buffer)]
        .map((b) => b.toString(16).padStart(2, '0'))
        .join(' ');
      console.log(`${descriptor.uuid}: ${bytes}`);
    } catch (error) {
      // z. B. NotSupportedError, wenn Lesen nicht erlaubt ist
      console.warn(`${descriptor.uuid}: ${error.name}`);
    }
  }
};

await dumpDescriptors(characteristic);
00002901-0000-1000-8000-00805f9b34fb: 41 6b 6b 75 00002902-0000-1000-8000-00805f9b34fb: 01 00

// Wichtig · Fallstricke

  • Browserunterstützung: Die Web Bluetooth API ist experimentell. Unterstützt wird sie nur in Chromium-Browsern (Chrome, Edge, Opera) unter Windows, macOS, ChromeOS und Android. Linux braucht teils ein Flag. Firefox und Safari (auch iOS) unterstützen die API nicht. Deshalb vorher prüfen: 'bluetooth' in navigator.
  • Sicherer Kontext: Die API gibt es nur über HTTPS oder localhost. requestDevice() braucht zusätzlich eine Nutzeraktion. In iframes ist die Permissions-Policy bluetooth nötig.
  • Sperrliste: Manche Deskriptoren sind für Lesezugriffe gesperrt. Bei ihnen wirft readValue() einen SecurityError. Ein Beispiel ist die Client Characteristic Configuration (0x2902) in manchen Implementierungen.
  • Verbindung: Bricht die GATT-Verbindung ab, schlagen laufende und neue Aufrufe mit NetworkError fehl. Deshalb auf das Event gattserverdisconnected reagieren.
  • Parallele Zugriffe: Viele Geräte und Plattformen können nur eine GATT-Operation gleichzeitig ausführen. Parallele Aufrufe (z. B. mit Promise.all) können mit NetworkError („GATT operation already in progress“) fehlschlagen. Aufrufe deshalb nacheinander mit await ausführen.
  • Der zurückgegebene DataView ist eine Kopie. Ändert man ihn, ändert sich nichts auf dem Gerät. Zum Schreiben dient writeValue().