Zum Inhalt springen

Erweiterte Kommunikation

Diese Seite behandelt erweiterte USB-Kommunikationsmethoden, serielle Schnittstellen und Netzwerk-Sockets. Für grundlegende Lese- und Schreibvorgänge siehe Schreiben und Lesen.

Das Verständnis des Unterschieds zwischen USB-Übertragungstypen hilft dir, die richtige Methode zu wählen und unerwartete Fehler zu debuggen.

TypMethodeTypische GrößeAnwendungsfall
Interruptdevice.write() / device.read()3–64 ByteRGB-Daten, kleine Befehle, Tastatur-/Mauseingabe
Bulkdevice.write() / device.read()64–1025 ByteLCD-Bilder, Firmware-Updates, große Konfigurationsblöcke
Controldevice.send_report() / device.get_report() / device.control_transfer()32–192 ByteAuthentifizierung, HID-Feature-Reports, Gerätekonfiguration

Die gleichen Funktionen device.write() und device.read() werden für Interrupt- und Bulk-Transfers verwendet — der USB-Treiber ermittelt den Typ anhand des Endpunkts und der Paketgröße.


Sendet einen HID-GET_INPUT_REPORT-Control-Transfer. Ähnlich wie device.get_report(), aber fordert explizit einen Input-Report statt eines Feature-Reports an. Verwende dies, wenn get_report() falsche Daten zurückgibt, weil das Gerät seine Input- und Feature-Report-Typen trennt.

ParameterTypBeschreibungBeispiel
DataArray1D-ArrayReport-Anforderungsdaten[0x01]
LengthIntErwartete Report-Größe in Bytes64
RückgabeTypBeschreibung
DataArray1D-ArrayVom Gerät empfangene Bytes
var inputData = device.input_report([0x01], 64);

Führt einen direkten Bulk- oder Interrupt-Transfer zu einem bestimmten USB-Endpunkt durch. Im Gegensatz zu device.write() und device.read(), die den von device.set_endpoint() gewählten Endpunkt verwenden, kannst du damit jeden Endpunkt über seine Adresse ansprechen.

  • Endpunktadressen, die mit 0x80 oder höher enden, sind IN (Gerät → Host, Lesen).
  • Endpunktadressen unter 0x80 sind OUT (Host → Gerät, Schreiben).
ParameterTypBeschreibungBeispiel
EndpointHexUSB-Endpunktadresse0x81
DataArray1D-ArrayZu sendende Daten (OUT) oder leeres Array (IN)[0x01, 0x02]
LengthIntTransfergröße in Bytes64
TimeoutIntMillisekunden bis zum Abbruch100
RückgabeTypBeschreibung
DataArray1D-ArrayEmpfangene Bytes (IN-Transfers), oder leer
// An Endpunkt 0x01 schreiben
device.bulk_transfer(0x01, [0x00, 0x01, 0x02], 3, 100);
// Von Endpunkt 0x81 lesen
var response = device.bulk_transfer(0x81, [], 64, 100);
// Großer Bulk-Write (z. B. LCD-Bilddaten)
device.bulk_transfer(0x02, imageData, 1024, 500);

Low-Level-USB-Control-Transfer. Wird für Authentifizierungs-Handshakes, herstellerspezifische Protokolle und Fälle verwendet, in denen HID-Methoden nicht ausreichen. Dies ist ein Control-Transfer, kein Bulk-Transfer.

ParameterTypBeschreibungBeispiel
RequestTypeHexUSB-Request-Type-Bitmap (Richtung, Typ, Empfänger)0xA1
RequestHexRequest-Code (gerätespezifisch)0x01
ValueHexValue-Feld0x0100
IndexIntInterface- oder Endpunkt-Index0x00
DataArray1D-ArrayZu sendende Daten (Host→Gerät), oder leer[]
LengthIntErwartete Antwortlänge (Gerät→Host)192
TimeoutIntMillisekunden bis zum Abbruch1000
RückgabeTypBeschreibung
DataArray1D-ArrayEmpfangene Bytes (Gerät→Host-Transfers)

Häufige RequestType-Werte:

WertRichtungTypEmpfängerAnwendungsfall
0x21Host → GerätClassInterfaceHID SET_REPORT
0xA1Gerät → HostClassInterfaceHID GET_REPORT
0x80Gerät → HostStandardGerätDeskriptor-Lesevorgänge
0x00Host → GerätStandardGerätStandardbefehle
// Authentifizierungs-Token lesen (Gerät → Host, Class, Interface)
var token = device.control_transfer(
0xA1, // Gerät→Host, Class, Interface
0x01, // GET_REPORT
0x0100, // Report-Typ (Feature) + Report-ID
0x00, // Interface 0
[], // Keine ausgehenden Daten
192, // 192 Bytes zurückerwarten
1000 // 1 Sekunde Timeout
);
// Feature-Report senden (Host → Gerät)
device.control_transfer(0x21, 0x09, 0x0300, 0, [0x03, 0x08, 0x32], 0, 500);

Für serielle/COM-Port-Geräte importiere das Serial-Modul und setze Type() deines Plugins auf "serial".

