Przejdź do głównej zawartości

Zaawansowana komunikacja

Ta strona omawia zaawansowane metody komunikacji USB, porty szeregowe i gniazda sieciowe. W przypadku podstawowych operacji odczytu i zapisu zobacz Zapisy i odczyty.

Zrozumienie różnicy między typami przesyłu USB pomaga wybrać właściwą metodę i debugować nieoczekiwane błędy.

TypMetodaTypowy rozmiarPrzypadek użycia
Interruptdevice.write() / device.read()3–64 bajtyDane RGB, małe polecenia, wejście klawiatury/myszy
Bulkdevice.write() / device.read()64–1025 bajtówObrazy LCD, aktualizacje oprogramowania układowego, duże bloki konfiguracji
Controldevice.send_report() / device.get_report() / device.control_transfer()32–192 bajtyUwierzytelnianie, raporty funkcji HID, konfiguracja urządzenia

Te same funkcje device.write() i device.read() są używane zarówno do przesyłu interrupt, jak i bulk — sterownik USB określa typ na podstawie punktu końcowego i rozmiaru pakietu.


Wysyła przesył sterujący HID GET_INPUT_REPORT. Podobny do device.get_report(), ale konkretnie żąda raportu Input zamiast Feature. Użyj tego, gdy get_report() zwraca nieprawidłowe dane, ponieważ urządzenie oddziela typy raportów Input i Feature.

ParametrTypOpisPrzykład
DataArrayTablica 1DDane żądania raportu[0x01]
LengthIntOczekiwany rozmiar raportu w bajtach64
ZwrotTypOpis
DataArrayTablica 1DBajty odebrane od urządzenia
var inputData = device.input_report([0x01], 64);

Wykonuje bezpośredni przesył bulk lub interrupt do konkretnego punktu końcowego USB. W przeciwieństwie do device.write() i device.read(), które używają punktu końcowego wybranego przez device.set_endpoint(), pozwala to na celowanie dowolnego punktu końcowego według adresu.

  • Adresy punktów końcowych kończące się na 0x80 lub wyżej to IN (urządzenie → host, odczyt).
  • Adresy punktów końcowych poniżej 0x80 to OUT (host → urządzenie, zapis).
ParametrTypOpisPrzykład
EndpointHexAdres punktu końcowego USB0x81
DataArrayTablica 1DDane do wysłania (OUT), lub pusta tablica (IN)[0x01, 0x02]
LengthIntRozmiar przesyłu w bajtach64
TimeoutIntMilisekundy przed rezygnacją100
ZwrotTypOpis
DataArrayTablica 1DOdebrane bajty (przesyły IN) lub puste
// Write to endpoint 0x01
device.bulk_transfer(0x01, [0x00, 0x01, 0x02], 3, 100);
// Read from endpoint 0x81
var response = device.bulk_transfer(0x81, [], 64, 100);
// Large bulk write (e.g. LCD image data)
device.bulk_transfer(0x02, imageData, 1024, 500);

Niskopoziomowy przesył sterujący USB. Używany do uścisków dłoni uwierzytelniania, protokołów specyficznych dla dostawcy i przypadków, gdy metody HID nie wystarczają. Jest to przesył sterujący, nie bulk.

ParametrTypOpisPrzykład
RequestTypeHexBitmapa typu żądania USB (kierunek, typ, odbiorca)0xA1
RequestHexKod żądania (specyficzny dla urządzenia)0x01
ValueHexPole wartości0x0100
IndexIntIndeks interfejsu lub punktu końcowego0x00
DataArrayTablica 1DDane do wysłania (host-do-urządzenia) lub puste[]
LengthIntOczekiwana długość odpowiedzi (urządzenie-do-hosta)192
TimeoutIntMilisekundy przed rezygnacją1000
ZwrotTypOpis
DataArrayTablica 1DOdebrane bajty (przesyły urządzenie-do-hosta)

Często używane wartości RequestType:

WartośćKierunekTypOdbiorcaPrzypadek użycia
0x21Host → UrządzenieKlasaInterfejsHID SET_REPORT
0xA1Urządzenie → HostKlasaInterfejsHID GET_REPORT
0x80Urządzenie → HostStandardUrządzenieOdczyty deskryptora
0x00Host → UrządzenieStandardUrządzenieStandardowe polecenia
// Read authentication token (device → host, class, interface)
var token = device.control_transfer(
0xA1, // Device-to-host, class, interface
0x01, // GET_REPORT
0x0100, // Report type (Feature) + report ID
0x00, // Interface 0
[], // No outbound data
192, // Expect 192 bytes back
1000 // 1 second timeout
);
// Send a feature report (host → device)
device.control_transfer(0x21, 0x09, 0x0300, 0, [0x03, 0x08, 0x32], 0, 500);

