Gå til indhold

Avanceret kommunikation

Denne side behandler avancerede USB-kommunikationsmetoder, serielle grænseflader og netværks-sockets. For grundlæggende læse- og skriveoperationer, se Skrivninger og læsninger.

Forståelse af forskellen mellem USB-overførselstyper hjælper dig med at vælge den rigtige metode og debugge uventede fejl.

TypeMetodeTypisk størrelseBrugstilfælde
Interruptdevice.write() / device.read()3–64 bytesRGB-data, små kommandoer, tastatur-/museinput
Bulkdevice.write() / device.read()64–1025 bytesLCD-billeder, firmware-opdateringer, store konfigurationsblokke
Controldevice.send_report() / device.get_report() / device.control_transfer()32–192 bytesAutentificering, HID-feature-reports, enhedskonfiguration

De samme funktioner device.write() og device.read() bruges til interrupt- og bulk-transfers — USB-driveren bestemmer typen baseret på endepunktet og pakkestørrelsen.


Sender en HID-GET_INPUT_REPORT-control-transfer. Ligner device.get_report(), men anmoder eksplicit om en input-rapport i stedet for en feature-rapport. Brug dette, når get_report() returnerer forkerte data, fordi enheden adskiller sine input- og feature-rapport-typer.

ParameterTypeBeskrivelseEksempel
DataArray1D-ArrayRapport-anmodningsdata[0x01]
LengthIntForventet rapport-størrelse i bytes64
ReturneringTypeBeskrivelse
DataArray1D-ArrayBytes modtaget fra enheden
var inputData = device.input_report([0x01], 64);

Udfører en direkte bulk- eller interrupt-transfer til et bestemt USB-endepunkt. I modsætning til device.write() og device.read(), der bruger det endepunkt valgt af device.set_endpoint(), kan du med dette adressere ethvert endepunkt via dets adresse.

  • Endepunktadresser der slutter på 0x80 eller højere er IN (enhed → host, læsning).
  • Endepunktadresser under 0x80 er OUT (host → enhed, skrivning).
ParameterTypeBeskrivelseEksempel
EndpointHexUSB-endepunktadresse0x81
DataArray1D-ArrayData der skal sendes (OUT) eller tomt array (IN)[0x01, 0x02]
LengthIntOverførselsstørrelse i bytes64
TimeoutIntMillisekunder til afbrydelse100
ReturneringTypeBeskrivelse
DataArray1D-ArrayModtagne bytes (IN-transfers), eller tomt
// Skriv til endepunkt 0x01
device.bulk_transfer(0x01, [0x00, 0x01, 0x02], 3, 100);
// Læs fra endepunkt 0x81
var response = device.bulk_transfer(0x81, [], 64, 100);
// Stor bulk-skrivning (f.eks. LCD-billeddata)
device.bulk_transfer(0x02, imageData, 1024, 500);

Low-level USB-control-transfer. Bruges til autentificerings-handshakes, producentspecifikke protokoller og tilfælde, hvor HID-metoder ikke er tilstrækkelige. Dette er en control-transfer, ikke en bulk-transfer.

ParameterTypeBeskrivelseEksempel
RequestTypeHexUSB-request-type-bitmap (retning, type, modtager)0xA1
RequestHexRequest-kode (enhedsspecifik)0x01
ValueHexValue-felt0x0100
IndexIntInterface- eller endepunkt-indeks0x00
DataArray1D-ArrayData der skal sendes (host→enhed), eller tomt[]
LengthIntForventet svarlængde (enhed→host)192
TimeoutIntMillisekunder til afbrydelse1000
ReturneringTypeBeskrivelse
DataArray1D-ArrayModtagne bytes (enhed→host-transfers)

Hyppige RequestType-værdier:

