플러그인 만들기
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 찾기
섹션 제목: “공급업체 및 제품 ID 찾기”공급업체 ID와 제품 ID를 찾으려면 먼저 왼쪽 하단의 톱니바퀴 아이콘을 사용하여 SignalRGB 설정 메뉴를 열어야 합니다.

이제 장치 정보 페이지로 이동해야 합니다.

구현하는 장치의 VendorID와 ProductID를 찾고 있습니다. 이 경우 Corsair Scimitar Pro입니다. Scimitar의 공급업체 ID는 0x1b1c이고 제품 ID는 0x1b3e입니다.

이제 공급업체와 제품 ID를 얻었으므로 플러그인의 해당 필드를 채울 수 있습니다.
Publisher 필드에는 자신의 이름을 입력할 수 있습니다!
이제 현재 채울 수 있는 모든 필드를 입력했습니다.
아래는 필드가 입력된 Scimitar Pro의 예시입니다.

RGB 패킷 만들기
섹션 제목: “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;
}위와 같이 패킷의 헤더 데이터를 채우기 시작합니다. 위치 5는 RGB 관련 데이터의 첫 번째 바이트이므로 위치 4에서 멈춥니다.
패킷 유형 결정
섹션 제목: “패킷 유형 결정”다음으로 색상 채우기 시스템을 만들어야 합니다. 이것은 몇 가지 다른 방법으로 할 수 있습니다. 사용하는 방법은 장치의 패킷 구조에 따라 다릅니다. 다음은 몇 가지 다른 색상 패킷 예시입니다:
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임을 알 수 있습니다. DPI LED도 제어할 수 있어 보이므로 5번째 구역을 추가했습니다.

이제 구역 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 설정
섹션 제목: “기본 LED 설정”LED를 설정하려면 vLedNames와 vLedPositions에 올바른 수의 LED를 추가해야 합니다. 이 경우 아래와 같이 각각 4개의 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] ];SignalRGB 내 매핑과 관련하여 장치에 이 LED들이 물리적으로 어디에 위치하는지 아직 알 수 없으므로 지금은 이 4개의 LED에 기본 매핑을 부여합니다.
이제 LED를 매핑했으므로 장치 크기를 설정해야 합니다. 장치 크기는 양방향으로 가장 멀리 있는 LED보다 하나 더 커야 합니다. 이 경우 가장 먼 LED가 [4,0]에 있으므로 크기는 [5,1]이어야 합니다.
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]; }다음으로 파악해야 할 것은 장치의 엔드포인트입니다.