Zum Inhalt springen

Ein Plugin erstellen

Jetzt, da wir unsere RGB-Daten isoliert haben, können wir damit beginnen, unser Plugin zu erstellen.

Um ein Plugin zu erstellen, öffnen wir einen Texteditor und fügen den folgenden Text ein.

export function Name() { return ""; }
export function VendorId() { return ; }
export function ProductId() { return ; }
export function Publisher() { return ""; }
export function Documentation(){ return "troubleshooting/brand"; }
export function Size() { return [1,1]; }
export function ControllableParameters() {
return [
{"property":"shutdownColor", "group":"lighting", "label":"Shutdown Color", "min":"0", "max":"360", "type":"color", "default":"009bde"},
{"property":"LightingMode", "group":"lighting", "label":"Lighting Mode", "type":"combobox", "values":["Canvas", "Forced"], "default":"Canvas"},
{"property":"forcedColor", "group":"lighting", "label":"Forced Color", "min":"0", "max":"360", "type":"color", "default":"009bde"},
];
}
export function Initialize() {
}
var vLedNames = [ "Led 1" ];
var vLedPositions = [ [0,0] ];
export function LedNames() {
}
export function LedPositions() {
}
export function Render() {
}
export function Shutdown() {
}
function hexToRgb(hex) {
let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
let colors = [];
colors[0] = parseInt(result[1], 16);
colors[1] = parseInt(result[2], 16);
colors[2] = parseInt(result[3], 16);
return colors;
}
export function Validate(endpoint) {
return endpoint.interface === 0 && endpoint.usage === 0 && endpoint.usage_page === 0;
}
export function ImageUrl() {
return "";
}

Der obige Text ist ein grundlegendes Layout für ein Geräte-Plugin.

Wir beginnen damit, die Felder am Anfang des Plugins mit Informationen zu unserem Gerät zu füllen.

Wir können das Namensfeld mit dem Namen des Geräts ausfüllen.

Um die Vendor-ID und die Product-ID zu finden, müssen wir zunächst das Einstellungsmenü von SignalRGB über das Zahnrad-Symbol in der unteren linken Ecke öffnen.

Nun müssen wir zur Seite “Geräteinformationen” navigieren.

Wir suchen die VendorID und die ProductID für das Gerät, das wir implementieren. In meinem Fall ist das die Corsair Scimitar Pro. Die Vendor-ID der Scimitar ist 0x1b1c und die Product-ID ist 0x1b3e.

Jetzt, da wir die Vendor- und Product-ID haben, können wir diese Felder im Plugin ausfüllen.

Das Publisher-Feld können Sie mit Ihrem Namen füllen!

Damit haben wir vorerst alle Felder ausgefüllt, die wir können.

Hier ist unser Beispiel für die Scimitar Pro mit den ausgefüllten Feldern.

Als Nächstes müssen wir eine Funktion erstellen, um Farbdaten an unser Gerät zu senden. Wir beginnen damit, eine einfache Funktion wie die folgende zu erstellen:

function sendColors(shutdown = false)
{
let packet = [];
}

Als Nächstes müssen wir unser Packet mit Daten füllen. Dazu verwenden wir die Daten aus einem unserer markierten RGB-Packets.

  • HINWEIS: Dieses Gerät verwendet Zero-Padding. Das bedeutet, dass wir alle unsere Bytes um 1 Position nach oben verschieben müssen. Erfahren Sie mehr über Zero-Padding hier.

function sendColors(shutdown = false)
{
let packet = [];
packet[0] = 0x00;
packet[1] = 0x07;
packet[2] = 0x22;
packet[3] = 0x05;
packet[4] = 0x01;
}

Wir beginnen damit, die Header-Daten für das Packet wie oben gezeigt einzufügen. Wir hören bei Position 4 auf, da Position 5 unser erstes Byte der RGB-bezogenen Daten ist.

Als Nächstes müssen wir unser Farb-Füllsystem erstellen. Es gibt einige verschiedene Möglichkeiten, dies zu tun. Die verwendete Methode hängt von der Packet-Struktur des Geräts ab. Hier sind einige verschiedene Farb-Packet-Beispiele:

