تخطَّ إلى المحتوى

ما هي الإضافة؟

يستخدم SignalRGB إضافات USB مخصصة مكتوبة بلغة JavaScript لدعم أجهزة RGB من جهات خارجية. إذا كان لديك جهاز غير مدعوم بعد، يمكنك كتابة إضافتك الخاصة له. وإذا كان لديك Arduino أو متحكم دقيق آخر مفتوح المصدر، يمكنك أيضًا إنشاء إضافة لـ SignalRGB للتواصل معه والحصول على حلول RGB مصنوعة يدويًا بالكامل.

إضافاتنا المنشورة حاليًا ذات شيفرة مصدرية قابلة للقراءة ومتاحة في مستودع إضافات SignalRGB العام. إذا أنشأت شيئًا يمكن للآخرين الاستفادة منه، فلا تتردد في تقديم طلب سحب (pull request) أو التواصل مع فريق الدعم الرسمي لدينا!


الإضافة عبارة عن ملف JavaScript واحد يحمّله SignalRGB لجهاز USB محدد. وهي تقوم بأمرين:

  1. تصف الجهاز — صادرات تُخبر SignalRGB باسم الجهاز ومعرّفاته وتخطيط مصابيح LED وبروتوكول الاتصال.
  2. تشغّل الجهاز — دوال دورة الحياة التي يستدعيها SignalRGB لتهيئة الجهاز، وإرسال الألوان في كل إطار، والتنظيف عند الخروج.

تتبع كل إضافة الشكل الأساسي نفسه:

// ── Device identity ──────────────────────────────────────
export function Name() { return "My Device"; }
export function Publisher() { return "Your Name"; }
export function VendorId() { return 0x1234; }
export function ProductId() { return 0x5678; }
export function Type() { return "hid"; }
// ── Canvas size and LED layout ────────────────────────────
export function Size() { return [7, 3]; }
export function LedNames() { return ["Logo", "Left", "Right"]; }
export function LedPositions() { return [[3,1], [0,1], [6,1]]; }
// ── Lifecycle ─────────────────────────────────────────────
export function Initialize() {
// Called once when the device connects or streaming is enabled.
// Send any initialization packets the device needs here.
SendInitPacket();
}
export function Render() {
// Called every frame (~30ms by default).
// Read colors from the canvas and send them to the device.
SendColors();
}
export function Shutdown() {
// Called when SignalRGB exits or streaming is disabled.
// Return the device to hardware mode here if needed.
SetHardwareControl();
}

تُستدعى مرة واحدة عند اتصال الجهاز أو إعادة اتصاله، وكلما تم تفعيل مفتاح البث في صفحة إعدادات الجهاز. استخدمها لأي عمل عند بدء التشغيل: تحويل الجهاز إلى وضع التحكم البرمجي، أو إرسال مصافحات البرنامج الثابت، أو قراءة الإعدادات المحفوظة، وما إلى ذلك.

إذا كانت هناك أي عمليات متعارضة قيد التشغيل، فستنتظر التهيئة حتى تُغلق أو يتجاوز المستخدم هذا الفحص.

حلقة العرض هي جوهر الإضافة. يستدعي SignalRGB الدالة Render() في كل إطار. التسلسل في كل إطار هو:

  1. تُحدَّث إعدادات المستخدم
  2. تُسحب الألوان من اللوحة إلى مخزن البكسلات المؤقت للجهاز
  3. تُطلق أي استدعاءات on*Changed (بترتيب حدوث التغييرات)
  4. تُستدعى Render()

داخل Render() تستدعي device.color(x, y) لقراءة ألوان البكسلات وإرسالها إلى العتاد. الفاصل الزمني الافتراضي بين الإطارات هو 30ms.

تُستدعى عند خروج SignalRGB بشكل سليم أو عند تعطيل مفتاح البث. إذا كان لجهازك وضع إضاءة عتادي، فاستعِده هنا حتى لا تنطفئ مصابيح LED لدى المستخدم عندما لا يكون SignalRGB قيد التشغيل.

يمكن أن يكون لكل عنصر من عناصر التحكم الظاهرة للمستخدم (راجع ControllableParameters) استدعاء مطابق يُطلق قبل Render() كلما غيّر المستخدم ذلك الإعداد. سمِّ الدالة on[propertyName]Changed() — مع مراعاة حالة الأحرف.