W przypadku urządzeń szeregowych/COM importujesz moduł serial i ustawiasz Type() swojej wtyczki na "serial".

import { serial } from "@SignalRGB/serial";
export function Type() { return "serial"; }
serial.connect({
baudRate: 115200, // Default: 115200
parity: "None", // "None", "Even", "Odd", "Space", "Mark"
dataBits: 8, // 5, 6, 7, or 8
stopBits: "One" // "One", "OneAndHalf", "Two"
});
MetodaOpisZwraca
serial.connect(options?)Otwórz port szeregowybool
serial.disconnect()Zamknij port szeregowyvoid
serial.isConnected()Sprawdź status połączeniabool
serial.write(data)Wyślij danezapisane bajty
serial.read(maxBytes?, timeoutMs?)Odczytaj dostępne bajty (domyślnie: wszystko, timeout 1000ms)tablica bajtów
serial.readAll()Natychmiast odczytaj wszystkie dostępne bajtytablica bajtów
serial.availablePorts()Wylistuj dostępne porty COMtablica
serial.getPortName()Bieżąca nazwa portustring
serial.getBaudRate()Bieżąca prędkość transmisjiliczba
serial.getDeviceInfo()Informacje o porcie z VID, PID itp.obiekt
import { serial } from "@SignalRGB/serial";
export function Type() { return "serial"; }
export function Initialize() {
if (!serial.connect()) {
device.log("Failed to connect to serial port");
return;
}
device.log(`Connected on ${serial.getPortName()} at ${serial.getBaudRate()} baud`);
}
export function Render() {
serial.write([0xFF, ...RGBData]);
}
export function Shutdown() {
serial.disconnect();
}

W przypadku urządzeń połączonych sieciowo importujesz moduł TCP lub UDP i ustawiasz Type() na "network". Oba moduły używają modelu callbacków opartego na zdarzeniach.

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("Connected");
socket.send([0x01, 0x02, 0x03]);
});
socket.on("message", (data) => {
device.log(`Received: ${data}`);
});
socket.on("error", (err) => {
device.log(`Error: ${err}`);
});
socket.connect("192.168.1.100", 8080);
}
export function Render() {
if (socket.state === socket.ConnectedState) {
socket.send(RGBData);
}
}
export function Shutdown() {
socket.close();
}

Metody TCP:

MetodaOpis
tcp.createSocket()Utwórz nowe gniazdo TCP
socket.connect(address, port)Połącz z hostem
socket.send(data)Wyślij string lub tablicę bajtów
socket.bind(port)Powiąż z lokalnym portem
socket.close()Zamknij gniazdo
socket.on(event, callback)Zarejestruj procedurę obsługi zdarzeń

Zdarzenia TCP: "connected", "disconnected", "message", "error"


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

Metody UDP:

MetodaOpis
udp.createSocket()Utwórz nowe gniazdo UDP
socket.connect(address, port)Ustaw domyślne miejsce docelowe wysyłania
socket.send(data)Wyślij do połączonego adresu
socket.write(data, address, port)Wyślij do konkretnego adresu bez wcześniejszego wywołania connect()
socket.bind(port)Powiąż z lokalnym portem do odbioru
socket.close()Zamknij gniazdo
socket.on(event, callback)Zarejestruj procedurę obsługi zdarzeń

Zdarzenia UDP: "connected", "disconnected", "message", "error"


W przypadku urządzeń wymagających zaszyfrowanej komunikacji (np. Philips Hue) użyj funkcji dtls. Zapewnia zaszyfrowany UDP DTLS przy użyciu klucza wstępnie udostępnionego (PSK).

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

Metody DTLS:

MetodaOpis
dtls.createConnection(host, port, identity, key)Otwórz zaszyfrowane połączenie z PSK
dtls.send(data, endianness?)Wyślij zaszyfrowane dane (0 = little-endian, 1 = big-endian)
dtls.hasEncryptedConnection()Zwraca true jeśli połączenie zostało nawiązane
dtls.CloseConnection()Zamknij połączenie
dtls.onConnectionEstablished(cb)Callback gdy połączenie się powiedzie
dtls.onConnectionClosed(cb)Callback gdy połączenie się zamknie
dtls.onConnectionError(cb)Callback przy błędzie