function sendZone(zone, shutdown = false)
{
let packet = [];
packet[0] = LongMessage;
packet[1] = ConnectionMode;
packet[2] = RGBFeatureID;
packet[3] = 0x30;
packet[4] = zone;
packet[5] = 0x01;
var iX = vLedPositions[zone][0];
var iY = vLedPositions[zone][1];
var color;
if(shutdown)
{
color = hexToRgb(shutdownColor);
}
else if (LightingMode == "Forced")
{
color = hexToRgb(forcedColor);
}
else
{
color = device.color(iX, iY);
}
packet[6] = color[0];
packet[7] = color[1];
packet[8] = color[2];
packet[9] = 0x02;
device.write(packet, 120);
}
function SendPacket(shutdown = false)
{
let packet = [];
packet[0] = 0x00;
packet[1] = 0x00;
packet[2] = 0x1F;
packet[3] = 0x00;
packet[4] = 0x00;
packet[5] = 0x00;
packet[6] = 0x41;
packet[7] = 0x0F;
packet[8] = 0x03;
packet[13] = 0x13;
for(let iIdx = 0; iIdx < vLedPositions.length; iIdx++)
{
let iPxX = vLedPositions[iIdx][0];
let iPxY = vLedPositions[iIdx][1];
var color;
if(shutdown)
{
color = hexToRgb(shutdownColor);
}
else if (LightingMode === "Forced")
{
color = hexToRgb(forcedColor);
}
else
{
color = device.color(iPxX, iPxY);
}
let iLedIdx = (iIdx*3) + 14;
packet[iLedIdx] = color[0];
packet[iLedIdx+1] = color[1];
packet[iLedIdx+2] = color[2];
}
device.write(packet, 120);
}
function sendColors(shutdown = false){
let packet = [];
packet[0x00] = 0x00;
packet[0x01] = 0x08;
packet[0x02] = 0x12;
packet[0x03] = 0x05;
packet[0x04] = 0x01;
let zoneId = [1, 2, 3, 4, 5];
for(let zone_idx = 0; zone_idx < vLedPositions.length; zone_idx++) {
let iX = vLedPositions[zone_idx][0];
let iY = vLedPositions[zone_idx][1];
var col;
if(shutdown){
col = hexToRgb(shutdownColor);
}else if (LightingMode === "Forced") {
col = hexToRgb(forcedColor);
}else{
col = device.color(iX, iY);
}
packet[(zone_idx * 4) + 2] = zoneId[zone_idx];
packet[(zone_idx * 4) + 3] = col[0];
packet[(zone_idx * 4) + 4] = col[1];
packet[(zone_idx * 4) + 5] = col[2];
}
device.write(packet, 120);
}

Die drei obigen Beispiele eignen sich jeweils für eine andere Packet-Struktur. Die Funktion sendZone eignet sich für Geräte, die ein separates Packet für jede LED verwenden. Die Funktion sendPacket eignet sich besser für Geräte, die mehrere LEDs hintereinander in einem einzigen Packet senden. Die Funktion sendColors eignet sich für Geräte, die mehrere LEDs in einem Packet haben, aber nicht direkt nacheinander. In unserem Fall werden wir die Funktion sendColors verwenden.

function sendColors(shutdown = false)
{
let packet = [];
packet[0] = 0x00;
packet[1] = 0x07;
packet[2] = 0x22;
packet[3] = 0x05;
packet[4] = 0x01;
let zoneId = [2, 4, 5, 1, 3];
for(let zone_idx = 0; zone_idx < vLedPositions.length; zone_idx++) {
let iX = vLedPositions[zone_idx][0];
let iY = vLedPositions[zone_idx][1];
var col;
if(shutdown){
col = hexToRgb(shutdownColor);
}else if (LightingMode === "Forced") {
col = hexToRgb(forcedColor);
}else{
col = device.color(iX, iY);
}
packet[(zone_idx * 1) + 2] = zoneId[zone_idx];
packet[(zone_idx * 1) + 3] = col[0];
packet[(zone_idx * 1) + 4] = col[1];
packet[(zone_idx * 1) + 5] = col[2];
}
packet[21] = 0xff;
packet[22] = 0xff;
packet[23] = 0xff;
device.write(packet, 120);
}

Um die Funktion sendColors korrekt einzurichten, müssen wir die Zonen-IDs unseres Geräts herausfinden. Wenn wir uns die Packet-Aufzeichnung erneut ansehen, stellen wir fest, dass die Reihenfolge der Zonen 2, 4, 5, 1, 3 zu sein scheint, wie unten gezeigt. Beachten Sie, dass wir eine 5. Zone hinzugefügt haben, da es so aussieht, als ob wir auch die DPI-LED ansprechen können.