VærdiRetningTypeModtagerBrugstilfælde
0x21Host → EnhedClassInterfaceHID SET_REPORT
0xA1Enhed → HostClassInterfaceHID GET_REPORT
0x80Enhed → HostStandardEnhedDeskriptor-læsninger
0x00Host → EnhedStandardEnhedStandardkommandoer
// Læs autentificerings-token (enhed → host, Class, Interface)
var token = device.control_transfer(
0xA1, // enhed→host, Class, Interface
0x01, // GET_REPORT
0x0100, // Rapport-type (Feature) + rapport-ID
0x00, // Interface 0
[], // Ingen udgående data
192, // Forvent 192 bytes tilbage
1000 // 1 sekund timeout
);
// Send feature-rapport (host → enhed)
device.control_transfer(0x21, 0x09, 0x0300, 0, [0x03, 0x08, 0x32], 0, 500);

Til serielle/COM-port-enheder importeres Serial-modulet og pluginets Type() sættes til "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 eller 8
stopBits: "One" // "One", "OneAndHalf", "Two"
});
MetodeBeskrivelseReturnering
serial.connect(options?)Åbn seriel portbool
serial.disconnect()Luk seriel portvoid
serial.isConnected()Kontrollér forbindelsesstatusbool
serial.write(data)Send dataSendte bytes
serial.read(maxBytes?, timeoutMs?)Læs tilgængelige bytes (standard: alle, 1000 ms timeout)Byte-array
serial.readAll()Læs alle tilgængelige bytes straksByte-array
serial.availablePorts()List tilgængelige COM-porteArray
serial.getPortName()Aktuelt portnavnstring
serial.getBaudRate()Aktuel baudratenumber
serial.getDeviceInfo()Port-info med VID, PID osv.object
import { serial } from "@SignalRGB/serial";
export function Type() { return "serial"; }
export function Initialize() {
if (!serial.connect()) {
device.log("Forbindelse til seriel port mislykkedes");
return;
}
device.log(`Forbundet på ${serial.getPortName()} med ${serial.getBaudRate()} baud`);
}
export function Render() {
serial.write([0xFF, ...RGBData]);
}
export function Shutdown() {
serial.disconnect();
}

Til netværksaktiverede enheder importeres TCP- eller UDP-modulet og Type() sættes til "network". Begge moduler bruger en hændelsesbaseret callback-model.

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("Forbundet");
socket.send([0x01, 0x02, 0x03]);
});
socket.on("message", (data) => {
device.log(`Modtaget: ${data}`);
});
socket.on("error", (err) => {
device.log(`Fejl: ${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-metoder:

MetodeBeskrivelse
tcp.createSocket()Opret ny TCP-socket
socket.connect(address, port)Opret forbindelse til en host
socket.send(data)Send streng eller byte-array
socket.bind(port)Bind til lokal port
socket.close()Luk socket
socket.on(event, callback)Registrér event-handler

TCP-hændelser: "connected", "disconnected", "message", "error"


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

UDP-metoder:

MetodeBeskrivelse
udp.createSocket()Opret ny UDP-socket
socket.connect(address, port)Angiv standard sendemål
socket.send(data)Send til forbundet adresse
socket.write(data, address, port)Send til bestemt adresse uden forudgående connect()-kald
socket.bind(port)Bind til lokal port til modtagelse
socket.close()Luk socket
socket.on(event, callback)Registrér event-handler

UDP-hændelser: "connected", "disconnected", "message", "error"


Til enheder der kræver krypteret kommunikation (f.eks. Philips Hue), bruges dtls-feature’et. Det tilbyder DTLS-krypteret UDP med en Pre-Shared Key (PSK).

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

DTLS-metoder:

MetodeBeskrivelse
dtls.createConnection(host, port, identity, key)Åbn krypteret forbindelse med PSK
dtls.send(data, endianness?)Send krypterede data (0 = Little-Endian, 1 = Big-Endian)
dtls.hasEncryptedConnection()Returnerer true hvis forbindelsen er etableret
dtls.CloseConnection()Luk forbindelsen
dtls.onConnectionEstablished(cb)Callback når forbindelsen er oprettet
dtls.onConnectionClosed(cb)Callback når forbindelsen lukkes
dtls.onConnectionError(cb)Callback ved fejl