2024-07-26 22:13:14 +02:00
|
|
|
export function Name() { return "Corsair Headset Device"; }
|
|
|
|
export function VendorId() { return 0x1B1C; }
|
|
|
|
export function ProductId() { return Object.keys(CORSAIRdeviceLibrary.PIDLibrary); }
|
|
|
|
export function Publisher() { return "WhirlwindFx"; }
|
|
|
|
export function Documentation(){ return "troubleshooting/corsair"; }
|
|
|
|
export function Size() { return [1, 1]; }
|
|
|
|
/* global
|
|
|
|
LightingMode:readonly
|
|
|
|
forcedColor:readonly
|
|
|
|
micLedMode:readonly
|
|
|
|
micMuteColor:readonly
|
|
|
|
idleTimeout:readonly
|
|
|
|
SidetoneAmount:readonly
|
|
|
|
*/
|
|
|
|
export function ControllableParameters() {
|
|
|
|
return [
|
|
|
|
{"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"},
|
|
|
|
{"property":"micLedMode", "group":"lighting", "label":"Microphone LED Mode", "type":"combobox", "values":["Canvas", "MuteState"], "default":"Canvas"},
|
|
|
|
{"property":"micMuteColor", "group":"lighting", "label":"Microphone Mute Color", "min":"0", "max":"360", "type":"color", "default":"#ff0000"},
|
|
|
|
{"property":"SidetoneAmount", "group":"", "label":"Sidetone", "step":"1", "type":"number", "min":"0", "max":"100", "default":"0"},
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
export function Initialize() {
|
|
|
|
CORSAIR.Initialize();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function Render() {
|
|
|
|
CORSAIR.sendColors();
|
|
|
|
|
|
|
|
if(CORSAIR.getWirelessSupport()){
|
|
|
|
CORSAIR.fetchBattery();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function Shutdown(SystemSuspending) {
|
|
|
|
|
|
|
|
if(SystemSuspending){
|
|
|
|
// Go Dark on System Sleep/Shutdown
|
|
|
|
CORSAIR.sendColors("#000000");
|
|
|
|
}else{
|
|
|
|
const headsetMode = CORSAIR.getWirelessSupport() === true ? 0x09 : 0x08;
|
|
|
|
device.write([0x02, headsetMode, 0x01, 0x03, 0x00, 0x01], 64); // Hardware mode
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function onSidetoneAmountChanged() {
|
|
|
|
CORSAIR.setSidetone();
|
|
|
|
}
|
|
|
|
|
|
|
|
export function onidleTimeoutChanged() {
|
|
|
|
CORSAIR.setIdleTimeout();
|
|
|
|
}
|
|
|
|
|
|
|
|
export class CORSAIR_Device_Protocol {
|
|
|
|
constructor() {
|
|
|
|
this.Config = {
|
|
|
|
DeviceProductID: 0x0000,
|
|
|
|
DeviceName: "Corsair Headset Device",
|
|
|
|
DeviceEndpoint: { "interface": 0, "usage": 0x0000, "usage_page": 0x0000, "collection": 0x0000 },
|
|
|
|
LedNames: [],
|
|
|
|
LedPositions: [],
|
|
|
|
Leds: [],
|
|
|
|
Wireless: false, // True equals to 0x09 and false to 0x08,
|
|
|
|
pollingInterval: 500,
|
|
|
|
lastMicStatePolling: 0,
|
|
|
|
lastMicState: 0,
|
|
|
|
lastBatteryPolling: 0,
|
|
|
|
pollingBatteryInterval: 300000, // 5 Minutes
|
|
|
|
};
|
|
|
|
|
|
|
|
this.chargingStates = Object.freeze({
|
|
|
|
1 : 2,
|
|
|
|
2 : 1,
|
|
|
|
3 : 4
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
getDeviceProperties(deviceID) { return CORSAIRdeviceLibrary.LEDLibrary[deviceID];};
|
|
|
|
|
|
|
|
getDeviceProductId() { return this.Config.DeviceProductID; }
|
|
|
|
setDeviceProductId(productID) { this.Config.DeviceProductID = productID; }
|
|
|
|
|
|
|
|
getDeviceName() { return this.Config.DeviceName; }
|
|
|
|
setDeviceName(deviceName) { this.Config.DeviceName = deviceName; }
|
|
|
|
|
|
|
|
getDeviceEndpoint() { return this.Config.DeviceEndpoint; }
|
|
|
|
setDeviceEndpoint(deviceEndpoint) { this.Config.DeviceEndpoint = deviceEndpoint; }
|
|
|
|
|
|
|
|
getLedNames() { return this.Config.LedNames; }
|
|
|
|
setLedNames(ledNames) { this.Config.LedNames = ledNames; }
|
|
|
|
|
|
|
|
getLedPositions() { return this.Config.LedPositions; }
|
|
|
|
setLedPositions(ledPositions) { this.Config.LedPositions = ledPositions; }
|
|
|
|
|
|
|
|
getLeds() { return this.Config.Leds; }
|
|
|
|
setLeds(leds) { this.Config.Leds = leds; }
|
|
|
|
|
|
|
|
getDeviceImage() { return this.Config.image; }
|
|
|
|
setDeviceImage(image) { this.Config.image = image; }
|
|
|
|
|
|
|
|
getWirelessSupport() { return this.Config.Wireless; }
|
|
|
|
setWirelessSupport(wireless) { this.Config.Wireless = wireless; }
|
|
|
|
|
|
|
|
Initialize() {
|
|
|
|
//Initializing vars
|
|
|
|
this.setDeviceProductId(device.productId());
|
|
|
|
|
|
|
|
const DeviceProperties = this.getDeviceProperties(this.getDeviceProductId());
|
|
|
|
this.setDeviceName(DeviceProperties.name);
|
|
|
|
this.setDeviceEndpoint(DeviceProperties.endpoint);
|
|
|
|
this.setLedNames(DeviceProperties.LedNames);
|
|
|
|
this.setLedPositions(DeviceProperties.LedPositions);
|
|
|
|
this.setLeds(DeviceProperties.Leds);
|
|
|
|
this.setDeviceImage(DeviceProperties.image);
|
|
|
|
|
|
|
|
if(DeviceProperties.wireless){
|
|
|
|
this.setWirelessSupport(DeviceProperties.wireless);
|
|
|
|
device.addFeature("battery");
|
|
|
|
device.addProperty({"property":"idleTimeout", "group":"", "label":"Device Sleep Timeout (Minutes)", "type":"combobox", "values":["Off", "1", "2", "3", "4", "5", "10", "15", "20", "25", "30"], "default":"10"});
|
|
|
|
}
|
|
|
|
|
|
|
|
device.log("Device model found: " + this.getDeviceName());
|
|
|
|
device.setName("Corsair " + this.getDeviceName());
|
|
|
|
device.setSize(DeviceProperties.size);
|
|
|
|
device.setControllableLeds(this.getLedNames(), this.getLedPositions());
|
|
|
|
device.setImageFromUrl(this.getDeviceImage());
|
|
|
|
device.set_endpoint(
|
|
|
|
DeviceProperties.endpoint[`interface`],
|
|
|
|
DeviceProperties.endpoint[`usage`],
|
|
|
|
DeviceProperties.endpoint[`usage_page`],
|
|
|
|
DeviceProperties.endpoint[`collection`]
|
|
|
|
);
|
|
|
|
|
|
|
|
this.modernDirectLightingMode();
|
|
|
|
}
|
|
|
|
|
|
|
|
modernDirectLightingMode() {
|
|
|
|
const headsetMode = this.getWirelessSupport() === true ? 0x09 : 0x08;
|
|
|
|
const endpoint = this.getDeviceEndpoint();
|
|
|
|
device.set_endpoint(endpoint[`interface`], endpoint[`usage`], endpoint[`usage_page`]);
|
|
|
|
|
|
|
|
console.log("Setting Software Mode!");
|
|
|
|
device.write([0x02, headsetMode, 0x01, 0x03, 0x00, 0x02], 64); // Enable Software Mode
|
|
|
|
device.write([0x02, headsetMode, 0x0D, 0x00, 0x01], 64); //Open lighting endpoint
|
|
|
|
device.pause(1000);
|
|
|
|
|
|
|
|
const HWBrightnessPacket = [0x02, headsetMode, 0x02, 0x02, 0x00];
|
|
|
|
|
|
|
|
device.clearReadBuffer();
|
|
|
|
device.write(HWBrightnessPacket, 64);
|
|
|
|
device.pause(100);
|
|
|
|
|
|
|
|
const HWBrightness = device.read(HWBrightnessPacket, 64);
|
|
|
|
|
|
|
|
if (HWBrightness[4] !== 0xe8 || HWBrightness[5] !== 0x03) {
|
|
|
|
device.write([0x02, headsetMode, 0x01, 0x02, 0x00, 0xe8, 0x03], 64); //Hardware Brightness 100%
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sendColors(overrideColor) {
|
|
|
|
|
|
|
|
const deviceLedPositions = this.getLedPositions();
|
|
|
|
const deviceLedNames = this.getLedNames();
|
|
|
|
const deviceLeds = this.getLeds();
|
|
|
|
const RGBData = [];
|
|
|
|
|
|
|
|
for (let iIdx = 0; iIdx < deviceLeds.length; iIdx++) {
|
|
|
|
const iPxX = deviceLedPositions[iIdx][0];
|
|
|
|
const iPxY = deviceLedPositions[iIdx][1];
|
|
|
|
let color;
|
|
|
|
|
|
|
|
if(deviceLedNames[iIdx] === "Mic" && micLedMode === "MuteState"){
|
|
|
|
const micState = this.fetchMicStatus();
|
|
|
|
|
|
|
|
if (micState === 1) {
|
|
|
|
color = hexToRgb(micMuteColor);
|
|
|
|
} else {
|
|
|
|
color = device.color(iPxX, iPxY);
|
|
|
|
}
|
|
|
|
}else if (overrideColor){
|
|
|
|
color = hexToRgb(overrideColor);
|
|
|
|
}else if (LightingMode === "Forced") {
|
|
|
|
color = hexToRgb(forcedColor);
|
|
|
|
}else {
|
|
|
|
color = device.color(iPxX, iPxY);
|
|
|
|
}
|
|
|
|
|
|
|
|
RGBData[(deviceLeds[iIdx])] = color[0];
|
|
|
|
RGBData[(deviceLeds[iIdx])+3] = color[1];
|
|
|
|
RGBData[(deviceLeds[iIdx])+6] = color[2];
|
|
|
|
}
|
|
|
|
|
|
|
|
this.writeRGB(RGBData);
|
|
|
|
}
|
|
|
|
|
|
|
|
writeRGB(RGBData) {
|
|
|
|
const headsetMode = this.getWirelessSupport() === true ? 0x09 : 0x08;
|
|
|
|
const endpoint = this.getDeviceEndpoint();
|
|
|
|
device.set_endpoint(endpoint[`interface`], endpoint[`usage`], endpoint[`usage_page`]);
|
|
|
|
|
|
|
|
device.write([0x02, headsetMode, 0x06, 0x00, 0x09, 0x00, 0x00, 0x00].concat(RGBData), 64);
|
|
|
|
}
|
|
|
|
|
|
|
|
fetchMicStatus(){
|
|
|
|
|
|
|
|
if(Date.now() - this.Config.lastMicStatePolling < this.Config.pollingInterval) {
|
|
|
|
return this.Config.lastMicState;
|
|
|
|
}
|
|
|
|
|
|
|
|
const headsetMode = this.getWirelessSupport() === true ? 0x09 : 0x08;
|
|
|
|
const micreadMode = this.getDeviceName().includes("HS80") === true ? 0xA6 : 0x46;
|
|
|
|
const endpoint = this.getDeviceEndpoint();
|
|
|
|
device.set_endpoint(endpoint[`interface`], endpoint[`usage`], endpoint[`usage_page`]);
|
|
|
|
|
|
|
|
const micStatusPacket = [0x02, headsetMode, 0x02, micreadMode, 0x00];
|
|
|
|
|
|
|
|
device.pause(100);
|
|
|
|
device.clearReadBuffer();
|
|
|
|
device.write(micStatusPacket, 64);
|
|
|
|
device.pause(50);
|
|
|
|
|
|
|
|
const micStatus = device.read(micStatusPacket, 64); // Index 5 returns 0 to unmutted/enable and 1 to muted/disabled
|
|
|
|
this.Config.lastMicStatePolling = Date.now();
|
|
|
|
|
|
|
|
if (micStatus[3] === micreadMode) {
|
|
|
|
console.log("Invalid read on mic status.");
|
|
|
|
|
|
|
|
return this.Config.lastMicState;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.Config.lastMicState = micStatus[4];
|
|
|
|
|
|
|
|
return micStatus[4];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setSidetone() {
|
|
|
|
const headsetMode = this.getWirelessSupport() === true ? 0x09 : 0x08;
|
|
|
|
const endpoint = this.getDeviceEndpoint();
|
|
|
|
device.set_endpoint(endpoint[`interface`], endpoint[`usage`], endpoint[`usage_page`]);
|
|
|
|
|
|
|
|
const sidetoneValue = Math.round((SidetoneAmount / 100) * 1000);
|
|
|
|
|
|
|
|
console.log("Setting Sidetone!");
|
|
|
|
device.write([0x02, headsetMode, 0x01, 0x47, 0x00, sidetoneValue & 0xFF, (sidetoneValue >> 8) & 0xFF], 64);
|
|
|
|
}
|
|
|
|
|
|
|
|
setIdleTimeout() {
|
|
|
|
const headsetMode = this.getWirelessSupport() === true ? 0x09 : 0x08;
|
|
|
|
const endpoint = this.getDeviceEndpoint();
|
|
|
|
device.set_endpoint(endpoint[`interface`], endpoint[`usage`], endpoint[`usage_page`]);
|
|
|
|
|
|
|
|
if (idleTimeout === "Off") {
|
|
|
|
console.log ("Setting Idle Timeout to: disabled");
|
|
|
|
device.write([0x02, headsetMode, 0x01, 0x0D], 64);
|
|
|
|
} else {
|
|
|
|
device.write([0x02, headsetMode, 0x01, 0x0D, 0x01], 64);
|
|
|
|
device.pause(1);
|
|
|
|
|
|
|
|
device.write([0x02, headsetMode, 0x01, 0x0D, 0x00, 0x01], 64);
|
|
|
|
device.pause(1);
|
|
|
|
|
|
|
|
const timeoutValue = idleTimeout * 60000;
|
|
|
|
const hexValue = timeoutValue.toString(16).padStart(6, '0');
|
|
|
|
const littleEndianHex = hexValue.match(/../g).reverse();
|
|
|
|
|
|
|
|
const packet = [];
|
|
|
|
packet[0] = 0x02;
|
|
|
|
packet[1] = headsetMode;
|
|
|
|
packet[2] = 0x01;
|
|
|
|
packet[3] = 0x0e;
|
|
|
|
|
|
|
|
packet[5] = parseInt(littleEndianHex[0], 16);
|
|
|
|
packet[6] = parseInt(littleEndianHex[1], 16);
|
|
|
|
packet[7] = parseInt(littleEndianHex[2], 16);
|
|
|
|
|
|
|
|
console.log ("Setting Idle Timeout to: " + idleTimeout);
|
|
|
|
device.write(packet, 64);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fetchBattery(){
|
|
|
|
|
|
|
|
if(Date.now() - this.Config.lastBatteryPolling < this.Config.pollingBatteryInterval) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const headsetMode = this.getWirelessSupport() === true ? 0x09 : 0x08;
|
|
|
|
const endpoint = this.getDeviceEndpoint();
|
|
|
|
device.set_endpoint(endpoint[`interface`], endpoint[`usage`], endpoint[`usage_page`]);
|
|
|
|
|
|
|
|
const batteryLevelPacket = [0x02, headsetMode, 0x02, 0x0F, 0x00];
|
|
|
|
const batteryStatusPacket = [0x02, headsetMode, 0x02, 0x10, 0x00];
|
|
|
|
|
|
|
|
device.pause(1000);
|
|
|
|
device.clearReadBuffer();
|
|
|
|
device.write(batteryLevelPacket, 64);
|
|
|
|
|
|
|
|
device.pause(50);
|
|
|
|
device.clearReadBuffer();
|
|
|
|
device.write(batteryStatusPacket, 64);
|
|
|
|
|
|
|
|
const batteryLevelData = device.read(batteryLevelPacket, 64);
|
|
|
|
const batteryStatusData = device.read(batteryStatusPacket, 64);
|
|
|
|
|
|
|
|
const batteryLevel = this.ReadInt32LittleEndian(batteryLevelData.slice(4, 7));
|
|
|
|
const batteryStatus = batteryStatusData[4];
|
|
|
|
|
|
|
|
this.Config.lastBatteryPolling = Date.now();
|
|
|
|
|
|
|
|
device.log(`Battery Level is [${(batteryLevel ?? 0)/10}%]`);
|
|
|
|
device.log(`Battery Status is [${this.chargingStates[batteryStatus ?? 0]}]`);
|
|
|
|
|
|
|
|
battery.setBatteryLevel((batteryLevel ?? 0)/ 10);
|
|
|
|
battery.setBatteryState(this.chargingStates[batteryStatus ?? 0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
ReadInt32LittleEndian(array){
|
|
|
|
return (array[0] & 0xFF) | ((array[1] << 8) & 0xFF00) | ((array[2] << 16) & 0xFF0000) | ((array[3] << 24) & 0xFF000000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class deviceLibrary {
|
|
|
|
constructor(){
|
|
|
|
this.PIDLibrary = {
|
|
|
|
0x0A43: "Virtuoso",
|
|
|
|
0x0A42: "Virtuoso",
|
|
|
|
0x0A41: "Virtuoso",
|
|
|
|
0x0A44: "Virtuoso",
|
|
|
|
0x0A40: "Virtuoso",
|
|
|
|
0x0A4B: "Virtuoso",
|
|
|
|
0x0A4C: "Virtuoso",
|
|
|
|
0x0A5C: "Virtuoso",
|
|
|
|
0x0A3D: "Virtuoso SE",
|
|
|
|
0x0A3E: "Virtuoso SE",
|
|
|
|
0x0A34: "Virtuoso SE",
|
|
|
|
0x0A62: "Virtuoso XT",
|
|
|
|
0x0A64: "Virtuoso XT", // Wireless
|
|
|
|
0x0A69: "HS80",
|
|
|
|
//0x0A6A: "HS80", // PID for wired WHILE wireless dongle plugged in, doesnt control the headset
|
|
|
|
0x0A6B: "HS80",
|
|
|
|
0x0A71: "HS80", //White
|
|
|
|
0x0A73: "HS80", //White
|
|
|
|
};
|
|
|
|
|
|
|
|
this.LEDLibrary = {
|
|
|
|
|
|
|
|
// Virtuoso Standard
|
|
|
|
0x0A43: {
|
|
|
|
name: "Virtuoso",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-standard.png"
|
|
|
|
},
|
|
|
|
0x0A42: {
|
|
|
|
name: "Virtuoso Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-standard.png"
|
|
|
|
},
|
|
|
|
0x0A41: {
|
|
|
|
name: "Virtuoso Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-standard.png"
|
|
|
|
},
|
|
|
|
0x0A44: {
|
|
|
|
name: "Virtuoso Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-standard.png"
|
|
|
|
},
|
|
|
|
0x0A40: {
|
|
|
|
name: "Virtuoso Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-standard.png"
|
|
|
|
},
|
|
|
|
0x0A4B: {
|
|
|
|
name: "Virtuoso Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-standard.png"
|
|
|
|
},
|
|
|
|
0x0A4C: {
|
|
|
|
name: "Virtuoso Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-standard.png"
|
|
|
|
},
|
|
|
|
0x0A5C: {
|
|
|
|
name: "Virtuoso Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-standard.png"
|
|
|
|
},
|
|
|
|
|
|
|
|
// Virtuoso SE
|
|
|
|
0x0A3D: {
|
|
|
|
name: "Virtuoso SE",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-se.png"
|
|
|
|
},
|
|
|
|
0x0A3E: {
|
|
|
|
name: "Virtuoso SE Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 3, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-se.png"
|
|
|
|
},
|
|
|
|
0x0A346: { // NEED TO CONFIRM
|
|
|
|
name: "Virtuoso SE Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Left Cans", "Right Can", "Mic"],
|
|
|
|
LedPositions: [[0, 2], [2, 2], [1, 0]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 4, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0005 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-se.png"
|
|
|
|
},
|
|
|
|
|
|
|
|
// Virtuoso XT
|
|
|
|
0x0A62: {
|
|
|
|
name: "Virtuoso XT",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Logo", "Power", "Mic"],
|
|
|
|
LedPositions: [[1, 0], [0, 2], [2, 2]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
endpoint : { "interface": 3, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0005 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-xt.png"
|
|
|
|
},
|
|
|
|
0x0A64: {
|
|
|
|
name: "Virtuoso XT Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Logo", "Power", "Mic"],
|
|
|
|
LedPositions: [[1, 0], [0, 2], [2, 2]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 3, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0005 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/virtuoso-xt.png"
|
|
|
|
},
|
|
|
|
|
|
|
|
// HS80
|
|
|
|
/*
|
|
|
|
0x0A6A: { // PID for wired WHILE wireless dongle plugged in
|
|
|
|
name: "HS80 RGB",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Logo", "Power", "Mic"],
|
|
|
|
LedPositions: [[1, 0], [0, 2], [2, 2]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
endpoint : { "interface": 0, "usage": 0x0001, "usage_page": 0xFF58, "collection": 0x0001 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/hs80.png"
|
|
|
|
},
|
|
|
|
*/
|
|
|
|
0x0A69: {
|
|
|
|
name: "HS80 RGB",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Logo", "Power", "Mic"],
|
|
|
|
LedPositions: [[1, 0], [0, 2], [2, 2]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
endpoint : { "interface": 3, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/hs80.png"
|
|
|
|
},
|
|
|
|
0x0A6B: {
|
|
|
|
name: "HS80 RGB Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Logo", "Power", "Mic"],
|
|
|
|
LedPositions: [[1, 0], [0, 2], [2, 2]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 3, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/hs80.png"
|
|
|
|
},
|
|
|
|
0x0A71: {
|
|
|
|
name: "HS80 RGB White",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Logo", "Power", "Mic"],
|
|
|
|
LedPositions: [[1, 0], [0, 2], [2, 2]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
endpoint : { "interface": 3, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0004 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/hs80.png"
|
|
|
|
},
|
|
|
|
0x0A73: { //White
|
|
|
|
name: "HS80 RGB White Wireless",
|
|
|
|
size: [3, 3],
|
|
|
|
LedNames: ["Logo", "Power", "Mic"],
|
|
|
|
LedPositions: [[1, 0], [0, 2], [2, 2]],
|
|
|
|
Leds: [0, 1, 2],
|
|
|
|
wireless: true,
|
|
|
|
endpoint : { "interface": 3, "usage": 0x0001, "usage_page": 0xFF42, "collection": 0x0005 },
|
|
|
|
image: "https://assets.signalrgb.com/devices/brands/corsair/audio/hs80.png"
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const CORSAIRdeviceLibrary = new deviceLibrary();
|
|
|
|
const CORSAIR = new CORSAIR_Device_Protocol();
|
|
|
|
|
|
|
|
function hexToRgb(hex) {
|
|
|
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
|
|
const 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.interface === 3 || endpoint.interface === 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function ImageUrl() {
|
|
|
|
return "https://assets.signalrgb.com/devices/default/misc/usb-drive-render.png";
|
|
|
|
}
|