Signatur
Beschreibung
BluetoothRemoteGATTDescriptor gehört zur Web Bluetooth API und steht für einen Descriptor im GATT-Profil (Generic Attribute Profile) eines entfernten Bluetooth-Low-Energy-Geräts. Descriptors hängen an einer BluetoothRemoteGATTCharacteristic und liefern Metadaten zu deren Wert. Beispiele sind die menschenlesbare Beschreibung (Characteristic User Description, 0x2901), das Darstellungsformat (0x2904) oder der Client Characteristic Configuration Descriptor (CCCD, 0x2902), über den Benachrichtigungen ein- und ausgeschaltet werden.
Einen Descriptor bekommst du nicht über einen Konstruktor. Du erhältst ihn über characteristic.getDescriptor(uuid) oder characteristic.getDescriptors(). Die Schnittstelle hat folgende Eigenschaften und Methoden:
characteristic(nur lesbar): die zugehörigeBluetoothRemoteGATTCharacteristic.uuid(nur lesbar): die UUID des Descriptors als String, z. B."00002901-0000-1000-8000-00805f9b34fb".value(nur lesbar): einDataViewmit dem zuletzt gelesenen Wert, odernull, wenn noch nichts gelesen wurde.readValue(): liest den aktuellen Wert vom Gerät und gibt einPromise<DataView>zurück.writeValue(value): schreibt einenArrayBuffer, einTypedArrayoder einenDataViewauf das Gerät und gibt einPromise<void>zurück.
Typische Einsatzfälle: Du liest aus, was eine Characteristic bedeutet (Name, Einheit, Wertebereich), oder du wertest herstellerspezifische Descriptors aus. Benachrichtigungen schaltest du dagegen über startNotifications() der Characteristic. Der CCCD lässt sich nicht direkt beschreiben.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value Pflicht | ArrayBuffer|TypedArray|DataView | Nur bei writeValue(value): die Bytes, die in den Descriptor geschrieben werden. Maximal 512 Bytes. |
Rückgabewert
readValue() erfüllt sich mit einem DataView des gelesenen Werts und aktualisiert zugleich value. writeValue() erfüllt sich ohne Wert, sobald der Schreibvorgang bestätigt ist.Beispiele
Descriptor holen und Benutzerbeschreibung lesen
const connectAndDescribe = async () => {
// Muss durch eine Nutzeraktion ausgelöst werden (z. B. Klick)
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');
// 0x2901 = Characteristic User Description
const descriptor = await characteristic.getDescriptor('gatt.characteristic_user_description');
const dataView = await descriptor.readValue();
const text = new TextDecoder('utf-8').decode(dataView);
console.log(`Descriptor ${descriptor.uuid}: ${text}`);
};
document.querySelector('#connect').addEventListener('click', () => {
connectAndDescribe().catch((err) => console.error('Fehler:', err));
});
Alle Descriptors einer Characteristic auflisten
const listDescriptors = async (characteristic) => {
const descriptors = await characteristic.getDescriptors();
for (const d of descriptors) {
try {
const view = await d.readValue();
const bytes = [...new Uint8Array(view.buffer)]
.map((b) => b.toString(16).padStart(2, '0'))
.join(' ');
console.log(`${d.uuid} -> ${bytes}`);
} catch (err) {
// Lesen kann verboten sein (z. B. Blocklist) oder fehlschlagen
console.warn(`${d.uuid} nicht lesbar: ${err.name}`);
}
}
};
Herstellerspezifischen Descriptor beschreiben
const setUserDescription = async (characteristic, label) => {
const descriptor = await characteristic.getDescriptor('gatt.characteristic_user_description');
const data = new TextEncoder().encode(label); // Uint8Array
await descriptor.writeValue(data);
console.log('Geschrieben, lokaler Wert:', descriptor.value); // bleibt bis zum nächsten readValue() unverändert
const check = await descriptor.readValue();
console.log('Neu gelesen:', new TextDecoder().decode(check));
};
// Wichtig · Fallstricke
- Browser-Unterstützung: Die API ist experimentell und nur in Chromium-Browsern (Chrome, Edge, Opera) auf Desktop und Android verfügbar. Firefox und Safari (auch iOS) unterstützen sie nicht. Prüfe die Verfügbarkeit mit
'bluetooth' in navigator. - Sicherer Kontext: Die API funktioniert nur über HTTPS oder
localhost.requestDevice()muss durch eine Nutzeraktion ausgelöst werden, sonst gibt es einenSecurityError. - Blocklist: Manche Descriptors sind gesperrt. Der CCCD (
0x2902) und der Server Characteristic Configuration Descriptor (0x2903) lassen sich nicht direkt beschreiben, manche auch nicht lesen. In diesen Fällen wirft der Aufruf einenSecurityError. Benachrichtigungen aktivierst du stattdessen mitcharacteristic.startNotifications(). - Werte ändern sich nicht automatisch:
valueistnull, bisreadValue()einmal aufgerufen wurde. Die Eigenschaft wird auch nachwriteValue()nicht aktualisiert. - Verbindungsabbruch: Ist das Gerät getrennt, schlagen die Methoden mit einem
NetworkErrorfehl. Reagiere auf das EreignisgattserverdisconnectedamBluetoothDevice. - Parallele GATT-Operationen können mit
NotSupportedErroroder „GATT operation already in progress“ fehlschlagen. Führe Lese- und Schreibzugriffe deshalb nacheinander mitawaitaus.