Signatur
Beschreibung
Mit readValue() fragst du den aktuellen Wert einer Characteristic direkt beim verbundenen Bluetooth-Low-Energy-Gerät ab, zum Beispiel den Akkustand, die Herzfrequenz oder einen Sensormesswert. Die Methode schickt eine GATT-Leseanfrage an das Gerät und gibt ein Promise zurück. Dieses wird mit einem DataView erfüllt, der die gelesenen Rohbytes enthält. Gleichzeitig wird die Eigenschaft characteristic.value aktualisiert und das Event characteristicvaluechanged ausgelöst.
Lesen funktioniert nur, wenn die Characteristic das auch erlaubt. Prüfe deshalb vorher characteristic.properties.read. Bei Werten, die sich laufend ändern (etwa Messdaten), ist meistens startNotifications() besser geeignet als wiederholtes Abfragen mit readValue(). Das spart Energie und Funkverkehr.
Der DataView enthält nur Bytes. Wie sie zu deuten sind, legt die jeweilige GATT-Spezifikation oder das Protokoll des Herstellers fest. Typisch sind getUint8(), getInt16(offset, true) (Little-Endian, bei Bluetooth üblich) oder ein TextDecoder für Zeichenketten.
Rückgabewert
DataView erfüllt wird, der eine Kopie des gelesenen Werts enthält. Es wird abgelehnt, z. B. mit NotSupportedError (Characteristic nicht lesbar), NetworkError (Gerät nicht verbunden), SecurityError (gesperrte UUID oder Kopplung nötig), InvalidStateError (Characteristic nicht mehr gültig) oder InvalidModificationError.Beispiele
Akkustand eines Geräts lesen
// Muss durch eine Nutzeraktion ausgelöst werden (z. B. 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 value = await characteristic.readValue();
console.log(`Akkustand: ${value.getUint8(0)} %`);
} catch (error) {
console.error('Lesen fehlgeschlagen:', error.name, error.message);
}
});
Gerätenamen als Text auslesen (TextDecoder)
const readDeviceName = async (server) => {
const service = await server.getPrimaryService('device_information');
const characteristic = await service.getCharacteristic('manufacturer_name_string');
// Vorher prüfen, ob Lesen überhaupt erlaubt ist
if (!characteristic.properties.read) {
throw new Error('Characteristic ist nicht lesbar');
}
const dataView = await characteristic.readValue();
return new TextDecoder('utf-8').decode(dataView);
};
// Nutzung: const name = await readDeviceName(server);
// console.log(name);
Temperatur als Int16 Little-Endian dekodieren
const readTemperature = async (characteristic) => {
const view = await characteristic.readValue();
// Viele Sensoren liefern Hundertstel-Grad als vorzeichenbehafteten 16-Bit-Wert
const raw = view.getInt16(0, true); // true = Little-Endian
return raw / 100;
};
// Einfaches Polling alle 5 Sekunden
const startPolling = (characteristic) => setInterval(async () => {
const celsius = await readTemperature(characteristic);
console.log(`Temperatur: ${celsius.toFixed(2)} °C`);
}, 5000);
// Wichtig · Fallstricke
- Browser-Unterstützung: Die Web Bluetooth API gibt es nur in Chromium-Browsern (Chrome, Edge, Opera) auf Desktop und Android. Firefox und Safari (auch unter iOS) unterstützen sie nicht. Prüfe deshalb mit
'bluetooth' in navigator, ob sie vorhanden ist. - Sicherer Kontext: Die API funktioniert nur über HTTPS oder
localhost.requestDevice()muss durch eine Nutzeraktion ausgelöst werden. - Nur eine GATT-Operation gleichzeitig: Mehrere parallele Aufrufe von
readValue()/writeValue*()können mitNetworkError(„GATT operation already in progress“) scheitern. Warte die Aufrufe deshalb nacheinander mitawaitab oder reihe sie in eine Warteschlange ein. - Verbindungsabbrüche: Ist das Gerät getrennt, schlägt das Lesen fehl. Höre auf
gattserverdisconnectedund verbinde dich bei Bedarf neu. - Byte-Reihenfolge: Mehrbyte-Werte werden bei Bluetooth meist in Little-Endian übertragen. Vergisst du das zweite Argument (
true) beigetInt16/getUint32, bekommst du falsche Zahlen. - Gesperrte UUIDs: Manche Characteristics stehen auf der Sperrliste des Browsers. Beim Lesen erhältst du dann einen
SecurityError. - Für Werte, die sich häufig ändern, sind
startNotifications()und das Eventcharacteristicvaluechangedeffizienter als Polling.