跳转到内容

创建插件

现在我们已经分离了 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,我们需要首先通过左下角的齿轮图标打开 SignalRGB 的设置菜单。

现在,我们需要转到设备信息页面。

我们正在寻找我们正在实现的设备的 VendorID 和 ProductID。在本例中,这是 Corsair Scimitar Pro。Scimitar 的供应商 ID 是 0x1b1c,产品 ID 是 0x1b3e。

现在我们有了供应商和产品 ID,可以在插件中填写这些字段。

要填写发布者字段,您可以填写您的名字!

现在,我们暂时填写了所有能填写的字段。

以下是填写了字段的 Scimitar Pro 示例。

接下来,我们需要创建一个向设备发送颜色数据的函数。我们将从创建如下简单函数开始:

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 相关数据的第一个字节。

接下来,我们需要创建颜色填充系统。有几种不同的方法可以做到这一点。使用哪种方法取决于设备的数据包结构。以下是一些不同的颜色数据包示例:

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,我们需要在 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]; }

接下来我们需要找出设备的端点。