Signatur
Beschreibung
Das Interface BluetoothCharacteristicProperties gehört zur Web Bluetooth API. Es beschreibt die Eigenschaften (Properties) einer GATT-Charakteristik eines Bluetooth-Low-Energy-Geräts. Man erzeugt es nie selbst: Der Browser stellt eine Instanz über die schreibgeschützte Eigenschaft BluetoothRemoteGATTCharacteristic.properties bereit.
Jede Eigenschaft ist ein schreibgeschützter boolean, der einem Bit im Properties-Feld der Charakteristik-Deklaration aus der Bluetooth-Spezifikation entspricht:
broadcast– Der Wert darf in Advertising-Paketen gesendet werden.read– Der Wert kann mitreadValue()gelesen werden.writeWithoutResponse– Schreiben ohne Bestätigung überwriteValueWithoutResponse()ist möglich.write– Schreiben mit Bestätigung überwriteValueWithResponse()ist möglich.notify– Das Gerät kann Wertänderungen ohne Bestätigung melden (startNotifications()).indicate– Das Gerät kann Wertänderungen mit Bestätigung melden (auch überstartNotifications()).authenticatedSignedWrites– Signierte, authentifizierte Schreibvorgänge werden unterstützt.reliableWrite– „Reliable Write“ (in eine Warteschlange schreiben, dann ausführen) wird unterstützt (Extended Properties).writableAuxiliaries– Der Deskriptor Characteristic User Description kann beschrieben werden (Extended Properties).
In der Praxis prüft man diese Eigenschaften, bevor man eine Operation aufruft. So vermeidet man NotSupportedError-Ausnahmen und kann die Oberfläche anpassen, etwa einen „Schreiben“-Button ausblenden, wenn die Charakteristik nur lesbar ist. Das ist vor allem bei generischen Werkzeugen wichtig, zum Beispiel bei BLE-Explorern oder Debug-Oberflächen, die unbekannte Geräte untersuchen.
Rückgabewert
characteristic.properties. Alle neun Eigenschaften sind schreibgeschützte boolean-Werte.Beispiele
Eigenschaften einer Charakteristik auslesen
// Muss durch eine Nutzeraktion ausgelöst werden (z. B. Klick)
const button = document.querySelector('#verbinden');
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 props = characteristic.properties;
console.log('Lesbar:', props.read);
console.log('Schreibbar:', props.write);
console.log('Benachrichtigungen:', props.notify);
});
Alle gesetzten Eigenschaften als Liste ausgeben
const PROPERTY_NAMES = [
'broadcast', 'read', 'writeWithoutResponse', 'write',
'notify', 'indicate', 'authenticatedSignedWrites',
'reliableWrite', 'writableAuxiliaries'
];
const describeProperties = (characteristic) =>
PROPERTY_NAMES.filter((name) => characteristic.properties[name]);
// Alle Charakteristiken eines Dienstes untersuchen
const inspectService = async (service) => {
const characteristics = await service.getCharacteristics();
for (const c of characteristics) {
console.log(c.uuid, describeProperties(c).join(', '));
}
};
Operation abhängig von den Eigenschaften wählen
const subscribeOrPoll = async (characteristic, onValue) => {
const { notify, indicate, read } = characteristic.properties;
if (notify || indicate) {
characteristic.addEventListener('characteristicvaluechanged', (event) => {
onValue(event.target.value.getUint8(0));
});
await characteristic.startNotifications();
return () => characteristic.stopNotifications();
}
if (read) {
// Kein Push möglich: regelmäßig abfragen
const id = setInterval(async () => {
const value = await characteristic.readValue();
onValue(value.getUint8(0));
}, 5000);
return () => clearInterval(id);
}
throw new Error('Charakteristik ist weder lesbar noch meldet sie Änderungen');
};
// Nutzung
const stop = await subscribeOrPoll(characteristic, (level) => {
console.log(`Akkustand: ${level} %`);
});
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 {
console.warn('Charakteristik ist nicht beschreibbar');
}
};
await writeCommand(characteristic, [0x01, 0xff]);
// Wichtig · Fallstricke
- Browser-Unterstützung: Web Bluetooth gibt es nur in Chromium-Browsern (Chrome, Edge, Opera; unter Linux teilweise nur mit Flag). Firefox und Safari unterstützen die API nicht. Deshalb vorher mit
'bluetooth' in navigatorprüfen. - Sicherer Kontext und Nutzeraktion: Die API funktioniert nur über HTTPS (oder
localhost).requestDevice()muss durch eine Nutzeraktion wie einen Klick ausgelöst werden. In Cross-Origin-iframes ist die Permissions-Policybluetoothnötig. - Nur Angaben des Geräts: Die Werte zeigen, was das Gerät in seiner GATT-Datenbank angibt. Eine Operation kann trotzdem fehlschlagen, zum Beispiel wegen fehlender Kopplung oder Verschlüsselung, einer Blockliste des Browsers oder eines Verbindungsabbruchs. Deshalb Aufrufe immer in
try/catcheinschließen. - Extended Properties:
reliableWriteundwritableAuxiliariesstammen aus dem Deskriptor Characteristic Extended Properties. Hat das Gerät diesen Deskriptor nicht, sind beidefalse. - Die Eigenschaften sind schreibgeschützt. Eine Zuweisung wie
props.write = truehat keine Wirkung und ändert nichts am Verhalten. notifyundindicatenutzen beidestartNotifications(). Der Browser wählt das passende Verfahren selbst.