// ControllableParameters entry:
{ "property": "dpi1", "label": "DPI", "type": "number", "min": "200", "max": "18000", "default": "800" }
// Matching callback:
export function ondpi1Changed() {
setDpi(dpi1);
}

يُطلق الاستدعاء المدمج onBrightnessChanged() عند تحريك منزلق السطوع الرئيسي للجهاز.


تُخبر هذه الصادرات SignalRGB بكل ما يحتاج إلى معرفته عن الجهاز قبل أن يتصل به.

يُعرضان في واجهة SignalRGB.

export function Name() { return "Corsair K70 RGB"; }
export function Publisher() { return "YourName"; }

معرّفات USB التي يستخدمها SignalRGB للعثور على الجهاز في النظام. يجب أن تكون قيمًا سداسية عشرية دقيقة. إذا لم تظهر إضافتك، فإن عدم تطابق المعرّف هو السبب الأرجح.

export function VendorId() { return 0x1B1C; }
export function ProductId() { return 0x1B49; }

تضبط بروتوكول اتصال USB. القيمة الافتراضية هي "hid" إذا لم تُصدَّر. راجع تحديد نوع الجهاز للاطلاع على القائمة الكاملة وكيفية الاختيار.

export function Type() { return "hid"; } // HID (most devices)
export function Type() { return "rawusb"; } // Raw USB / libusb
export function Type() { return "hybrid"; } // Both simultaneously
export function Type() { return "serial"; } // COM port

تحدد هذه الصادرات الثلاث معًا كيفية ظهور الجهاز على اللوحة.

  • Size() — المربع المحيط [width, height] لشبكة بكسلات الجهاز. لا يمكن لـ device.color() أخذ عينات إلا من الإحداثيات الواقعة داخل هذا المربع.
  • LedNames() — مصفوفة مرتبة بأسماء مصابيح LED. يجب أن تتبع الأسماء قائمة أسماء المفاتيح المدعومة لتفعيل تأثيرات الضغط على المفاتيح وتلوين مصابيح LED.
  • LedPositions() — مصفوفة مرتبة من مواضع [x, y] داخل شبكة Size، موضع واحد لكل مصباح LED، بالترتيب نفسه لـ LedNames.
export function Size() { return [7, 3]; }
export function LedNames() { return ["Logo", "Left Side", "Right Side"]; }
export function LedPositions() { return [[3, 1], [0, 1], [6, 1]]; }

تتحكم في نقاط نهاية USB التي يفتحها SignalRGB. تُمرَّر كل نقطة نهاية مكتشفة إلى Validate() — أرجِع true لفتحها، وfalse لتخطيها. يمكنك فتح نقاط نهاية متعددة والتبديل بينها أثناء التشغيل باستخدام device.set_endpoint().

export function Validate(endpoint) {
return endpoint.interface === 2 && endpoint.usage_page === 0xFF00;
}

راجع اختيار نقاط النهاية لمعرفة كيفية العثور على القيم الصحيحة.

تُرجع مصفوفة من الإعدادات الظاهرة للمستخدم التي تظهر في صفحة إعدادات الجهاز. راجع عناصر تحكم المستخدم للاطلاع على المخطط الكامل.

export function ControllableParameters() {
return [
{ "property": "LightingMode", "label": "Lighting Mode", "type": "combobox",
"values": ["Software", "Hardware"], "default": "Software" },
{ "property": "DPILevel", "label": "DPI", "type": "number",
"min": "200", "max": "18000", "step": "50", "default": "800" }
];
}

قائمة بأسماء ملفات exe التي تتعارض مع هذه الإضافة. لن يبدأ SignalRGB التهيئة أثناء تشغيل أي منها. يجب أن تتطابق الأسماء تمامًا.

export function ConflictingProcesses() {
return ["iCUE.exe", "CorsairHID.exe"];
}

رابط صورة الجهاز المعروضة في واجهة SignalRGB. الحجم القياسي هو 1024×1024 مع منطقة عرض فعلية بحجم 920×920.

export function ImageUrl() { return "https://..."; }