創建外掛程式
現在我們已經隔離了 RGB 資料,我們可以開始創建外掛程式了。
要開始創建外掛程式,我們需要打開文字編輯器並貼上以下文字。
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 "";}上述文字是裝置外掛程式的基本佈局。
我們將從填寫外掛程式頂部的欄位,填入我們裝置的資訊開始。
我們可以在名稱欄位中填入裝置的名稱。
尋找廠商和產品 ID
Section titled “尋找廠商和產品 ID”要找到廠商 ID 和產品 ID,我們需要先使用左下角的齒輪圖示打開 SignalRGB 的設定選單。

現在,我們需要前往裝置資訊頁面。

我們正在尋找我們要實作的裝置的 VendorID 和 ProductID。在我的情況下,這是 Corsair Scimitar Pro。Scimitar 的廠商 ID 是 0x1b1c,其產品 ID 是 0x1b3e。

現在我們有了廠商和產品 ID,我們可以在外掛程式中填寫這些欄位。
要填寫 Publisher 欄位,您可以填入您的名字!
現在,我們已經填寫了目前可以填寫的所有欄位。
以下是我們的 Scimitar Pro 範例,欄位已填寫完整。

創建 RGB 封包
Section titled “創建 RGB 封包”接下來,我們需要創建一個函式來向我們的裝置發送顏色資料。我們將從創建一個如下所示的簡單函式開始:
function sendColors(shutdown = false){ let packet = [];}接下來,我們需要開始用一些資料填充我們的封包,我們將使用我們標記的 RGB 封包之一的資料來做到這一點。
- 注意:此裝置是零填充的。這意味著我們需要將所有位元組向上移動 1 個位置。在此處了解零填充。

function sendColors(shutdown = false){ let packet = []; packet[0] = 0x00; packet[1] = 0x07; packet[2] = 0x22; packet[3] = 0x05; packet[4] = 0x01;
}我們開始填寫封包的標頭資料,如上所示。我們停在位置 4,因為位置 5 是我們 RGB 相關資料的第一個位元組。
確定封包類型
Section titled “確定封包類型”接下來,我們需要創建我們的顏色填充系統。有幾種不同的方式可以做到這一點。使用哪種方法取決於裝置的封包結構。以下是幾個不同的顏色封包範例:
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);}上面三個範例各自適用於不同的封包結構。sendZone 函式適合每個 LED 使用獨立封包的裝置。sendPacket 函式更適合在單個封包中連續發送多個 LED 的裝置。sendColors 函式適合封包中有多個 LED 但它們不是緊接著排列的裝置。在我們的例子中,我們將使用 sendColors 函式。
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);}要正確設置 sendColors 函式,我們需要找出裝置的區域 ID。再次查看封包擷取,我們看到區域的順序似乎是 2,4,5,1,3,如下所示。請注意,我們添加了第 5 個區域,因為看起來我們也可以定址 DPI LED。

現在我們找出了區域 ID,我們需要找出 zone_idx 的偏移量。我們的第一個區域在 packet[4],第二個在 packet[8]。這意味著我們的 zone_idx 每次需要乘以 4 才能到達新的 LED。我們還需要找出 RGB 資料的移位位置數。由於我們的第一個區域在 packet[5],我們只需要將封包偏移 5 個位元組,如下所示。
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);}現在我們已經添加了封包中所需的所有內容,我們需要找到封包長度。要找到封包長度,我們只需要看看我們的 Wireshark 資料有多長。查看我們的範例,我們可以看到在這種情況下資料是 64 位元組長。
- 注意:此裝置是零填充的,這意味著我們需要將寫入長度設定為比 Wireshark 擷取中的長度多一個位元組。

現在我們知道了資料的長度,我們只需要將我們的 device.write 長度設定為 65 位元組長,如下所示。
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);}現在我們已經設置好了 RGB 封包,我們需要設置 LED 並選擇裝置端點。
基本 LED 設置
Section titled “基本 LED 設置”要設置我們的 LED,我們需要在 vLedNames 和 vLedPositions 中添加正確數量的 LED。在我們的例子中,我們需要在每個中再添加四個 LED,如下所示。
var vLedNames = [ "Led 1", "Led 2", "Led 3", "Led 4", "Led 5" ];var vLedPositions = [ [0,0], [1,0], [2,0], [3,0], [4,0] ];我們現在給這四個 LED 基本映射,因為我們還不知道這些 LED 在裝置上相對於 SignalRGB 內部映射的物理位置。
現在我們已經映射出了 LED,我們需要設置裝置大小。我們的裝置大小在兩個方向上都需要比最遠的 LED 大一個。在我的情況下,大小需要是 [5,1],因為我們最遠的 LED 在 [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]; }接下來我們需要找出裝置的端點。