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

HIDDevice.sendFeatureReport()

Methode

Sendet einen Feature-Report mit der angegebenen Report-ID und den Nutzdaten an ein geöffnetes HID-Gerät und gibt ein <code>Promise</code> zurück.

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

Signatur

HIDDevice.prototype.sendFeatureReport(reportId, data)

Beschreibung

Mit sendFeatureReport() schickt man über die WebHID API einen Feature-Report an ein HID-Gerät (Human Interface Device). Feature-Reports dienen meist zur Konfiguration eines Geräts, etwa um die Hintergrundbeleuchtung einer Tastatur einzustellen, die DPI-Stufe einer Maus zu ändern, einen Gerätemodus umzuschalten oder Firmware-Parameter zu setzen. Im Unterschied zu Output-Reports (sendReport()), die laufend Daten übertragen, sind Feature-Reports für seltene Einstellungen gedacht und lassen sich auch mit receiveFeatureReport() zurücklesen.

Vor dem Aufruf muss das Gerät über navigator.hid.requestDevice() ausgewählt und mit device.open() geöffnet sein. Das zurückgegebene Promise wird erfüllt, sobald der Report gesendet wurde. Schlägt das Senden fehl, etwa weil das Gerät nicht geöffnet ist oder den Report ablehnt, wird es mit einer DOMException zurückgewiesen (meist InvalidStateError oder NotAllowedError).

Welche Report-IDs und welche Datenlänge ein Gerät erwartet, steht in seinem Report-Deskriptor. Ausgelesen wird er über device.collections und dort über die Eigenschaft featureReports. Verwendet das Gerät keine Report-IDs, übergibt man 0 als reportId. Die Report-ID wird nicht in data eingetragen, der Browser stellt sie selbst voran.

Parameter

Name Typ Default Beschreibung
$reportId Pflicht number 8-Bit-Report-ID (0–255) des Feature-Reports. 0, wenn das Gerät keine Report-IDs verwendet.
$data Pflicht BufferSource (ArrayBuffer | TypedArray | DataView) Nutzdaten des Reports ohne vorangestellte Report-ID. Die Länge sollte der im Report-Deskriptor festgelegten Größe entsprechen.

Rückgabewert

Typ
Promise<undefined>
Beschreibung
Wird ohne Wert erfüllt, sobald der Report gesendet ist. Bei einem Fehler wird es mit einer DOMException zurückgewiesen.

Beispiele

Gerät auswählen, öffnen und Feature-Report senden

const connectBtn = document.querySelector('#connect');

connectBtn.addEventListener('click', async () => {
  // Muss durch eine Nutzeraktion ausgelöst werden
  const [device] = await navigator.hid.requestDevice({
    filters: [{ vendorId: 0x046d }] // Beispiel: Logitech
  });
  if (!device) return;

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

  // Report-ID 0x11, 3 Byte Nutzdaten
  const data = new Uint8Array([0x01, 0x80, 0xff]);
  try {
    await device.sendFeatureReport(0x11, data);
    console.log('Feature-Report gesendet');
  } catch (err) {
    console.error('Senden fehlgeschlagen:', err.name, err.message);
  }
});
Feature-Report gesendet

Tastaturbeleuchtung setzen und Ergebnis zurücklesen

const setBacklight = async (device, level) => {
  const REPORT_ID = 0x05;
  const payload = new Uint8Array(8); // Länge laut Report-Deskriptor
  payload[0] = 0x02;                 // Befehl: Helligkeit
  payload[1] = Math.min(255, Math.max(0, level));

  await device.sendFeatureReport(REPORT_ID, payload);

  // Kontrolle: denselben Feature-Report wieder abrufen
  const view = await device.receiveFeatureReport(REPORT_ID);
  // Byte 0 enthält beim Empfang die Report-ID
  console.log('Aktuelle Helligkeit:', view.getUint8(2));
};

const [kbd] = await navigator.hid.getDevices();
if (kbd) {
  await kbd.open();
  await setBacklight(kbd, 128);
}
Aktuelle Helligkeit: 128

Erwartete Report-Größe aus dem Deskriptor ermitteln

const getFeatureReportSize = (device, reportId) => {
  for (const collection of device.collections) {
    const report = collection.featureReports.find(r => r.reportId === reportId);
    if (report) {
      // Summe aller Felder in Bit → Byte
      const bits = report.items.reduce(
        (sum, item) => sum + item.reportSize * item.reportCount, 0);
      return Math.ceil(bits / 8);
    }
  }
  return null;
};

const [device] = await navigator.hid.getDevices();
const size = getFeatureReportSize(device, 0x11);
if (size !== null) {
  await device.open();
  await device.sendFeatureReport(0x11, new Uint8Array(size));
  console.log(`Report mit ${size} Byte gesendet`);
}
Report mit 8 Byte gesendet

// Wichtig · Fallstricke

  • Browser-Unterstützung: Nur Chromium-basierte Desktop-Browser (Chrome/Edge/Opera ab Version 89). Firefox und Safari unterstützen WebHID nicht. Vorher prüfen, ob 'hid' in navigator gilt.
  • Sicherer Kontext: Funktioniert nur über HTTPS (oder localhost). Außerdem muss die Permissions-Policy hid erlauben, was bei iframes relevant ist.
  • Gerät geöffnet? Ohne vorheriges await device.open() wird das Promise mit InvalidStateError zurückgewiesen.
  • Report-ID nicht doppelt senden: Die ID gehört in den ersten Parameter, nicht in data. Andernfalls verschieben sich alle Bytes um eine Stelle. Beim Empfang über receiveFeatureReport() steht die ID dagegen in Byte 0 der Antwort.
  • Gesperrte Geräte: Chrome blockiert bestimmte Geräteklassen (z. B. Tastatur-Eingaben, FIDO-Sicherheitsschlüssel) und Top-Level-Collections, damit Tastenanschläge oder Anmeldedaten nicht abgegriffen werden können. Reports an solche Collections schlagen fehl.
  • Vorsicht: Falsche Feature-Reports können Geräte fehlkonfigurieren. Deshalb nur Befehle senden, die in der Herstellerdokumentation beschrieben sind.
  • Unter Windows müssen die Daten oft exakt die Länge aus dem Deskriptor haben, sonst schlägt der Aufruf fehl.