Start · Sprachen · JavaScript · Referenz · USBDevice

USBDevice

Schnittstelle

Stellt ein gekoppeltes USB-Gerät dar. Die Schnittstelle liefert Metadaten wie Hersteller- und Produkt-ID und bietet Methoden zum Öffnen, Konfigurieren und für Datenübertragungen.

seit JavaScript Chrome/Edge 61+, Opera 48+ (nicht in Firefox und S Kategorie: webapi

Signatur

interface USBDevice

Beschreibung

USBDevice ist das zentrale Objekt der WebUSB API. Eine Instanz steht für ein physisches USB-Gerät, für das der Nutzer der Seite den Zugriff erlaubt hat. Man erzeugt sie nicht selbst, sondern bekommt sie von navigator.usb.requestDevice() (Auswahldialog), navigator.usb.getDevices() (bereits freigegebene Geräte) oder über die Ereignisse connect/disconnect von navigator.usb.

Die schreibgeschützten Eigenschaften beschreiben das Gerät: vendorId, productId, deviceClass, deviceSubclass, deviceProtocol, manufacturerName, productName, serialNumber, die Versionsangaben usbVersionMajor/Minor/Subminor und deviceVersionMajor/Minor/Subminor sowie configuration, configurations und opened.

Die Methoden geben alle ein Promise zurück. Der übliche Ablauf ist open(), dann selectConfiguration(), dann claimInterface(). Danach überträgt man Daten mit transferIn()/transferOut() (Bulk/Interrupt), controlTransferIn()/controlTransferOut() (Steuerübertragungen) oder isochronousTransferIn()/isochronousTransferOut(). Weitere Methoden sind selectAlternateInterface(), clearHalt(), reset(), releaseInterface(), close() und forget().

Gedacht ist WebUSB für eigene oder herstellerspezifische Hardware wie Mikrocontroller, Messgeräte oder Programmieradapter, für die es keine passende höherwertige API gibt. Für Tastaturen, Gamepads, serielle Adapter oder Speichermedien sind WebHID, die Gamepad API, Web Serial oder das Betriebssystem zuständig.

Rückgabewert

Typ
USBDevice
Beschreibung
Instanzen bekommt man über navigator.usb.requestDevice(), navigator.usb.getDevices() oder über USBConnectionEvent.device. Einen öffentlichen Konstruktor gibt es nicht.

Beispiele

Gerät anfordern und Metadaten auslesen

// Muss in einer Nutzeraktion (z. B. Klick) aufgerufen werden
const button = document.querySelector('#verbinden');

button.addEventListener('click', async () => {
  try {
    const device = await navigator.usb.requestDevice({
      filters: [{ vendorId: 0x2341 }] // z. B. Arduino
    });
    console.log(device.productName, device.manufacturerName);
    console.log('VID:', device.vendorId.toString(16), 'PID:', device.productId.toString(16));
    console.log('Seriennummer:', device.serialNumber);
  } catch (err) {
    console.warn('Kein Gerät ausgewählt:', err.message);
  }
});
Arduino Uno Arduino (www.arduino.cc) VID: 2341 PID: 43 Seriennummer: 85736323838351F0B191

Öffnen, Interface belegen und Daten senden/empfangen

const kommuniziere = async (device) => {
  await device.open();
  if (device.configuration === null) {
    await device.selectConfiguration(1);
  }
  await device.claimInterface(0);

  // Bulk-OUT an Endpunkt 1
  const befehl = new TextEncoder().encode('PING\n');
  const out = await device.transferOut(1, befehl);
  console.log('Gesendet:', out.bytesWritten, 'Bytes');

  // Bulk-IN von Endpunkt 2, max. 64 Bytes
  const result = await device.transferIn(2, 64);
  if (result.status === 'ok') {
    console.log('Antwort:', new TextDecoder().decode(result.data));
  }

  await device.releaseInterface(0);
  await device.close();
};

const [device] = await navigator.usb.getDevices();
if (device) await kommuniziere(device);
Gesendet: 5 Bytes Antwort: PONG

Herstellerspezifische Steuerübertragung

const setzeLed = async (device, an) => {
  await device.controlTransferOut({
    requestType: 'vendor',
    recipient: 'device',
    request: 0x01,        // herstellerspezifischer Befehl
    value: an ? 1 : 0,
    index: 0
  });
};

const leseStatus = async (device) => {
  const res = await device.controlTransferIn({
    requestType: 'vendor',
    recipient: 'device',
    request: 0x02,
    value: 0,
    index: 0
  }, 1);
  return res.data.getUint8(0);
};

const [device] = await navigator.usb.getDevices();
await device.open();
await setzeLed(device, true);
console.log('Status:', await leseStatus(device));
Status: 1

Verbindungswechsel überwachen und Freigabe widerrufen

navigator.usb.addEventListener('connect', ({ device }) => {
  console.log('Angeschlossen:', device.productName);
});

navigator.usb.addEventListener('disconnect', ({ device }) => {
  console.log('Getrennt:', device.productName, '– geöffnet?', device.opened);
});

// Freigabe dauerhaft widerrufen (Chrome 101+)
const [device] = await navigator.usb.getDevices();
await device?.forget();
Angeschlossen: Arduino Uno Getrennt: Arduino Uno – geöffnet? false

// Wichtig · Fallstricke

  • Kompatibilität: Nur in Chromium-Browsern (Chrome, Edge, Opera) auf Desktop und Android. Firefox und Safari unterstützen WebUSB nicht. Vor der Nutzung mit 'usb' in navigator prüfen.
  • Sicherer Kontext: Funktioniert nur über HTTPS oder localhost. requestDevice() braucht eine Nutzeraktion. In iframes muss die Permissions-Policy usb den Zugriff erlauben.
  • Geschützte Geräteklassen: Der Browser sperrt Interfaces der Klassen HID, Massenspeicher, Audio, Video, Smartcard und Drucker. Ein claimInterface() darauf schlägt mit SecurityError fehl.
  • Betriebssystem-Treiber: Hat das Betriebssystem das Interface schon belegt (unter Windows oft ein Hersteller-Treiber statt WinUSB, unter Linux etwa cdc_acm), meldet claimInterface() einen NetworkError. Unter Linux fehlen häufig udev-Regeln für die Zugriffsrechte.
  • Endpunkt-Nummern werden ohne Richtungsbit angegeben (1 statt 0x81). Die Richtung ergibt sich aus transferIn bzw. transferOut.
  • Den Status des Ergebnisses immer prüfen: Bei 'stall' den Endpunkt mit clearHalt() zurücksetzen, bei 'babble' hat das Gerät mehr Daten geschickt als angefordert.
  • Sicherheit: Direkter Hardwarezugriff kann Firmware verändern. Nur vertrauenswürdige Seiten sollten die Freigabe bekommen. Mit forget() lässt sich die Freigabe wieder entziehen.