Jetzt, da wir unsere Zonen-IDs herausgefunden haben, müssen wir unsere Offsets für zone_idx bestimmen. Unsere erste Zone ist bei packet[4] und unsere zweite bei packet[8]. Das bedeutet, dass zone_idx jedes Mal mit 4 multipliziert werden muss, um zur nächsten LED zu gelangen. Wir müssen auch herausfinden, um wie viele Positionen wir die RGB-Daten verschieben. Da unsere erste Zone bei packet[5] ist, müssen wir unser Packet nur um 5 Bytes versetzen, wie unten zu sehen.

function sendColors(shutdown = false)
{
let packet = [];
packet[0] = 0x00;
packet[1] = 0x07;
packet[2] = 0x22;
packet[3] = 0x05;
packet[4] = 0x01;
let zoneId = [2, 4, 5, 1, 3];
for(let zone_idx = 0; zone_idx < vLedPositions.length; zone_idx++) {
let iX = vLedPositions[zone_idx][0];
let iY = vLedPositions[zone_idx][1];
var col;
if(shutdown){
col = hexToRgb(shutdownColor);
}else if (LightingMode === "Forced") {
col = hexToRgb(forcedColor);
}else{
col = device.color(iX, iY);
}
packet[(zone_idx * 4) + 5] = zoneId[zone_idx];
packet[(zone_idx * 4) + 6] = col[0];
packet[(zone_idx * 4) + 7] = col[1];
packet[(zone_idx * 4) + 8] = col[2];
}
device.write(packet, 120);
}

Jetzt, da wir alles hinzugefügt haben, was in unser Packet gehört, müssen wir die Packet-Länge ermitteln. Um die Packet-Länge zu finden, müssen wir nur nachsehen, wie lang unsere Daten in Wireshark sind. In unserem Beispiel sehen wir, dass die Daten in diesem Fall 64 Bytes lang sind.

  • HINWEIS: Dieses Gerät verwendet Zero-Padding, was bedeutet, dass wir die Schreiblänge um eins größer machen müssen als in der Wireshark-Aufzeichnung.

Da wir nun die Länge unserer Daten kennen, müssen wir nur noch unsere device.write-Länge auf 65 Bytes setzen, wie unten gezeigt.

function sendColors(shutdown = false)
{
let packet = [];
packet[0] = 0x00;
packet[1] = 0x07;
packet[2] = 0x22;
packet[3] = 0x05;
packet[4] = 0x01;
let zoneId = [2, 4, 5, 1, 3];
for(let zone_idx = 0; zone_idx < vLedPositions.length; zone_idx++) {
let iX = vLedPositions[zone_idx][0];
let iY = vLedPositions[zone_idx][1];
var col;
if(shutdown){
col = hexToRgb(shutdownColor);
}else if (LightingMode === "Forced") {
col = hexToRgb(forcedColor);
}else{
col = device.color(iX, iY);
}
packet[(zone_idx * 4) + 5] = zoneId[zone_idx];
packet[(zone_idx * 4) + 6] = col[0];
packet[(zone_idx * 4) + 7] = col[1];
packet[(zone_idx * 4) + 8] = col[2];
}
device.write(packet, 65);
}

Jetzt, da wir unser RGB-Packet eingerichtet haben, müssen wir unsere LEDs einrichten und die Geräte-Endpoints auswählen.

Um unsere LEDs einzurichten, müssen wir die richtige Anzahl von LEDs zu unseren vLedNames und vLedPositions hinzufügen. In unserem Fall müssen wir zu beiden vier weitere LEDs hinzufügen, wie unten gezeigt.

var vLedNames = [ "Led 1", "Led 2", "Led 3", "Led 4", "Led 5" ];
var vLedPositions = [ [0,0], [1,0], [2,0], [3,0], [4,0] ];

Wir geben diesen vier LEDs vorerst grundlegende Zuordnungen, da wir noch nicht wissen, wo diese LEDs physisch auf dem Gerät in Bezug auf ihre Zuordnungen innerhalb von SignalRGB positioniert sind.

Jetzt, da wir unsere LEDs zugeordnet haben, müssen wir unsere Gerätegröße festlegen. Unsere Gerätegröße muss in beide Richtungen um eins größer sein als unsere am weitesten entfernte LED. In meinem Fall muss die Größe [5,1] sein, da unsere am weitesten entfernte LED bei [4,0] ist.

export function Name() { return "Corsair Scimitar Pro"; }
export function VendorId() { return 0x1b1c; }
export function ProductId() { return 0x1B3E; }
export function Publisher() { return "WhirlwindFX"; }
export function Documentation(){ return "troubleshooting/corsair"; }
export function Size() { return [5,1]; }

Als Nächstes müssen wir den Endpoint unseres Geräts bestimmen.