import { serial } from "@SignalRGB/serial";
export function Type() { return "serial"; }
serial.connect({
baudRate: 115200, // Standard: 115200
parity: "None", // "None", "Even", "Odd", "Space", "Mark"
dataBits: 8, // 5, 6, 7 oder 8
stopBits: "One" // "One", "OneAndHalf", "Two"
});
MethodeBeschreibungRückgabe
serial.connect(options?)Seriellen Port öffnenbool
serial.disconnect()Seriellen Port schließenvoid
serial.isConnected()Verbindungsstatus prüfenbool
serial.write(data)Daten sendenGesendete Bytes
serial.read(maxBytes?, timeoutMs?)Verfügbare Bytes lesen (Standard: alle, 1000 ms Timeout)Byte-Array
serial.readAll()Alle verfügbaren Bytes sofort lesenByte-Array
serial.availablePorts()Verfügbare COM-Ports auflistenArray
serial.getPortName()Aktueller Port-Namestring
serial.getBaudRate()Aktuelle Baudratenumber
serial.getDeviceInfo()Port-Info mit VID, PID usw.object
import { serial } from "@SignalRGB/serial";
export function Type() { return "serial"; }
export function Initialize() {
if (!serial.connect()) {
device.log("Verbindung zum seriellen Port fehlgeschlagen");
return;
}
device.log(`Verbunden auf ${serial.getPortName()} mit ${serial.getBaudRate()} Baud`);
}
export function Render() {
serial.write([0xFF, ...RGBData]);
}
export function Shutdown() {
serial.disconnect();
}

Für netzwerkfähige Geräte importiere das TCP- oder UDP-Modul und setze Type() auf "network". Beide Module verwenden ein ereignisbasiertes Callback-Modell.

import { tcp } from "@SignalRGB/tcp";
import { udp } from "@SignalRGB/udp";
export function Type() { return "network"; }
import { tcp } from "@SignalRGB/tcp";
let socket;
export function Initialize() {
socket = tcp.createSocket();
socket.on("connected", () => {
device.log("Verbunden");
socket.send([0x01, 0x02, 0x03]);
});
socket.on("message", (data) => {
device.log(`Empfangen: ${data}`);
});
socket.on("error", (err) => {
device.log(`Fehler: ${err}`);
});
socket.connect("192.168.1.100", 8080);
}
export function Render() {
if (socket.state === socket.ConnectedState) {
socket.send(RGBData);
}
}
export function Shutdown() {
socket.close();
}

TCP-Methoden:

MethodeBeschreibung
tcp.createSocket()Neuen TCP-Socket erstellen
socket.connect(address, port)Verbindung zu einem Host herstellen
socket.send(data)String oder Byte-Array senden
socket.bind(port)An lokalen Port binden
socket.close()Socket schließen
socket.on(event, callback)Event-Handler registrieren

TCP-Events: "connected", "disconnected", "message", "error"


import { udp } from "@SignalRGB/udp";
let socket;
export function Initialize() {
socket = udp.createSocket();
socket.on("message", (data) => {
device.log(`Empfangen: ${data}`);
});
socket.connect("192.168.1.100", 21324);
}
export function Render() {
socket.send(RGBData);
}
export function Shutdown() {
socket.close();
}

UDP-Methoden:

MethodeBeschreibung
udp.createSocket()Neuen UDP-Socket erstellen
socket.connect(address, port)Standard-Sendeziel festlegen
socket.send(data)An verbundene Adresse senden
socket.write(data, address, port)An bestimmte Adresse senden ohne vorherigen connect()-Aufruf
socket.bind(port)An lokalen Port zum Empfangen binden
socket.close()Socket schließen
socket.on(event, callback)Event-Handler registrieren

UDP-Events: "connected", "disconnected", "message", "error"


Für Geräte, die verschlüsselte Kommunikation erfordern (z. B. Philips Hue), verwende das dtls-Feature. Es bietet DTLS-verschlüsseltes UDP mit einem Pre-Shared Key (PSK).

export function Initialize() {
device.addFeature("dtls");
dtls.onConnectionEstablished(() => { device.log("DTLS verbunden"); });
dtls.onConnectionClosed(() => { device.log("DTLS geschlossen"); });
dtls.onConnectionError(() => { device.log("DTLS Fehler"); });
dtls.createConnection("192.168.1.50", 2100, authIdentity, authKey);
}
export function Render() {
if (dtls.hasEncryptedConnection()) {
dtls.send(RGBData);
}
}
export function Shutdown() {
dtls.CloseConnection();
}

DTLS-Methoden:

MethodeBeschreibung
dtls.createConnection(host, port, identity, key)Verschlüsselte Verbindung mit PSK öffnen
dtls.send(data, endianness?)Verschlüsselte Daten senden (0 = Little-Endian, 1 = Big-Endian)
dtls.hasEncryptedConnection()Gibt true zurück, wenn die Verbindung besteht
dtls.CloseConnection()Verbindung schließen
dtls.onConnectionEstablished(cb)Callback wenn Verbindung erfolgreich
dtls.onConnectionClosed(cb)Callback wenn Verbindung geschlossen
dtls.onConnectionError(cb)Callback bei Fehler