Start · Sprachen · JavaScript · Referenz · HIDDevice.receiveFeatureReport()

HIDDevice.receiveFeatureReport()

Methode

Liest einen Feature-Bericht mit der angegebenen Report-ID von einem geöffneten HID-Gerät und liefert die Daten als <code>DataView</code>.

seit JavaScript WebHID API – Chromium 89+ (Chrome, Edge, Opera); n Kategorie: webapi

Signatur

HIDDevice.prototype.receiveFeatureReport(reportId)

Beschreibung

Mit receiveFeatureReport() fragt eine Webanwendung über die WebHID API aktiv einen Feature Report von einem HID-Gerät ab (z. B. Tastatur, Gamepad, Messgerät, LED-Controller). Anders als Eingabeberichte, die das Gerät von selbst sendet und die über das Ereignis inputreport ankommen, werden Feature-Berichte auf Anfrage gelesen. Typischerweise stehen darin Konfigurationswerte, Firmware-Version, Akkustand oder Kalibrierungsdaten.

Die Methode gibt ein Promise zurück, das mit einem DataView erfüllt wird. Hat das Gerät nummerierte Berichte (Report-IDs ungleich 0), ist das erste Byte die Report-ID, danach folgen die Nutzdaten. Welche Report-IDs und Feldlayouts existieren, beschreibt der HID-Report-Deskriptor; über device.collections und dort featureReports lässt er sich auslesen.

Voraussetzung: Das Gerät wurde vorher per navigator.hid.requestDevice() vom Nutzer freigegeben (bzw. über navigator.hid.getDevices() wieder abgerufen) und mit device.open() geöffnet. Gegenstück zum Schreiben ist sendFeatureReport().

Parameter

Name Typ Default Beschreibung
$reportId Pflicht number 8-Bit-Report-ID (0–255) des gewünschten Feature-Berichts. Nutzt das Gerät keine Report-IDs, wird 0 übergeben.

Rückgabewert

Typ
Promise<DataView>
Beschreibung
Ein Promise, das mit einem DataView über die empfangenen Bytes erfüllt wird. Es wird abgelehnt (z. B. NotAllowedError oder InvalidStateError), wenn das Gerät nicht geöffnet ist, der Bericht nicht existiert oder das Lesen fehlschlägt.

Beispiele

Gerät auswählen, öffnen und Feature-Bericht lesen

// Muss durch eine Nutzergeste (z. B. Klick) ausgelöst werden
document.querySelector('#verbinden').addEventListener('click', async () => {
  const [device] = await navigator.hid.requestDevice({
    filters: [{ vendorId: 0x046d }] // Beispiel: Logitech
  });
  if (!device) return;

  if (!device.opened) await device.open();

  const view = await device.receiveFeatureReport(1);
  const bytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
  console.log('Report-ID:', bytes[0]);
  console.log('Daten:', [...bytes.slice(1)].map(b => b.toString(16).padStart(2, '0')).join(' '));
});
Report-ID: 1 Daten: 02 5a 00 ff ...

Firmware-Version und Akkustand auswerten

const leseStatus = async (device) => {
  try {
    const view = await device.receiveFeatureReport(0x05);
    // Layout laut Hersteller: [ID, Major, Minor, Akku %]
    const major = view.getUint8(1);
    const minor = view.getUint8(2);
    const akku = view.getUint8(3);
    return { firmware: `${major}.${minor}`, akku };
  } catch (err) {
    console.error('Feature-Bericht nicht lesbar:', err.name, err.message);
    return null;
  }
};

const [device] = await navigator.hid.getDevices();
if (device) {
  await device.open();
  console.log(await leseStatus(device));
}
{ firmware: '1.4', akku: 87 }

Verfügbare Feature-Report-IDs aus dem Deskriptor ermitteln

const featureIds = (device) =>
  device.collections.flatMap(c => c.featureReports.map(r => r.reportId));

const [device] = await navigator.hid.getDevices();
await device.open();

for (const id of featureIds(device)) {
  const view = await device.receiveFeatureReport(id);
  console.log(`Report ${id}: ${view.byteLength} Bytes`);
}
Report 1: 9 Bytes Report 5: 4 Bytes

// Wichtig · Fallstricke

  • Browser-Unterstützung: Nur Chromium-basierte Desktop-Browser (Chrome/Edge/Opera ab Version 89). Firefox und Safari unterstützen WebHID nicht; vorher mit 'hid' in navigator prüfen.
  • Sicherer Kontext: Nur über HTTPS (oder localhost) verfügbar; in iframes ist die Permissions-Policy hid nötig. Die Geräteauswahl erfordert eine Nutzergeste.
  • Gerät muss geöffnet sein: Ohne vorheriges await device.open() wird das Promise mit InvalidStateError abgelehnt.
  • Report-ID im Ergebnis: Das erste Byte des DataView enthält bei nummerierten Berichten die Report-ID – Offsets beim Parsen entsprechend um 1 verschieben. Das Verhalten kann sich je nach Betriebssystem leicht unterscheiden; immer byteLength prüfen.
  • Blockierte Geräte: Sicherheitskritische Geräteklassen (z. B. FIDO-Sicherheitsschlüssel) und manche Tastatur-/Maus-Collections sind vom Browser gesperrt und nicht lesbar.
  • Nebenläufige Aufrufe auf dasselbe Gerät möglichst serialisieren (nacheinander awaiten), da manche Geräte parallele Anfragen schlecht vertragen.