Signatur
Beschreibung
Die Methode getSignals() des SerialPort-Interfaces fragt den aktuellen Zustand der Eingangs-Steuersignale ab, die das angeschlossene Gerät setzt. Das zurückgegebene Promise wird mit einem Objekt aufgelöst, das vier boolesche Eigenschaften enthält:
clearToSend– CTS (Clear To Send): Das Gerät ist bereit, Daten zu empfangen.dataCarrierDetect– DCD (Data Carrier Detect): Ein Trägersignal wurde erkannt, z. B. bei Modems.dataSetReady– DSR (Data Set Ready): Das Gerät ist eingeschaltet und betriebsbereit.ringIndicator– RI (Ring Indicator): Ein eingehender Anruf bzw. ein Klingelsignal liegt an.
Nützlich ist das vor allem bei Hardware, die über Steuerleitungen statt über den Datenstrom kommuniziert: Modems, industrielle Steuerungen, Barcode-Scanner, Mikrocontroller-Boards oder eigene Hardware-Flusskontrolle. Das Gegenstück für die Ausgangssignale (DTR, RTS, Break) ist SerialPort.setSignals().
Der Port muss zuvor mit port.open() geöffnet worden sein. Da es kein Ereignis für Signaländerungen gibt, muss man bei Bedarf selbst in einem Intervall abfragen (Polling).
Rückgabewert
InvalidStateError-DOMException zurückgewiesen, wenn der Port nicht geöffnet ist, bzw. mit einer NetworkError-DOMException, wenn die Signale nicht gelesen werden konnten (z. B. Gerät getrennt).Beispiele
Signale nach dem Öffnen eines Ports auslesen
// Muss durch eine Nutzeraktion (z. B. Klick) ausgelöst werden
document.querySelector('#verbinden').addEventListener('click', async () => {
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 9600 });
const signale = await port.getSignals();
console.log(signale);
});
Warten, bis das Gerät sendebereit ist (CTS)
const warteAufCTS = async (port, timeoutMs = 5000) => {
const start = Date.now();
while (Date.now() - start < timeoutMs) {
const { clearToSend } = await port.getSignals();
if (clearToSend) return true;
await new Promise((r) => setTimeout(r, 50));
}
throw new Error('Gerät hat CTS nicht innerhalb des Timeouts gesetzt');
};
// Verwendung mit einem bereits geöffneten Port
if (await warteAufCTS(port)) {
const writer = port.writable.getWriter();
await writer.write(new TextEncoder().encode('PING\n'));
writer.releaseLock();
}
Signaländerungen per Polling überwachen (z. B. Modem-Klingeln)
const ueberwacheSignale = (port, onChange, intervallMs = 200) => {
let letzte = null;
const id = setInterval(async () => {
try {
const aktuell = await port.getSignals();
const json = JSON.stringify(aktuell);
if (json !== letzte) {
letzte = json;
onChange(aktuell);
}
} catch (err) {
console.error('Signale nicht lesbar:', err.name);
clearInterval(id);
}
}, intervallMs);
return () => clearInterval(id); // Stopp-Funktion
};
const stopp = ueberwacheSignale(port, ({ ringIndicator, dataCarrierDetect }) => {
if (ringIndicator) console.log('Eingehender Anruf!');
console.log('Träger erkannt:', dataCarrierDetect);
});
// Wichtig · Fallstricke
- Browser-Kompatibilität: Die Web Serial API gibt es nur in Chromium-Browsern auf dem Desktop (Chrome, Edge, Opera). Firefox und Safari unterstützen sie nicht. Vorher mit
'serial' in navigatorprüfen. - Sicherer Kontext: Die API steht nur über HTTPS (oder
localhost) zur Verfügung. Den Portzugriff muss der Nutzer übernavigator.serial.requestPort()ausdrücklich freigeben. Außerdem kann eine Permissions-Policy (serial) den Zugriff in iframes sperren. - Port muss geöffnet sein: Rufst du die Methode vor
open()oder nachclose()auf, wird das Promise mitInvalidStateErrorzurückgewiesen. - Kein Änderungsereignis: Signaländerungen lösen kein Ereignis aus, du musst selbst regelmäßig abfragen. Zu kurze Intervalle belasten die CPU und den USB-Treiber, 50–250 ms sind meist ausreichend.
- Hardware-Abhängigkeit: Viele USB-Seriell-Adapter (z. B. einfache CH340- oder FTDI-Kabel mit nur TX/RX) führen nicht alle Leitungen nach außen. Nicht angeschlossene Signale liefern dann konstant
falseoder undefinierte Pegel. - Bei
flowControl: 'hardware'wertet der Treiber CTS/RTS bereits selbst aus. Manuelles Polling ist dann meist unnötig.