Signatur
Beschreibung
Die schreibgeschützte Eigenschaft properties einer BluetoothRemoteGATTCharacteristic gibt ein BluetoothCharacteristicProperties-Objekt zurück. Dieses beschreibt, welche GATT-Operationen das entfernte Bluetooth-Low-Energy-Gerät für diese Characteristic erlaubt. Jede Fähigkeit ist ein eigenes boolesches Feld, z. B. read, write, writeWithoutResponse, notify, indicate, broadcast, authenticatedSignedWrites, reliableWrite und writableAuxiliaries.
Man nutzt die Eigenschaft vor allem, bevor man eine Operation ausführt: Statt blind readValue(), writeValueWithResponse() oder startNotifications() aufzurufen und auf einen NotSupportedError zu warten, prüft man vorab, ob die Characteristic die Operation überhaupt anbietet. Das ist besonders bei generischen Tools (z. B. BLE-Explorern) oder bei Geräten mit unterschiedlichen Firmware-Versionen nützlich.
Die Werte stammen aus dem Characteristic-Declaration-Attribut des Geräts und ändern sich während der Verbindung nicht. Es handelt sich um eine reine Eigenschaft ohne Parameter; der Zugriff ist synchron.
Rückgabewert
broadcast, read, writeWithoutResponse, write, notify, indicate, authenticatedSignedWrites, reliableWrite, writableAuxiliaries).Beispiele
Unterstützte Operationen einer Characteristic prüfen
// Muss durch eine Nutzergeste (z. B. Klick) ausgelöst werden
const button = document.querySelector('#connect');
button.addEventListener('click', async () => {
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 { read, notify, write } = characteristic.properties;
console.log({ read, notify, write });
});
Nur lesen bzw. abonnieren, wenn erlaubt
const subscribeOrRead = async (characteristic, onValue) => {
const props = characteristic.properties;
if (props.notify || props.indicate) {
characteristic.addEventListener('characteristicvaluechanged', (event) => {
onValue(event.target.value);
});
await characteristic.startNotifications();
return 'abonniert';
}
if (props.read) {
onValue(await characteristic.readValue());
return 'einmalig gelesen';
}
throw new Error('Characteristic ist weder lesbar noch abonnierbar');
};
// Nutzung, z. B. mit einer Herzfrequenz-Characteristic:
// const modus = await subscribeOrRead(hrChar, (dv) => console.log(dv.getUint8(1)));
Alle Fähigkeiten als Liste ausgeben (BLE-Explorer)
const FLAGS = [
'broadcast', 'read', 'writeWithoutResponse', 'write', 'notify',
'indicate', 'authenticatedSignedWrites', 'reliableWrite', 'writableAuxiliaries'
];
const describeCharacteristic = (characteristic) => {
const active = FLAGS.filter((flag) => characteristic.properties[flag]);
return `${characteristic.uuid}: ${active.join(', ') || 'keine'}`;
};
// const chars = await service.getCharacteristics();
// chars.forEach((c) => console.log(describeCharacteristic(c)));
Passende Schreibmethode wählen
const writeCommand = async (characteristic, bytes) => {
const data = new Uint8Array(bytes);
const { write, writeWithoutResponse } = characteristic.properties;
if (write) {
await characteristic.writeValueWithResponse(data);
} else if (writeWithoutResponse) {
await characteristic.writeValueWithoutResponse(data);
} else {
throw new Error('Characteristic ist nicht beschreibbar');
}
};
// await writeCommand(ledChar, [0x01, 0xff, 0x00, 0x00]);
// Wichtig · Fallstricke
- Browser-Kompatibilität: Web Bluetooth ist experimentell und nur in Chromium-basierten Browsern (Chrome, Edge, Opera; auf Desktop und Android) verfügbar. Firefox und Safari unterstützen die API nicht – vorher mit
'bluetooth' in navigatorprüfen. - Die API funktioniert nur in einem sicheren Kontext (HTTPS oder
localhost), undrequestDevice()erfordert eine Nutzergeste. In Iframes ist die Permissions-Policybluetoothnötig. - Die Flags geben an, was das Gerät deklariert – eine Operation kann trotzdem scheitern, z. B. wegen fehlender Kopplung/Verschlüsselung, einer getrennten Verbindung oder einer Characteristic auf der Blocklist (
SecurityError). writeundwriteWithoutResponsesind unterschiedliche Fähigkeiten: Die veraltete MethodewriteValue()wählt den Modus selbst; besser explizitwriteValueWithResponse()bzw.writeValueWithoutResponse()passend zum Flag verwenden.- Für
startNotifications()mussnotifyoderindicategesetzt sein. propertiesselbst ist schreibgeschützt; das Zuweisen eines Werts hat keine Wirkung.