Gå til indhold

Opret et plugin

Nu da vi har isoleret vores RGB-data, kan vi begynde at oprette vores plugin.

For at oprette et plugin åbner vi en teksteditor og indsætter følgende tekst.

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 "";
}

Ovenstående tekst er et grundlæggende layout for et enhedsplugin.

Vi begynder med at udfylde felterne i begyndelsen af pluginet med oplysninger om vores enhed.

Vi kan udfylde navnefeltet med enhedens navn.

For at finde Vendor-ID og Product-ID skal vi først åbne indstillingsmenuen i SignalRGB via tandhjulsikonet i nederste venstre hjørne.

Nu skal vi navigere til siden “Enhedsoplysninger”.

Vi søger efter VendorID og ProductID for den enhed vi implementerer. I vores tilfælde er det Corsair Scimitar Pro. Scimitarens Vendor-ID er 0x1b1c og Product-ID er 0x1b3e.

Nu da vi har Vendor- og Product-ID, kan vi udfylde disse felter i pluginet.

Publisher-feltet kan du udfylde med dit eget navn!

Med dette har vi foreløbig udfyldt alle de felter vi kan.

Her er vores eksempel for Scimitar Pro med de udfyldte felter.

Dernæst skal vi oprette en funktion til at sende farvedata til vores enhed. Vi begynder med at oprette en simpel funktion som følgende:

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

Dernæst skal vi udfylde vores pakke med data. Til dette bruger vi dataene fra en af vores markerede RGB-pakker.

  • BEMÆRK: Denne enhed bruger zero-padding. Det betyder at vi skal flytte alle vores bytes op med 1 position. Læs mere om Zero-Padding her.

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

Vi begynder med at indsætte header-dataene for pakken som vist ovenfor. Vi stopper ved position 4, da position 5 er vores første byte af RGB-relaterede data.

Dernæst skal vi oprette vores farve-udfyldningssystem. Der er nogle forskellige måder at gøre dette på. Den brugte metode afhænger af enhedens pakkestruktur. Her er nogle forskellige farve-pakke-eksempler:

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);
}

De tre ovenstående eksempler egner sig hver til en forskellig pakkestruktur. sendZone-funktionen egner sig til enheder der bruger en separat pakke til hver LED. sendPacket-funktionen egner sig bedre til enheder der sender flere LED’er fortløbende i én enkelt pakke. sendColors-funktionen egner sig til enheder der har flere LED’er i én pakke, men ikke direkte fortløbende. I vores tilfælde bruger vi sendColors-funktionen.

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);
}

For korrekt at opsætte sendColors-funktionen skal vi finde ud af vores enheds zone-ID’er. Når vi ser på pakkeoptagnelsen igen, opdager vi at zone-rækkefølgen ser ud til at være 2, 4, 5, 1, 3 som vist nedenfor. Bemærk at vi har tilføjet en 5. zone, da det ser ud til at vi også kan adressere DPI-LED’en.

Nu da vi har fundet vores zone-ID’er, skal vi bestemme vores offsets for zone_idx. Vores første zone er ved packet[4] og vores anden ved packet[8]. Det betyder at zone_idx skal multipliceres med 4 hver gang for at komme til næste LED. Vi skal også finde ud af med hvor mange positioner vi skal forskyve RGB-dataene. Da vores første zone er ved packet[5], skal vi blot forskyve vores pakke med 5 bytes som vist nedenfor.

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);
}

Nu da vi har tilføjet alt der hører til i vores pakke, skal vi bestemme pakkelængden. For at finde pakkelængden skal vi blot se hvor lang vores data er i Wireshark. I vores eksempel ser vi at dataene i dette tilfælde er 64 bytes lang.

  • BEMÆRK: Denne enhed bruger zero-padding, hvilket betyder at vi skal gøre skrivelængden én større end i Wireshark-optagelsen.

Nu da vi kender vores datares længde, skal vi blot sætte vores device.write-længde til 65 bytes som vist nedenfor.

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);
}

Nu da vi har sat vores RGB-pakke op, skal vi opsætte vores LED’er og vælge enhedsendepunkterne.

For at opsætte vores LED’er skal vi tilføje det korrekte antal LED’er til vores vLedNames og vLedPositions. I vores tilfælde skal vi tilføje fire yderligere LED’er til begge som vist nedenfor.

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

Vi giver disse fire LED’er grundlæggende tilknytninger for nu, da vi endnu ikke ved, hvor disse LED’er er fysisk placeret på enheden i forhold til deres tilknytninger inden for SignalRGB.

Nu da vi har tilknyttet vores LED’er, skal vi angive vores enhedsstørrelse. Vores enhedsstørrelse skal i begge retninger være én større end vores fjerneste LED. I vores tilfælde skal størrelsen være [5,1], da vores fjerneste LED er ved [4,0].

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]; }

Dernæst skal vi bestemme vores enheds endepunkt.