From 68f706e0c1a18332d95e96b0ef93c2f696fd7af0 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 15:32:09 +0800
Subject: [PATCH 01/34] Add SignalRGB flags
---
builddefs/common_features.mk | 7 +++++++
keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk | 1 +
2 files changed, 8 insertions(+)
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 3a6f6f6579e1..6b9965c0e836 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -638,6 +638,13 @@ ifeq ($(strip $(VIA_ENABLE)), yes)
TRI_LAYER_ENABLE := yes
endif
+ifeq ($(strip $(SIGNALRGB_ENABLE)), yes)
+ DYNAMIC_KEYMAP_ENABLE := yes
+ RAW_ENABLE := yes
+ BOOTMAGIC_ENABLE := yes
+ TRI_LAYER_ENABLE := yes
+endif
+
VALID_CUSTOM_MATRIX_TYPES:= yes lite no
CUSTOM_MATRIX ?= no
diff --git a/keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk b/keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk
index 1e5b99807cb7..5d69e14570ec 100644
--- a/keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk
+++ b/keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk
@@ -1 +1,2 @@
VIA_ENABLE = yes
+SIGNALRGB_ENABLE = yes
From efc8d559481626d752b1c638212a6b417ab7f91c Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 15:38:11 +0800
Subject: [PATCH 02/34] Add SignalRGB support
---
builddefs/common_features.mk | 12 +-
.../nuphy/air96_v2/ansi/keymaps/via/rules.mk | 1 -
quantum/qmk_version.h | 3 +
quantum/signalrgb.c | 193 ++++++++++++++++++
quantum/signalrgb.h | 82 ++++++++
5 files changed, 281 insertions(+), 10 deletions(-)
create mode 100644 quantum/qmk_version.h
create mode 100644 quantum/signalrgb.c
create mode 100644 quantum/signalrgb.h
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 6b9965c0e836..2e5421d6a33d 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -28,6 +28,7 @@ QUANTUM_SRC += \
$(QUANTUM_DIR)/sync_timer.c \
$(QUANTUM_DIR)/logging/debug.c \
$(QUANTUM_DIR)/logging/sendchar.c \
+ $(QUANTUM_DIR)/signalrgb.c \
VPATH += $(QUANTUM_DIR)/logging
# Fall back to lib/printf if there is no platform provided print
@@ -631,19 +632,12 @@ ifeq ($(strip $(LED_TABLES)), yes)
SRC += $(QUANTUM_DIR)/led_tables.c
endif
-ifeq ($(strip $(VIA_ENABLE)), yes)
+#ifeq ($(strip $(VIA_ENABLE)), yes)
DYNAMIC_KEYMAP_ENABLE := yes
RAW_ENABLE := yes
BOOTMAGIC_ENABLE := yes
TRI_LAYER_ENABLE := yes
-endif
-
-ifeq ($(strip $(SIGNALRGB_ENABLE)), yes)
- DYNAMIC_KEYMAP_ENABLE := yes
- RAW_ENABLE := yes
- BOOTMAGIC_ENABLE := yes
- TRI_LAYER_ENABLE := yes
-endif
+#endif
VALID_CUSTOM_MATRIX_TYPES:= yes lite no
diff --git a/keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk b/keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk
index 5d69e14570ec..1e5b99807cb7 100644
--- a/keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk
+++ b/keyboards/nuphy/air96_v2/ansi/keymaps/via/rules.mk
@@ -1,2 +1 @@
VIA_ENABLE = yes
-SIGNALRGB_ENABLE = yes
diff --git a/quantum/qmk_version.h b/quantum/qmk_version.h
new file mode 100644
index 000000000000..c420733791a8
--- /dev/null
+++ b/quantum/qmk_version.h
@@ -0,0 +1,3 @@
+#define QMK_VERSION_BYTE_1 0
+#define QMK_VERSION_BYTE_2 26
+#define QMK_VERSION_BYTE_3 0
diff --git a/quantum/signalrgb.c b/quantum/signalrgb.c
new file mode 100644
index 000000000000..3b3a71da8eb4
--- /dev/null
+++ b/quantum/signalrgb.c
@@ -0,0 +1,193 @@
+#ifndef RAW_ENABLE
+# error "RAW HID Communication is not enabled" //This should be impossible to run into afaik. Common_features ensures RAWHID is enabled.
+#endif
+
+#include "qmk_version.h"
+#include "protocol/host.h"
+#include "version.h"
+#include "quantum.h"
+#include "signalrgb.h"
+#include "color.h"
+#include "raw_hid.h"
+
+
+ uint8_t packet[32];
+
+void get_qmk_version(void) //Grab the QMK Version the board's firmware is built off of
+{
+ packet[0] = GET_QMK_VERSION;
+ packet[1] = QMK_VERSION_BYTE_1;
+ packet[2] = QMK_VERSION_BYTE_2;
+ packet[3] = QMK_VERSION_BYTE_3;
+
+ raw_hid_send(packet, 32);
+}
+
+void get_signalrgb_protocol_version(void)
+{
+ packet[0] = GET_PROTOCOL_VERSION;
+ packet[1] = PROTOCOL_VERSION_BYTE_1;
+ packet[2] = PROTOCOL_VERSION_BYTE_2;
+ packet[3] = PROTOCOL_VERSION_BYTE_3;
+
+ raw_hid_send(packet, 32);
+}
+
+void get_unique_identifier(void) //Grab the unique identifier for each specific model of keyboard.
+{
+ packet[0] = GET_UNIQUE_IDENTIFIER;
+ packet[1] = DEVICE_UNIQUE_IDENTIFIER_BYTE_1;
+ packet[2] = DEVICE_UNIQUE_IDENTIFIER_BYTE_2;
+ packet[3] = DEVICE_UNIQUE_IDENTIFIER_BYTE_3;
+
+ raw_hid_send(packet, 32);
+}
+
+void led_streaming(uint8_t *data) //Stream data from HID Packets to Keyboard.
+{
+ uint8_t index = data[1];
+ uint8_t numberofleds = data[2];
+ #if defined(RGBLIGHT_ENABLE)
+ if(index + numberofleds > RGBLIGHT_LED_COUNT) {
+ #elif defined(RGB_MATRIX_ENABLE)
+ if(index + numberofleds > RGB_MATRIX_LED_COUNT) {
+ #endif
+ packet[1] = DEVICE_ERROR_LED_BOUNDS;
+ raw_hid_send(packet,32);
+ return;
+ }
+
+ if(numberofleds >= 10)
+ {
+ packet[1] = DEVICE_ERROR_LED_COUNT;
+ raw_hid_send(packet,32);
+ return;
+ }
+
+ for (uint8_t i = 0; i < numberofleds; i++)
+ {
+ uint8_t offset = (i * 3) + 3;
+ uint8_t r = data[offset];
+ uint8_t g = data[offset + 1];
+ uint8_t b = data[offset + 2];
+
+ //if ( ((index + i) == CAPS_LOCK_LED_INDEX && host_keyboard_led_state().caps_lock) || ((index + i) == NUM_LOCK_LED_INDEX && host_keyboard_led_state().num_lock) || ((index + i) == SCROLL_LOCK_LED_INDEX && host_keyboard_led_state().scroll_lock)) {
+ //if ( ((index + i) == CAPS_LOCK_LED_INDEX && host_keyboard_led_state().caps_lock) || ((index + i) == NUM_LOCK_LED_INDEX && host_keyboard_led_state().num_lock)) {
+ //if ( (index + i) == CAPS_MAC_WIN_LED_INDEX && host_keyboard_led_state().caps_lock) {
+ //if ( (index + i) == CAPS_LOCK_LED_INDEX && host_keyboard_led_state().caps_lock) {
+ //if ( (index + i) == NUM_LOCK_LED_INDEX && host_keyboard_led_state().num_lock) {
+ //#if defined(RGBLIGHT_ENABLE)
+ //rgblight_setrgb_at(255, 255, 255, index + i);
+ //#elif defined(RGB_MATRIX_ENABLE)
+ //rgb_matrix_set_color(index + i, 255, 255, 255);
+ //#endif
+
+ //} else {
+
+ #if defined(RGBLIGHT_ENABLE)
+ rgblight_setrgb_at(r, g, b, index + i);
+ #elif defined(RGB_MATRIX_ENABLE)
+ rgb_matrix_set_color(index + i, r, g, b);
+ #endif
+ }
+ }
+//}
+
+void signalrgb_mode_enable(void)
+{
+ #if defined(RGB_MATRIX_ENABLE)
+ rgb_matrix_mode_noeeprom(RGB_MATRIX_SIGNALRGB); //Set RGB Matrix to SignalRGB Compatible Mode
+ #endif
+}
+
+void signalrgb_mode_disable(void)
+{
+ #if defined(RGBLIGHT_ENABLE)
+ rgblight_reload_from_eeprom();
+ #elif defined(RGB_MATRIX_ENABLE)
+ rgb_matrix_reload_from_eeprom(); //Reloading last effect from eeprom
+ #endif
+}
+
+void get_total_leds(void)//Grab total number of leds that a board has.
+{
+ packet[0] = GET_TOTAL_LEDS;
+ #if defined(RGBLIGHT_ENABLE)
+ packet[1] = RGBLIGHT_LED_COUNT;
+ #elif defined(RGB_MATRIX_ENABLE)
+ packet[1] = RGB_MATRIX_LED_COUNT;
+ #endif
+
+ raw_hid_send(packet, 32);
+}
+
+void get_firmware_type(void) //Grab which fork of qmk a board is running.
+{
+ packet[0] = GET_FIRMWARE_TYPE;
+ packet[1] = FIRMWARE_TYPE_BYTE;
+
+ raw_hid_send(packet, 32);
+}
+
+bool srgb_raw_hid_rx(uint8_t *data, uint8_t length) {
+ switch (data[0]) {
+ case GET_QMK_VERSION:
+
+ get_qmk_version();
+
+ break;
+ case GET_PROTOCOL_VERSION:
+
+ get_signalrgb_protocol_version();
+
+ break;
+ case GET_UNIQUE_IDENTIFIER:
+
+ get_unique_identifier();
+
+ break;
+ case STREAM_RGB_DATA:
+
+ led_streaming(data);
+
+ break;
+
+ case SET_SIGNALRGB_MODE_ENABLE:
+
+ signalrgb_mode_enable();
+
+ break;
+
+ case SET_SIGNALRGB_MODE_DISABLE:
+
+ signalrgb_mode_disable();
+
+ break;
+
+ case GET_TOTAL_LEDS:
+
+ get_total_leds();
+
+ break;
+
+ case GET_FIRMWARE_TYPE:
+
+ get_firmware_type();
+
+ break;
+
+ default:
+ return false;
+ }
+ return true;
+}
+
+#if defined(VIA_ENABLE)
+__attribute__((weak)) bool via_command_kb(uint8_t *data, uint8_t length) {
+ return srgb_raw_hid_rx(data, length);
+}
+#else
+void raw_hid_receive(uint8_t *data, uint8_t length) {
+ srgb_raw_hid_rx(data, length);
+}
+#endif
diff --git a/quantum/signalrgb.h b/quantum/signalrgb.h
new file mode 100644
index 000000000000..de909672ec5a
--- /dev/null
+++ b/quantum/signalrgb.h
@@ -0,0 +1,82 @@
+#pragma once
+
+enum signalrgb_commands
+{
+ GET_QMK_VERSION = 0x21,
+ GET_PROTOCOL_VERSION = 0x22,
+ GET_UNIQUE_IDENTIFIER = 0x23,
+ STREAM_RGB_DATA = 0x24,
+ SET_SIGNALRGB_MODE_ENABLE = 0x25,
+ SET_SIGNALRGB_MODE_DISABLE = 0x26,
+ GET_TOTAL_LEDS = 0x27,
+ GET_FIRMWARE_TYPE = 0x28,
+};
+
+enum signalrgb_responses
+{
+ PROTOCOL_VERSION_BYTE_1 = 1,
+ PROTOCOL_VERSION_BYTE_2 = 0,
+ PROTOCOL_VERSION_BYTE_3 = 6,
+ DEVICE_UNIQUE_IDENTIFIER_BYTE_1 = 0,
+ DEVICE_UNIQUE_IDENTIFIER_BYTE_2 = 0,
+ DEVICE_UNIQUE_IDENTIFIER_BYTE_3 = 0,
+ FIRMWARE_TYPE_BYTE = 2,
+ DEVICE_ERROR_LED_BOUNDS = 253,
+ DEVICE_ERROR_LED_COUNT = 254
+};
+
+void get_qmk_version(void);
+void get_signalrgb_protocol_version(void);
+void get_unique_identifier(void);
+void led_streaming(uint8_t *data);
+void signalrgb_mode_enable(void);
+void signalrgb_mode_disable(void);
+void get_total_leds(void);
+
+//Changelogs for Firmware Versions------------------------------------
+//V1.0.1 added detection for the total number of LEDs a board has. Plugins need a rewrite to make use of this change. Rewritten plugins will not function with older firmware.
+//V1.0.2 added another detection byte for which fork of SignalRGB firmware device is running. This means we can keep overlap Unique Identifiers between Sonix and Mainline.
+//V1.0.3 unifies the command IDs between Mainline, Sonix, and VIA. All commands have a 0x20 offset now.
+//V1.0.4 improves detection handling, and has a complete rewrite of the plugins. Also merges Mainline and VIA branches. VIA Branch is deprecated.
+//V1.0.5 adds support for RGBLight and adds proper bounds checking for leds to ensure we don't crash the firmware.
+//V1.0.6 fixes conflict with VIA running at the same time.
+
+/* keymap default:
+DEVICE, DEVICE_UNIQUE_IDENTIFIER_BYTE_1,DEVICE_UNIQUE_IDENTIFIER_BYTE_2,DEVICE_UNIQUE_IDENTIFIER_BYTE_3
+gmmk/pro/rev1/ansi:default 0 0 5
+gmmk/pro/rev2/ansi:default 0 0 5
+gmmk/pro/rev1/iso:default 0 0 6
+gmmk/pro/rev2/iso:default 0 0 6
+gmmk/gmmk2/p65/ansi:default 0 0 7
+gmmk/gmmk2/p65/iso:default 0 0 8
+gmmk/gmmk2/p96/ansi:default 0 0 9
+gmmk/gmmk2/p96/iso:default 0 0 10
+redragon/k530:default 0 1 1
+redragon/k552/rev1:ansi 0 1 2
+redragon/k552/rev1:iso 0 1 2
+redragon/k552/rev2:default 0 1 2
+redragon/k552/rev2:abnt2 0 1 2
+redragon/k556:default 0 1 3
+redragon/k580:default 0 1 4
+redragon/k582:default 0 1 3
+redragon/k630:default 0 1 5
+*/
+
+
+/* keymap via:
+DEVICE, DEVICE_UNIQUE_IDENTIFIER_BYTE_1,DEVICE_UNIQUE_IDENTIFIER_BYTE_2,DEVICE_UNIQUE_IDENTIFIER_BYTE_3
+gmmk/pro/rev1/ansi:via 0 0 5
+gmmk/pro/rev2/ansi:via 0 0 5
+gmmk/pro/rev1/iso:via 0 0 6
+gmmk/pro/rev2/iso:via 0 0 6
+gmmk/gmmk2/p65/ansi:via 0 0 7
+gmmk/gmmk2/p65/iso:via 0 0 8
+gmmk/gmmk2/p96/ansi:via 0 0 9
+gmmk/gmmk2/p96/iso:via 0 0 10
+gmmk/gmmk3/p65/ansi:via 0 0 11
+gmmk/gmmk3/p65/iso:via 0 0 12
+gmmk/gmmk3/p75/ansi:via 0 0 13
+gmmk/gmmk3/p75/iso:via 0 0 14
+gmmk/gmmk3/p100/ansi:via 0 0 15
+gmmk/gmmk3/p100/iso:via 0 0 16
+*/
From 0dcdb9c9ced38ad39fcf2783b98e39d6f24ccf8b Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 16:00:58 +0800
Subject: [PATCH 03/34] Add SignalRGB animation definition
---
quantum/rgb_matrix/animations/rgb_matrix_effects.inc | 3 ++-
quantum/rgb_matrix/animations/signalrgb_anim.h | 12 ++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
create mode 100644 quantum/rgb_matrix/animations/signalrgb_anim.h
diff --git a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc
index a02238a2d1a6..00a9731526f1 100644
--- a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc
+++ b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc
@@ -42,4 +42,5 @@
#include "starlight_anim.h"
#include "starlight_dual_sat_anim.h"
#include "starlight_dual_hue_anim.h"
-#include "riverflow_anim.h"
\ No newline at end of file
+#include "riverflow_anim.h"
+#include "signalrgb_anim.h"
\ No newline at end of file
diff --git a/quantum/rgb_matrix/animations/signalrgb_anim.h b/quantum/rgb_matrix/animations/signalrgb_anim.h
new file mode 100644
index 000000000000..39ce5129b2a5
--- /dev/null
+++ b/quantum/rgb_matrix/animations/signalrgb_anim.h
@@ -0,0 +1,12 @@
+// animations/signalrgb_anim.h
+RGB_MATRIX_EFFECT(SIGNALRGB)
+#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
+
+bool SIGNALRGB(effect_params_t* params)
+{
+ RGB_MATRIX_USE_LIMITS(led_min, led_max);
+
+ return rgb_matrix_check_finished_leds(led_max);
+}
+
+#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
\ No newline at end of file
From 25fff49e17ac0610c238d82440e250d72bf60dea Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 16:24:47 +0800
Subject: [PATCH 04/34] Add SignalRGB plugin for Air96v2.
---
.../NuPhy_Air96v2_QMK_ANSI_Keyboard.js | 329 ++++++++++++++++++
1 file changed, 329 insertions(+)
create mode 100644 SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
diff --git a/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
new file mode 100644
index 000000000000..db66c7950c14
--- /dev/null
+++ b/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
@@ -0,0 +1,329 @@
+export function Name() { return "NuPhy Air96 v2 ANSI QMK Keyboard"; }
+export function Version() { return "1.1.9"; }
+export function VendorId() { return 0x19F5; }
+export function ProductId() { return 0x3266; }
+export function Publisher() { return "WhirlwindFX"; }
+export function Documentation() { return "qmk/srgbmods-qmk-firmware"; }
+export function DeviceType() { return "keyboard"; }
+export function Size() { return [19, 6]; }
+export function DefaultPosition(){return [10, 100]; }
+export function DefaultScale(){return 8.0;}
+/* global
+shutdownMode:readonly
+shutdownColor:readonly
+LightingMode:readonly
+forcedColor:readonly
+*/
+export function ControllableParameters() {
+ return [
+ {"property":"shutdownMode", "group":"lighting", "label":"Shutdown Mode", "type":"combobox", "values":["SignalRGB", "Hardware"], "default":"SignalRGB"},
+ {"property":"shutdownColor", "group":"lighting", "label":"Shutdown Color", "min":"0", "max":"360", "type":"color", "default":"#000000"},
+ {"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"},
+ ];
+}
+
+//Plugin Version: Built for Protocol V1.0.6
+
+const vKeys = [
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, //19
+ 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, //18
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, //18
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, //16
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, //17
+ 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 //12
+];
+
+const vKeyNames = [
+ "Esc", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Print", "Del", "Home", "End", "Page Up", "Page Down", //19
+ "`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "+", "Backspace", "NumLock", "Num /", "Num *", "Num -", //18
+ "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\", "Num 7", "Num 8", "Num 9", "Num +", //18
+ "CapsLock", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter", "Num 4", "Num 5", "Num 6", //16
+ "Left Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "Right Shift", "Up Arrow", "Num 1", "Num 2", "Num 3", "Num Enter", //17
+ "Left Ctrl", "Left Win", "Left Alt", "Space", "Right Alt", "Fn", "LeftCtrl", "Left Arrow", "Down Arrow", "Right Arrow", "Num 0", "Num .", //12
+];
+
+const vKeyPositions = [
+ [0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0] , [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [16, 0], [17, 0], [18, 0], //19
+ [0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1], [9, 1] , [10, 1], [11, 1], [12, 1], [13, 1], [15, 1], [16, 1], [17, 1], [18, 1], //18
+ [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2] , [10, 2], [11, 2], [12, 2], [14, 2], [15, 2], [16, 2], [17, 2], [18, 2], //18
+ [0, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [14, 3], [15, 3], [16, 3], [17, 3], //16
+ [0, 4], [2, 4], [3, 4], [4, 4], [5, 4], [6, 4], [7, 4], [8, 4], [9, 4], [10, 4], [11, 4], [13, 4], [14, 4], [15, 4], [16, 4], [17, 4], [18, 4], //17
+ [0, 5], [2, 5], [3, 5], [7, 5], [10, 5], [11, 5], [12, 5], [13, 5], [14, 5], [15, 5], [16, 5], [17, 5], //12
+];
+
+let LEDCount = 0;
+let IsViaKeyboard = false;
+const MainlineQMKFirmware = 1;
+const VIAFirmware = 2;
+const PluginProtocolVersion = "1.0.6";
+
+export function LedNames() {
+ return vKeyNames;
+}
+
+export function LedPositions() {
+ return vKeyPositions;
+}
+
+export function vKeysArrayCount() {
+ device.log('vKeys ' + vKeys.length);
+ device.log('vKeyNames ' + vKeyNames.length);
+ device.log('vKeyPositions ' + vKeyPositions.length);
+}
+
+export function Initialize() {
+ requestFirmwareType();
+ requestQMKVersion();
+ requestSignalRGBProtocolVersion();
+ requestUniqueIdentifier();
+ requestTotalLeds();
+ effectEnable();
+
+}
+
+export function Render() {
+ sendColors();
+}
+
+export function Shutdown(SystemSuspending) {
+
+ if(SystemSuspending) {
+ sendColors("#000000"); // Go Dark on System Sleep/Shutdown
+ } else {
+ if (shutdownMode === "SignalRGB") {
+ sendColors(shutdownColor);
+ } else {
+ effectDisable();
+ }
+ }
+
+ vKeysArrayCount(); // For debugging array counts
+
+}
+
+function commandHandler() {
+ const readCounts = [];
+
+ do {
+ const returnpacket = device.read([0x00], 32, 10);
+ processCommands(returnpacket);
+
+ readCounts.push(device.getLastReadSize());
+
+ // Extra Read to throw away empty packets from Via
+ // Via always sends a second packet with the same Command Id.
+ if(IsViaKeyboard) {
+ device.read([0x00], 32, 10);
+ }
+ }
+ while(device.getLastReadSize() > 0);
+
+}
+
+function processCommands(data) {
+ switch(data[1]) {
+ case 0x21:
+ returnQMKVersion(data);
+ break;
+ case 0x22:
+ returnSignalRGBProtocolVersion(data);
+ break;
+ case 0x23:
+ returnUniqueIdentifier(data);
+ break;
+ case 0x24:
+ sendColors();
+ break;
+ case 0x27:
+ returnTotalLeds(data);
+ break;
+ case 0x28:
+ returnFirmwareType(data);
+ break;
+ }
+}
+
+function requestQMKVersion() //Check the version of QMK Firmware that the keyboard is running
+{
+ device.write([0x00, 0x21], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnQMKVersion(data) {
+ const QMKVersionByte1 = data[2];
+ const QMKVersionByte2 = data[3];
+ const QMKVersionByte3 = data[4];
+ device.log("QMK Version: " + QMKVersionByte1 + "." + QMKVersionByte2 + "." + QMKVersionByte3);
+ device.log("QMK SRGB Plugin Version: "+ Version());
+ device.pause(30);
+}
+
+function requestSignalRGBProtocolVersion() //Grab the version of the SignalRGB Protocol the keyboard is running
+{
+ device.write([0x00, 0x22], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnSignalRGBProtocolVersion(data) {
+ const ProtocolVersionByte1 = data[2];
+ const ProtocolVersionByte2 = data[3];
+ const ProtocolVersionByte3 = data[4];
+
+ const SignalRGBProtocolVersion = ProtocolVersionByte1 + "." + ProtocolVersionByte2 + "." + ProtocolVersionByte3;
+ device.log(`SignalRGB Protocol Version: ${SignalRGBProtocolVersion}`);
+
+
+ if(PluginProtocolVersion !== SignalRGBProtocolVersion) {
+ device.notify("Unsupported Protocol Version", `This plugin is intended for SignalRGB Protocol version ${PluginProtocolVersion}. This device is version: ${SignalRGBProtocolVersion}`, 2, "Documentation");
+ }
+
+ device.pause(30);
+}
+
+function requestUniqueIdentifier() //Grab the unique identifier for this keyboard model
+{
+ if(device.write([0x00, 0x23], 32) === -1) {
+ device.notify("Unsupported Firmware", "This device is not running SignalRGB-compatible firmware. Click the Documentation button to learn more.", 3, "Documentation");
+ }
+
+ device.pause(30);
+ commandHandler();
+}
+
+
+function returnUniqueIdentifier(data) {
+ const UniqueIdentifierByte1 = data[2];
+ const UniqueIdentifierByte2 = data[3];
+ const UniqueIdentifierByte3 = data[4];
+
+ if(!(UniqueIdentifierByte1 === 0 && UniqueIdentifierByte2 === 0 && UniqueIdentifierByte3 === 0)) {
+ device.log("Unique Device Identifier: " + UniqueIdentifierByte1 + UniqueIdentifierByte2 + UniqueIdentifierByte3);
+ }
+
+ device.pause(30);
+}
+
+function requestTotalLeds() //Calculate total number of LEDs
+{
+ device.write([0x00, 0x27], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnTotalLeds(data) {
+ LEDCount = data[2];
+ device.log("Device Total LED Count: " + LEDCount);
+ device.pause(30);
+}
+
+function requestFirmwareType() {
+ device.write([0x00, 0x28], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnFirmwareType(data) {
+ const FirmwareTypeByte = data[2];
+
+ if(!(FirmwareTypeByte === MainlineQMKFirmware || FirmwareTypeByte === VIAFirmware)) {
+ device.notify("Unsupported Firmware", "Click the Documentation button to learn more.", 3, "Documentation");
+ }
+
+ if(FirmwareTypeByte === MainlineQMKFirmware) {
+ IsViaKeyboard = false;
+ device.log("Firmware Type: Mainline");
+ }
+
+ if(FirmwareTypeByte === VIAFirmware) {
+ IsViaKeyboard = true;
+ device.log("Firmware Type: VIA");
+ }
+
+ device.pause(30);
+}
+
+function effectEnable() //Enable the SignalRGB Effect Mode
+{
+ device.write([0x00, 0x25], 32);
+ device.pause(30);
+}
+
+function effectDisable() //Revert to Hardware Mode
+{
+ device.write([0x00, 0x26], 32);
+ device.pause(30);
+}
+
+function createSolidColorArray(color) {
+ const rgbdata = new Array(vKeys.length * 3).fill(0);
+
+ for(let iIdx = 0; iIdx < vKeys.length; iIdx++) {
+ const iLedIdx = vKeys[iIdx] * 3;
+ rgbdata[iLedIdx] = color[0];
+ rgbdata[iLedIdx+1] = color[1];
+ rgbdata[iLedIdx+2] = color[2];
+ }
+
+ return rgbdata;
+}
+
+function grabColors(overrideColor) {
+ if(overrideColor) {
+ return createSolidColorArray(hexToRgb(overrideColor));
+ } else if (LightingMode === "Forced") {
+ return createSolidColorArray(hexToRgb(forcedColor));
+ }
+
+ const rgbdata = new Array(vKeys.length * 3).fill(0);
+
+ for(let iIdx = 0; iIdx < vKeys.length; iIdx++) {
+ const iPxX = vKeyPositions[iIdx][0];
+ const iPxY = vKeyPositions[iIdx][1];
+ const color = device.color(iPxX, iPxY);
+
+ const iLedIdx = vKeys[iIdx] * 3;
+ rgbdata[iLedIdx] = color[0];
+ rgbdata[iLedIdx+1] = color[1];
+ rgbdata[iLedIdx+2] = color[2];
+ }
+
+ return rgbdata;
+}
+
+function sendColors(overrideColor) {
+ const rgbdata = grabColors(overrideColor);
+
+ const LedsPerPacket = 9;
+ let BytesSent = 0;
+ let BytesLeft = rgbdata.length;
+
+ while(BytesLeft > 0) {
+ const BytesToSend = Math.min(LedsPerPacket * 3, BytesLeft);
+ StreamLightingData(Math.floor(BytesSent / 3), rgbdata.splice(0, BytesToSend));
+
+ BytesLeft -= BytesToSend;
+ BytesSent += BytesToSend;
+ }
+}
+
+function StreamLightingData(StartLedIdx, RGBData) {
+ const packet = [0x00, 0x24, StartLedIdx, Math.floor(RGBData.length / 3)].concat(RGBData);
+ device.write(packet, 33);
+}
+
+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 === 1;
+}
\ No newline at end of file
From 7bb7333f38e3a48da876632942f3e4119a4c0a7e Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 16:25:12 +0800
Subject: [PATCH 05/34] Update readme.md.
---
readme.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/readme.md b/readme.md
index f0e49a08e956..a0b07d7c833e 100644
--- a/readme.md
+++ b/readme.md
@@ -1,3 +1,11 @@
+# Forked from nuphy-src/qmk_firmware
+
+## improvements:
+
+1. Added SignalRGB support for Nuphy Keyboards using qmk firmware.
+2. Fixed some keymapping errors in nuphy keyboard plugin for Air96v2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugin is saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
+
+
# Quantum Mechanical Keyboard Firmware
[](https://github.com/qmk/qmk_firmware/tags)
From 5e4227c0b55786c1d4e114948677e9b40c749c75 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 16:32:40 +0800
Subject: [PATCH 06/34] Update readme.md.
---
readme.md | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index a0b07d7c833e..d54312d912c1 100644
--- a/readme.md
+++ b/readme.md
@@ -1,10 +1,16 @@
-# Forked from nuphy-src/qmk_firmware
+# Project forked from nuphy-src/qmk_firmware
## improvements:
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware.
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96v2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugin is saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
+## Note: SignalRGB / VIA Issue
+(From [document](https://docs.signalrgb.com/qmk) provided by SignalRGB)
+
+Please note that SignalRGB and VIA do not happily run at the same time. You must quit either VIA (or close the browser tab) before running SignalRGB, or close SignalRGB before attempting to use VIA as the raw_hid_recieve solution that both Software(s) use conflict with each other.
+
+---
# Quantum Mechanical Keyboard Firmware
From c8483b71fcbbdc5893dbbf1e022ff4d1800f040e Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 16:56:47 +0800
Subject: [PATCH 07/34] Update readme.md.
---
readme.md | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/readme.md b/readme.md
index d54312d912c1..f0e49a08e956 100644
--- a/readme.md
+++ b/readme.md
@@ -1,17 +1,3 @@
-# Project forked from nuphy-src/qmk_firmware
-
-## improvements:
-
-1. Added SignalRGB support for Nuphy Keyboards using qmk firmware.
-2. Fixed some keymapping errors in nuphy keyboard plugin for Air96v2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugin is saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
-
-## Note: SignalRGB / VIA Issue
-(From [document](https://docs.signalrgb.com/qmk) provided by SignalRGB)
-
-Please note that SignalRGB and VIA do not happily run at the same time. You must quit either VIA (or close the browser tab) before running SignalRGB, or close SignalRGB before attempting to use VIA as the raw_hid_recieve solution that both Software(s) use conflict with each other.
-
----
-
# Quantum Mechanical Keyboard Firmware
[](https://github.com/qmk/qmk_firmware/tags)
From 620903133733b00a56b5f367332a6c010ec5cdbb Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 17:01:12 +0800
Subject: [PATCH 08/34] Update readme.md.
---
readme.md | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/readme.md b/readme.md
index f0e49a08e956..f5bd9a391ee0 100644
--- a/readme.md
+++ b/readme.md
@@ -1,3 +1,16 @@
+# Project forked from nuphy-src/qmk_firmware
+
+## improvements:
+
+1. Added SignalRGB support for Nuphy Keyboards using qmk firmware.
+2. Fixed some keymapping errors in nuphy keyboard plugin for Air96v2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugin is saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
+
+## Note: SignalRGB / VIA Issue
+(From [document](https://docs.signalrgb.com/qmk) provided by SignalRGB)
+
+Please note that SignalRGB and VIA do not happily run at the same time. You must quit either VIA (or close the browser tab) before running SignalRGB, or close SignalRGB before attempting to use VIA as the raw_hid_recieve solution that both Software(s) use conflict with each other.
+
+---
# Quantum Mechanical Keyboard Firmware
[](https://github.com/qmk/qmk_firmware/tags)
From 0905c133f64d20fb14e95b58be8cd9dd84141477 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 17:37:49 +0800
Subject: [PATCH 09/34] Add SignalRGB plugin for Air60v2.
---
.../NuPhy_Air60v2_QMK_ANSI_Keyboard.js | 332 ++++++++++++++++++
1 file changed, 332 insertions(+)
create mode 100644 SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
diff --git a/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
new file mode 100644
index 000000000000..8454c5256e02
--- /dev/null
+++ b/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
@@ -0,0 +1,332 @@
+export function Name() { return "NuPhy Air60 V2 QMK Keyboard"; }
+export function Version() { return "1.1.9"; }
+export function VendorId() { return 0x19f5; }
+export function ProductId() { return 0x3255; }
+export function Publisher() { return "ZZM"; }
+export function Documentation() { return "qmk/srgbmods-qmk-firmware"; }
+export function DeviceType() { return "keyboard"; }
+export function Size() { return [16, 6]; }
+export function DefaultPosition(){return [10, 100]; }
+export function DefaultScale(){return 8.0;}
+/* global
+shutdownMode:readonly
+shutdownColor:readonly
+LightingMode:readonly
+forcedColor:readonly
+*/
+export function ControllableParameters() {
+ return [
+ {"property":"shutdownMode", "group":"lighting", "label":"Shutdown Mode", "type":"combobox", "values":["SignalRGB", "Hardware"], "default":"SignalRGB"},
+ {"property":"shutdownColor", "group":"lighting", "label":"Shutdown Color", "min":"0", "max":"360", "type":"color", "default":"#000000"},
+ {"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"},
+ ];
+}
+
+//Plugin Version: Built for Protocol V1.0.6
+
+const vKeys = [
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, //14
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, //14
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, //14
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, //14
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, //14
+ 69, 70, 71, 72, 73, 74, 75, 76, 77, //9
+];
+
+const vKeyNames = [
+ "Esc", "!1", "@2", "#3", "$4", "%5", "^6", "&7", "*8", "(9", ")0", "_-", "+=", "Backspace", //14
+ "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\", //14
+ "CapsLock", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter", //14
+ "Left Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "Right Shift", "Up Arrow", "Del", //14
+ "Left Ctrl", "Opt", "Cmd", "Space", "Right Cmd", "Fn", "Left Arrow", "Down Arrow", "Right Arrow", //9
+];
+
+const vKeyPositions = [
+ [0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0], [13, 0], //14
+ [0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1], [9, 1], [10, 1], [11, 1], [12, 1], [13, 1], //14
+ [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2], [10, 2], [11, 2], [12, 2], [13, 2], //14
+ [0, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [13, 3], //14
+ [0, 4], [1, 4], [2, 4], [6, 4], [9, 4], [10, 4], [11, 4], [12, 4], [13, 4], //9
+];
+
+let LEDCount = 0;
+let IsViaKeyboard = false;
+const MainlineQMKFirmware = 1;
+const VIAFirmware = 2;
+const PluginProtocolVersion = "1.0.6";
+
+export function LedNames() {
+ return vKeyNames;
+}
+
+export function LedPositions() {
+ return vKeyPositions;
+}
+
+export function vKeysArrayCount() {
+ device.log('vKeys ' + vKeys.length);
+ device.log('vKeyNames ' + vKeyNames.length);
+ device.log('vKeyPositions ' + vKeyPositions.length);
+}
+
+export function Initialize() {
+ requestFirmwareType();
+ requestQMKVersion();
+ requestSignalRGBProtocolVersion();
+ requestUniqueIdentifier();
+ requestTotalLeds();
+ effectEnable();
+
+}
+
+export function Render() {
+ sendColors();
+}
+
+export function Shutdown(SystemSuspending) {
+
+ if(SystemSuspending) {
+ sendColors("#000000"); // Go Dark on System Sleep/Shutdown
+ } else {
+ if (shutdownMode === "SignalRGB") {
+ sendColors(shutdownColor);
+ } else {
+ effectDisable();
+ }
+ }
+
+ //vKeysArrayCount(); // For debugging array counts
+
+}
+
+function commandHandler() {
+ const readCounts = [];
+
+ do {
+ const returnpacket = device.read([0x00], 32, 10);
+ processCommands(returnpacket);
+
+ readCounts.push(device.getLastReadSize());
+
+ // Extra Read to throw away empty packets from Via
+ // Via always sends a second packet with the same Command Id.
+ if(IsViaKeyboard) {
+ device.read([0x00], 32, 10);
+ }
+ }
+ while(device.getLastReadSize() > 0);
+
+}
+
+function processCommands(data) {
+ switch(data[1]) {
+ case 0x21:
+ returnQMKVersion(data);
+ break;
+ case 0x22:
+ returnSignalRGBProtocolVersion(data);
+ break;
+ case 0x23:
+ returnUniqueIdentifier(data);
+ break;
+ case 0x24:
+ sendColors();
+ break;
+ case 0x27:
+ returnTotalLeds(data);
+ break;
+ case 0x28:
+ returnFirmwareType(data);
+ break;
+ }
+}
+
+function requestQMKVersion() //Check the version of QMK Firmware that the keyboard is running
+{
+ device.write([0x00, 0x21], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnQMKVersion(data) {
+ const QMKVersionByte1 = data[2];
+ const QMKVersionByte2 = data[3];
+ const QMKVersionByte3 = data[4];
+ device.log("QMK Version: " + QMKVersionByte1 + "." + QMKVersionByte2 + "." + QMKVersionByte3);
+ device.log("QMK SRGB Plugin Version: "+ Version());
+ device.pause(30);
+}
+
+function requestSignalRGBProtocolVersion() //Grab the version of the SignalRGB Protocol the keyboard is running
+{
+ device.write([0x00, 0x22], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnSignalRGBProtocolVersion(data) {
+ const ProtocolVersionByte1 = data[2];
+ const ProtocolVersionByte2 = data[3];
+ const ProtocolVersionByte3 = data[4];
+
+ const SignalRGBProtocolVersion = ProtocolVersionByte1 + "." + ProtocolVersionByte2 + "." + ProtocolVersionByte3;
+ device.log(`SignalRGB Protocol Version: ${SignalRGBProtocolVersion}`);
+
+
+ if(PluginProtocolVersion !== SignalRGBProtocolVersion) {
+ device.notify("Unsupported Protocol Version", `This plugin is intended for SignalRGB Protocol version ${PluginProtocolVersion}. This device is version: ${SignalRGBProtocolVersion}`, 2, "Documentation");
+ }
+
+ device.pause(30);
+}
+
+function requestUniqueIdentifier() //Grab the unique identifier for this keyboard model
+{
+ if(device.write([0x00, 0x23], 32) === -1) {
+ device.notify("Unsupported Firmware", "This device is not running SignalRGB-compatible firmware. Click the Documentation button to learn more.", 3, "Documentation");
+ }
+
+ device.pause(30);
+ commandHandler();
+}
+
+
+function returnUniqueIdentifier(data) {
+ const UniqueIdentifierByte1 = data[2];
+ const UniqueIdentifierByte2 = data[3];
+ const UniqueIdentifierByte3 = data[4];
+
+ if(!(UniqueIdentifierByte1 === 0 && UniqueIdentifierByte2 === 0 && UniqueIdentifierByte3 === 0)) {
+ device.log("Unique Device Identifier: " + UniqueIdentifierByte1 + UniqueIdentifierByte2 + UniqueIdentifierByte3);
+ }
+
+ device.pause(30);
+}
+
+function requestTotalLeds() //Calculate total number of LEDs
+{
+ device.write([0x00, 0x27], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnTotalLeds(data) {
+ LEDCount = data[2];
+ device.log("Device Total LED Count: " + LEDCount);
+ device.pause(30);
+}
+
+function requestFirmwareType() {
+ device.write([0x00, 0x28], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnFirmwareType(data) {
+ const FirmwareTypeByte = data[2];
+
+ if(!(FirmwareTypeByte === MainlineQMKFirmware || FirmwareTypeByte === VIAFirmware)) {
+ device.notify("Unsupported Firmware", "Click the Documentation button to learn more.", 3, "Documentation");
+ }
+
+ if(FirmwareTypeByte === MainlineQMKFirmware) {
+ IsViaKeyboard = false;
+ device.log("Firmware Type: Mainline");
+ }
+
+ if(FirmwareTypeByte === VIAFirmware) {
+ IsViaKeyboard = true;
+ device.log("Firmware Type: VIA");
+ }
+
+ device.pause(30);
+}
+
+function effectEnable() //Enable the SignalRGB Effect Mode
+{
+ device.write([0x00, 0x25], 32);
+ device.pause(30);
+}
+
+function effectDisable() //Revert to Hardware Mode
+{
+ device.write([0x00, 0x26], 32);
+ device.pause(30);
+}
+
+function createSolidColorArray(color) {
+ const rgbdata = new Array(vKeys.length * 3).fill(0);
+
+ for(let iIdx = 0; iIdx < vKeys.length; iIdx++) {
+ const iLedIdx = vKeys[iIdx] * 3;
+ rgbdata[iLedIdx] = color[0];
+ rgbdata[iLedIdx+1] = color[1];
+ rgbdata[iLedIdx+2] = color[2];
+ }
+
+ return rgbdata;
+}
+
+function grabColors(overrideColor) {
+ if(overrideColor) {
+ return createSolidColorArray(hexToRgb(overrideColor));
+ } else if (LightingMode === "Forced") {
+ return createSolidColorArray(hexToRgb(forcedColor));
+ }
+
+ const rgbdata = new Array(vKeys.length * 3).fill(0);
+
+ for(let iIdx = 0; iIdx < vKeys.length; iIdx++) {
+ const iPxX = vKeyPositions[iIdx][0];
+ const iPxY = vKeyPositions[iIdx][1];
+ const color = device.color(iPxX, iPxY);
+
+ const iLedIdx = vKeys[iIdx] * 3;
+ rgbdata[iLedIdx] = color[0];
+ rgbdata[iLedIdx+1] = color[1];
+ rgbdata[iLedIdx+2] = color[2];
+ }
+
+ return rgbdata;
+}
+
+function sendColors(overrideColor) {
+ const rgbdata = grabColors(overrideColor);
+
+ const LedsPerPacket = 9;
+ let BytesSent = 0;
+ let BytesLeft = rgbdata.length;
+
+ while(BytesLeft > 0) {
+ const BytesToSend = Math.min(LedsPerPacket * 3, BytesLeft);
+ StreamLightingData(Math.floor(BytesSent / 3), rgbdata.splice(0, BytesToSend));
+
+ BytesLeft -= BytesToSend;
+ BytesSent += BytesToSend;
+ }
+}
+
+function StreamLightingData(StartLedIdx, RGBData) {
+ const packet = [0x00, 0x24, StartLedIdx, Math.floor(RGBData.length / 3)].concat(RGBData);
+ device.write(packet, 33);
+}
+
+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 === 1;
+}
+
+export function ImageUrl()
+{
+ return "https://raw.githubusercontent.com/SRGBmods/QMK-Images/main/images/NuPhy_Air75v2.png";
+}
\ No newline at end of file
From 839ae0b63fbe095808cf1d008dc7794f5ed36c22 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 17:39:45 +0800
Subject: [PATCH 10/34] Update readme.md.
---
readme.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index f5bd9a391ee0..5a53c2b65ef5 100644
--- a/readme.md
+++ b/readme.md
@@ -3,7 +3,8 @@
## improvements:
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware.
-2. Fixed some keymapping errors in nuphy keyboard plugin for Air96v2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugin is saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
+2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 v2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugin is saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
+3. Add SignalRGB plugin for Air60 v2.
## Note: SignalRGB / VIA Issue
(From [document](https://docs.signalrgb.com/qmk) provided by SignalRGB)
From abaf699be94447ef8b8669d32d71be310bbbcd32 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 17:43:03 +0800
Subject: [PATCH 11/34] Add SignalRGB plugin for Air60v2.
---
SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
index 8454c5256e02..b8acf486cc22 100644
--- a/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
+++ b/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
@@ -29,16 +29,15 @@ const vKeys = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, //14
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, //14
28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, //14
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, //14
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, //14
- 69, 70, 71, 72, 73, 74, 75, 76, 77, //9
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, //13
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, //9
];
const vKeyNames = [
"Esc", "!1", "@2", "#3", "$4", "%5", "^6", "&7", "*8", "(9", ")0", "_-", "+=", "Backspace", //14
"Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\", //14
"CapsLock", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter", //14
- "Left Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "Right Shift", "Up Arrow", "Del", //14
+ "Left Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "Right Shift", "Up Arrow", "Del", //13
"Left Ctrl", "Opt", "Cmd", "Space", "Right Cmd", "Fn", "Left Arrow", "Down Arrow", "Right Arrow", //9
];
@@ -46,7 +45,7 @@ const vKeyPositions = [
[0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0], [13, 0], //14
[0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1], [9, 1], [10, 1], [11, 1], [12, 1], [13, 1], //14
[0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2], [10, 2], [11, 2], [12, 2], [13, 2], //14
- [0, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [13, 3], //14
+ [0, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [13, 3], //13
[0, 4], [1, 4], [2, 4], [6, 4], [9, 4], [10, 4], [11, 4], [12, 4], [13, 4], //9
];
From c5cc212e363b42b9c235611eb69b24966ee49f33 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 17:54:11 +0800
Subject: [PATCH 12/34] Add SignalRGB plugin for Air60v2.
---
SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
index b8acf486cc22..7fc59f618ac3 100644
--- a/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
+++ b/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
@@ -28,24 +28,24 @@ export function ControllableParameters() {
const vKeys = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, //14
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, //14
- 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, //14
- 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, //13
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //13
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, //14
55, 56, 57, 58, 59, 60, 61, 62, 63, //9
];
const vKeyNames = [
"Esc", "!1", "@2", "#3", "$4", "%5", "^6", "&7", "*8", "(9", ")0", "_-", "+=", "Backspace", //14
"Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\", //14
- "CapsLock", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter", //14
- "Left Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "Right Shift", "Up Arrow", "Del", //13
+ "CapsLock", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter", //13
+ "Left Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "Right Shift", "Up Arrow", "Del", //14
"Left Ctrl", "Opt", "Cmd", "Space", "Right Cmd", "Fn", "Left Arrow", "Down Arrow", "Right Arrow", //9
];
const vKeyPositions = [
[0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0], [13, 0], //14
[0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1], [9, 1], [10, 1], [11, 1], [12, 1], [13, 1], //14
- [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2], [10, 2], [11, 2], [12, 2], [13, 2], //14
- [0, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [13, 3], //13
+ [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2], [10, 2], [11, 2], [12, 2], //13
+ [0, 3], [1, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [13, 3], //14
[0, 4], [1, 4], [2, 4], [6, 4], [9, 4], [10, 4], [11, 4], [12, 4], [13, 4], //9
];
From e3da87fed45cbd6de95c67925ae39c037249fcfc Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 17:56:17 +0800
Subject: [PATCH 13/34] Update SignalRGB plugin for Air96v2.
---
SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
index db66c7950c14..c0428abd00d5 100644
--- a/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
+++ b/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
@@ -2,7 +2,7 @@ export function Name() { return "NuPhy Air96 v2 ANSI QMK Keyboard"; }
export function Version() { return "1.1.9"; }
export function VendorId() { return 0x19F5; }
export function ProductId() { return 0x3266; }
-export function Publisher() { return "WhirlwindFX"; }
+export function Publisher() { return "ZZM"; }
export function Documentation() { return "qmk/srgbmods-qmk-firmware"; }
export function DeviceType() { return "keyboard"; }
export function Size() { return [19, 6]; }
From 9810a64f92c1523c43326b0f0b33e11b04ce05e0 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Thu, 13 Mar 2025 22:04:56 +0800
Subject: [PATCH 14/34] Update SignalRGB plugin keymap
---
SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js | 2 +-
SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js | 12 ++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
index 7fc59f618ac3..c798a5c8ce12 100644
--- a/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
+++ b/SRGB_qmk_plugins/NuPhy_Air60v2_QMK_ANSI_Keyboard.js
@@ -5,7 +5,7 @@ export function ProductId() { return 0x3255; }
export function Publisher() { return "ZZM"; }
export function Documentation() { return "qmk/srgbmods-qmk-firmware"; }
export function DeviceType() { return "keyboard"; }
-export function Size() { return [16, 6]; }
+export function Size() { return [14, 5]; }
export function DefaultPosition(){return [10, 100]; }
export function DefaultScale(){return 8.0;}
/* global
diff --git a/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
index c0428abd00d5..78f72513e10b 100644
--- a/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
+++ b/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
@@ -44,12 +44,12 @@ const vKeyNames = [
];
const vKeyPositions = [
- [0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0] , [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [16, 0], [17, 0], [18, 0], //19
- [0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1], [9, 1] , [10, 1], [11, 1], [12, 1], [13, 1], [15, 1], [16, 1], [17, 1], [18, 1], //18
- [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2] , [10, 2], [11, 2], [12, 2], [14, 2], [15, 2], [16, 2], [17, 2], [18, 2], //18
- [0, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [14, 3], [15, 3], [16, 3], [17, 3], //16
- [0, 4], [2, 4], [3, 4], [4, 4], [5, 4], [6, 4], [7, 4], [8, 4], [9, 4], [10, 4], [11, 4], [13, 4], [14, 4], [15, 4], [16, 4], [17, 4], [18, 4], //17
- [0, 5], [2, 5], [3, 5], [7, 5], [10, 5], [11, 5], [12, 5], [13, 5], [14, 5], [15, 5], [16, 5], [17, 5], //12
+ [0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [16, 0], [17, 0], [18, 0], //19
+ [0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1], [9, 1], [10, 1], [11, 1], [12, 1], [13, 1], [15, 1], [16, 1], [17, 1], [18, 1], //18
+ [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2], [10, 2], [11, 2], [12, 2], [14, 2], [15, 2], [16, 2], [17, 2], [18, 2], //18
+ [0, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [14, 3], [15, 3], [16, 3], [17, 3], //16
+ [0, 4], [2, 4], [3, 4], [4, 4], [5, 4], [6, 4], [7, 4], [8, 4], [9, 4], [10, 4], [11, 4], [13, 4], [14, 4], [15, 4], [16, 4], [17, 4], [18, 4], //17
+ [0, 5], [2, 5], [3, 5], [7, 5], [10, 5], [11, 5], [12, 5], [13, 5], [14, 5], [15, 5], [16, 5], [17, 5], //12
];
let LEDCount = 0;
From 303713ee6d0560ef3824f05fbd8f2b6db35395ac Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 17:37:18 +0800
Subject: [PATCH 15/34] Update SignalRGB plugin keymap
---
.../NuPhy_Air75v2_QMK_ANSI_Keyboard.js | 334 ++++++++++++++++++
.../NuPhy_Air96v2_QMK_ANSI_Keyboard.js | 14 +-
2 files changed, 341 insertions(+), 7 deletions(-)
create mode 100644 SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
diff --git a/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
new file mode 100644
index 000000000000..ea9cf60de50e
--- /dev/null
+++ b/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
@@ -0,0 +1,334 @@
+export function Name() { return "NuPhy Air75 V2 QMK ANSI Keyboard"; }
+export function Version() { return "1.1.9"; }
+export function VendorId() { return 0x19f5; }
+export function ProductId() { return 0x3246; }
+export function Publisher() { return "ZZM"; }
+export function Documentation() { return "qmk/srgbmods-qmk-firmware"; }
+export function DeviceType() { return "keyboard"; }
+export function Size() { return [61, 6]; }
+export function DefaultPosition(){return [10, 100]; }
+export function DefaultScale(){return 8.0;}
+/* global
+shutdownMode:readonly
+shutdownColor:readonly
+LightingMode:readonly
+forcedColor:readonly
+*/
+export function ControllableParameters() {
+ return [
+ {"property":"shutdownMode", "group":"lighting", "label":"Shutdown Mode", "type":"combobox", "values":["SignalRGB", "Hardware"], "default":"SignalRGB"},
+ {"property":"shutdownColor", "group":"lighting", "label":"Shutdown Color", "min":"0", "max":"360", "type":"color", "default":"#000000"},
+ {"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"},
+ ];
+}
+
+//Plugin Version: Built for Protocol V1.0.6
+
+const vKeys = [
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, //16
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, //15
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, //15
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, //14
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, //14
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 //10
+];
+
+const vKeyNames = [
+ "Esc", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "Print Screen", "Insert", "Del", //16
+ "`", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "+", "Backspace", "Page Up", //15
+ "Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "[", "]", "\\", "Page Down", //15
+ "CapsLock", "A", "S", "D", "F", "G", "H", "J", "K", "L", ";", "'", "Enter", "Home", //14
+ "Left Shift", "Z", "X", "C", "V", "B", "N", "M", ",", ".", "/", "Right Shift", "Up Arrow", "End", //14
+ "Left Ctrl", "Left Win", "Left Alt", "Space", "Right Alt", "Fn", "Right Ctrl", "Left Arrow", "Down Arrow", "Right Arrow", //10
+];
+
+const vKeyPositions = [
+ [ 0, 0], [ 4, 0], [ 8, 0], [12, 0], [16, 0], [20, 0], [24, 0], [28, 0], [32, 0], [36, 0], [40, 0], [44, 0], [48, 0], [52, 0], [56, 0], [60, 0], //16
+ [ 0, 1], [ 4, 1], [ 8, 1], [12, 1], [16, 1], [20, 1], [24, 1], [28, 1], [32, 1], [36, 1], [40, 1], [44, 1], [48, 1], [54, 1], [60, 1], //15
+ [ 0, 2], [ 6, 2], [10, 2], [14, 2], [18, 2], [22, 2], [26, 2], [30, 2], [34, 2], [38, 2], [42, 2], [46, 2], [50, 2], [55, 2], [60, 2], //15
+ [ 0, 3], [ 7, 3], [11, 3], [15, 3], [19, 3], [23, 3], [27, 3], [31, 3], [35, 3], [39, 3], [43, 3], [47, 3], [53, 3], [60, 3], //14
+ [ 0, 4], [ 9, 4], [13, 4], [17, 4], [21, 4], [25, 4], [29, 4], [33, 4], [37, 4], [41, 4], [45, 4], [51, 4], [56, 4], [60, 4], //14
+ [ 0, 5], [ 5, 5], [ 10, 5], [26, 5], [40, 5], [44, 5], [48, 5], [52, 5], [56, 5], [60, 5], //10
+];
+
+let LEDCount = 0;
+let IsViaKeyboard = false;
+const MainlineQMKFirmware = 1;
+const VIAFirmware = 2;
+const PluginProtocolVersion = "1.0.6";
+
+export function LedNames() {
+ return vKeyNames;
+}
+
+export function LedPositions() {
+ return vKeyPositions;
+}
+
+export function vKeysArrayCount() {
+ device.log('vKeys ' + vKeys.length);
+ device.log('vKeyNames ' + vKeyNames.length);
+ device.log('vKeyPositions ' + vKeyPositions.length);
+}
+
+export function Initialize() {
+ requestFirmwareType();
+ requestQMKVersion();
+ requestSignalRGBProtocolVersion();
+ requestUniqueIdentifier();
+ requestTotalLeds();
+ effectEnable();
+
+}
+
+export function Render() {
+ sendColors();
+}
+
+export function Shutdown(SystemSuspending) {
+
+ if(SystemSuspending) {
+ sendColors("#000000"); // Go Dark on System Sleep/Shutdown
+ } else {
+ if (shutdownMode === "SignalRGB") {
+ sendColors(shutdownColor);
+ } else {
+ effectDisable();
+ }
+ }
+
+ //vKeysArrayCount(); // For debugging array counts
+
+}
+
+function commandHandler() {
+ const readCounts = [];
+
+ do {
+ const returnpacket = device.read([0x00], 32, 10);
+ processCommands(returnpacket);
+
+ readCounts.push(device.getLastReadSize());
+
+ // Extra Read to throw away empty packets from Via
+ // Via always sends a second packet with the same Command Id.
+ if(IsViaKeyboard) {
+ device.read([0x00], 32, 10);
+ }
+ }
+ while(device.getLastReadSize() > 0);
+
+}
+
+function processCommands(data) {
+ switch(data[1]) {
+ case 0x21:
+ returnQMKVersion(data);
+ break;
+ case 0x22:
+ returnSignalRGBProtocolVersion(data);
+ break;
+ case 0x23:
+ returnUniqueIdentifier(data);
+ break;
+ case 0x24:
+ sendColors();
+ break;
+ case 0x27:
+ returnTotalLeds(data);
+ break;
+ case 0x28:
+ returnFirmwareType(data);
+ break;
+ }
+}
+
+function requestQMKVersion() //Check the version of QMK Firmware that the keyboard is running
+{
+ device.write([0x00, 0x21], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnQMKVersion(data) {
+ const QMKVersionByte1 = data[2];
+ const QMKVersionByte2 = data[3];
+ const QMKVersionByte3 = data[4];
+ device.log("QMK Version: " + QMKVersionByte1 + "." + QMKVersionByte2 + "." + QMKVersionByte3);
+ device.log("QMK SRGB Plugin Version: "+ Version());
+ device.pause(30);
+}
+
+function requestSignalRGBProtocolVersion() //Grab the version of the SignalRGB Protocol the keyboard is running
+{
+ device.write([0x00, 0x22], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnSignalRGBProtocolVersion(data) {
+ const ProtocolVersionByte1 = data[2];
+ const ProtocolVersionByte2 = data[3];
+ const ProtocolVersionByte3 = data[4];
+
+ const SignalRGBProtocolVersion = ProtocolVersionByte1 + "." + ProtocolVersionByte2 + "." + ProtocolVersionByte3;
+ device.log(`SignalRGB Protocol Version: ${SignalRGBProtocolVersion}`);
+
+
+ if(PluginProtocolVersion !== SignalRGBProtocolVersion) {
+ device.notify("Unsupported Protocol Version", `This plugin is intended for SignalRGB Protocol version ${PluginProtocolVersion}. This device is version: ${SignalRGBProtocolVersion}`, 2, "Documentation");
+ }
+
+ device.pause(30);
+}
+
+function requestUniqueIdentifier() //Grab the unique identifier for this keyboard model
+{
+ if(device.write([0x00, 0x23], 32) === -1) {
+ device.notify("Unsupported Firmware", "This device is not running SignalRGB-compatible firmware. Click the Documentation button to learn more.", 3, "Documentation");
+ }
+
+ device.pause(30);
+ commandHandler();
+}
+
+
+function returnUniqueIdentifier(data) {
+ const UniqueIdentifierByte1 = data[2];
+ const UniqueIdentifierByte2 = data[3];
+ const UniqueIdentifierByte3 = data[4];
+
+ if(!(UniqueIdentifierByte1 === 0 && UniqueIdentifierByte2 === 0 && UniqueIdentifierByte3 === 0)) {
+ device.log("Unique Device Identifier: " + UniqueIdentifierByte1 + UniqueIdentifierByte2 + UniqueIdentifierByte3);
+ }
+
+ device.pause(30);
+}
+
+function requestTotalLeds() //Calculate total number of LEDs
+{
+ device.write([0x00, 0x27], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnTotalLeds(data) {
+ LEDCount = data[2];
+ device.log("Device Total LED Count: " + LEDCount);
+ device.pause(30);
+}
+
+function requestFirmwareType() {
+ device.write([0x00, 0x28], 32);
+ device.pause(30);
+ commandHandler();
+}
+
+function returnFirmwareType(data) {
+ const FirmwareTypeByte = data[2];
+
+ if(!(FirmwareTypeByte === MainlineQMKFirmware || FirmwareTypeByte === VIAFirmware)) {
+ device.notify("Unsupported Firmware", "Click the Documentation button to learn more.", 3, "Documentation");
+ }
+
+ if(FirmwareTypeByte === MainlineQMKFirmware) {
+ IsViaKeyboard = false;
+ device.log("Firmware Type: Mainline");
+ }
+
+ if(FirmwareTypeByte === VIAFirmware) {
+ IsViaKeyboard = true;
+ device.log("Firmware Type: VIA");
+ }
+
+ device.pause(30);
+}
+
+function effectEnable() //Enable the SignalRGB Effect Mode
+{
+ device.write([0x00, 0x25], 32);
+ device.pause(30);
+}
+
+function effectDisable() //Revert to Hardware Mode
+{
+ device.write([0x00, 0x26], 32);
+ device.pause(30);
+}
+
+function createSolidColorArray(color) {
+ const rgbdata = new Array(vKeys.length * 3).fill(0);
+
+ for(let iIdx = 0; iIdx < vKeys.length; iIdx++) {
+ const iLedIdx = vKeys[iIdx] * 3;
+ rgbdata[iLedIdx] = color[0];
+ rgbdata[iLedIdx+1] = color[1];
+ rgbdata[iLedIdx+2] = color[2];
+ }
+
+ return rgbdata;
+}
+
+function grabColors(overrideColor) {
+ if(overrideColor) {
+ return createSolidColorArray(hexToRgb(overrideColor));
+ } else if (LightingMode === "Forced") {
+ return createSolidColorArray(hexToRgb(forcedColor));
+ }
+
+ const rgbdata = new Array(vKeys.length * 3).fill(0);
+
+ for(let iIdx = 0; iIdx < vKeys.length; iIdx++) {
+ const iPxX = vKeyPositions[iIdx][0];
+ const iPxY = vKeyPositions[iIdx][1];
+ const color = device.color(iPxX, iPxY);
+
+ const iLedIdx = vKeys[iIdx] * 3;
+ rgbdata[iLedIdx] = color[0];
+ rgbdata[iLedIdx+1] = color[1];
+ rgbdata[iLedIdx+2] = color[2];
+ }
+
+ return rgbdata;
+}
+
+function sendColors(overrideColor) {
+ const rgbdata = grabColors(overrideColor);
+
+ const LedsPerPacket = 9;
+ let BytesSent = 0;
+ let BytesLeft = rgbdata.length;
+
+ while(BytesLeft > 0) {
+ const BytesToSend = Math.min(LedsPerPacket * 3, BytesLeft);
+ StreamLightingData(Math.floor(BytesSent / 3), rgbdata.splice(0, BytesToSend));
+
+ BytesLeft -= BytesToSend;
+ BytesSent += BytesToSend;
+ }
+}
+
+function StreamLightingData(StartLedIdx, RGBData) {
+ const packet = [0x00, 0x24, StartLedIdx, Math.floor(RGBData.length / 3)].concat(RGBData);
+ device.write(packet, 33);
+}
+
+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 === 1;
+}
+
+export function ImageUrl()
+{
+ return "https://raw.githubusercontent.com/SRGBmods/QMK-Images/main/images/NuPhy_Air75v2.png";
+}
\ No newline at end of file
diff --git a/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
index 78f72513e10b..22356c05c99c 100644
--- a/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
+++ b/SRGB_qmk_plugins/NuPhy_Air96v2_QMK_ANSI_Keyboard.js
@@ -5,7 +5,7 @@ export function ProductId() { return 0x3266; }
export function Publisher() { return "ZZM"; }
export function Documentation() { return "qmk/srgbmods-qmk-firmware"; }
export function DeviceType() { return "keyboard"; }
-export function Size() { return [19, 6]; }
+export function Size() { return [73, 11]; }
export function DefaultPosition(){return [10, 100]; }
export function DefaultScale(){return 8.0;}
/* global
@@ -44,12 +44,12 @@ const vKeyNames = [
];
const vKeyPositions = [
- [0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0], [6, 0], [7, 0], [8, 0], [9, 0], [10, 0], [11, 0], [12, 0], [13, 0], [14, 0], [15, 0], [16, 0], [17, 0], [18, 0], //19
- [0, 1], [1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1], [9, 1], [10, 1], [11, 1], [12, 1], [13, 1], [15, 1], [16, 1], [17, 1], [18, 1], //18
- [0, 2], [1, 2], [2, 2], [3, 2], [4, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2], [10, 2], [11, 2], [12, 2], [14, 2], [15, 2], [16, 2], [17, 2], [18, 2], //18
- [0, 3], [2, 3], [3, 3], [4, 3], [5, 3], [6, 3], [7, 3], [8, 3], [9, 3], [10, 3], [11, 3], [12, 3], [14, 3], [15, 3], [16, 3], [17, 3], //16
- [0, 4], [2, 4], [3, 4], [4, 4], [5, 4], [6, 4], [7, 4], [8, 4], [9, 4], [10, 4], [11, 4], [13, 4], [14, 4], [15, 4], [16, 4], [17, 4], [18, 4], //17
- [0, 5], [2, 5], [3, 5], [7, 5], [10, 5], [11, 5], [12, 5], [13, 5], [14, 5], [15, 5], [16, 5], [17, 5], //12
+ [0, 0], [4, 0], [8, 0], [12, 0], [16, 0], [20, 0], [24, 0], [28, 0], [32, 0], [36, 0], [40, 0], [44, 0], [48, 0], [52, 0], [56, 0], [60, 0], [64, 0], [68, 0], [72, 0], //19
+ [0, 2], [4, 2], [8, 2], [12, 2], [16, 2], [20, 2], [24, 2], [28, 2], [32, 2], [36, 2], [40, 2], [44, 2], [48, 2], [54, 2], [60, 2], [64, 2], [68, 2], [72, 2], //18
+ [0, 4], [6, 4], [10, 4], [14, 4], [18, 4], [22, 4], [26, 4], [30, 4], [34, 4], [38, 4], [42, 4], [46, 4], [50, 4], [55, 4], [60, 4], [64, 4], [68, 4], [72, 5], //18
+ [0, 6], [7, 6], [11, 6], [15, 6], [19, 6], [23, 6], [27, 6], [31, 6], [35, 6], [39, 6], [43, 6], [47, 6], [54, 6], [60, 6], [64, 6], [68, 6], //16
+ [0, 8], [9, 8], [13, 8], [17, 8], [21, 8], [25, 8], [29, 8], [33, 8], [37, 8], [41, 8], [45, 8], [51, 8], [56, 8], [60, 8], [64, 8], [68, 8], [72, 9], //17
+ [0,10], [5,10], [10,10], [26,10], [40,10], [44,10], [48,10], [52,10], [56,10], [60,10], [64,10], [68,10], //12
];
let LEDCount = 0;
From 7e5f2c8bece83b5f6eda9e7d8cc887a14d535887 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 17:40:50 +0800
Subject: [PATCH 16/34] Update readme.md
---
keyboards/nuphy/air96_v2/ansi/side.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/keyboards/nuphy/air96_v2/ansi/side.c b/keyboards/nuphy/air96_v2/ansi/side.c
index 9bc667555392..e6698774b8b0 100644
--- a/keyboards/nuphy/air96_v2/ansi/side.c
+++ b/keyboards/nuphy/air96_v2/ansi/side.c
@@ -301,6 +301,9 @@ void sys_led_show(void)
if (host_keyboard_led_state().caps_lock) {
set_left_rgb(0X00, SIDE_BLINK_LIGHT, SIDE_BLINK_LIGHT);
}
+ if (!host_keyboard_led_state().num_lock) {
+ set_right_rgb(0X00, SIDE_BLINK_LIGHT / 2, SIDE_BLINK_LIGHT / 2);
+ }
}
else {
if (dev_info.rf_led & 0x02) {
@@ -635,10 +638,10 @@ void bat_percent_led(uint8_t bat_percent)
bat_r = SIDE_BLINK_LIGHT, bat_g = SIDE_BLINK_LIGHT / 2, bat_b = 0;
} else if (bat_percent <= 70) {
bat_end_led = 3;
- bat_r = SIDE_BLINK_LIGHT, bat_g = SIDE_BLINK_LIGHT / 2, bat_b = 0;
+ bat_r = SIDE_BLINK_LIGHT, bat_g = SIDE_BLINK_LIGHT, bat_b = 0;
} else if (bat_percent <= 95) {
bat_end_led = 4;
- bat_r = SIDE_BLINK_LIGHT, bat_g = SIDE_BLINK_LIGHT / 2, bat_b = 0;
+ bat_r = SIDE_BLINK_LIGHT, bat_g = SIDE_BLINK_LIGHT, bat_b = 0;
} else {
bat_end_led = 4;
bat_r = 0, bat_g = SIDE_BLINK_LIGHT, bat_b = 0;
From 4dc930f0c0cffe849f286e2ab3007b491efa3405 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 17:42:11 +0800
Subject: [PATCH 17/34] Update readme.md
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index 5a53c2b65ef5..dce6e193a5d5 100644
--- a/readme.md
+++ b/readme.md
@@ -3,7 +3,7 @@
## improvements:
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware.
-2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 v2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugin is saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
+2. Fixed some keymapping errors in nuphy keyboard plugin for Air96V2/Air75V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
3. Add SignalRGB plugin for Air60 v2.
## Note: SignalRGB / VIA Issue
From 7abd595398dac2d0885809680f33a401e6825cf6 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 17:52:34 +0800
Subject: [PATCH 18/34] Add reverse NumLock indicator; Decrease brightness of
CapsLock and NumLock; Change battery indicator: yellow when 50-95%.
---
keyboards/nuphy/air96_v2/ansi/side.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/keyboards/nuphy/air96_v2/ansi/side.c b/keyboards/nuphy/air96_v2/ansi/side.c
index e6698774b8b0..b9ac3da9e7c3 100644
--- a/keyboards/nuphy/air96_v2/ansi/side.c
+++ b/keyboards/nuphy/air96_v2/ansi/side.c
@@ -299,7 +299,7 @@ void sys_led_show(void)
{
if (dev_info.link_mode == LINK_USB) {
if (host_keyboard_led_state().caps_lock) {
- set_left_rgb(0X00, SIDE_BLINK_LIGHT, SIDE_BLINK_LIGHT);
+ set_left_rgb(0X00, SIDE_BLINK_LIGHT / 2, SIDE_BLINK_LIGHT / 2);
}
if (!host_keyboard_led_state().num_lock) {
set_right_rgb(0X00, SIDE_BLINK_LIGHT / 2, SIDE_BLINK_LIGHT / 2);
From 6510681ca945ae21f4a6d29caed14fb14eefc823 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 18:01:57 +0800
Subject: [PATCH 19/34] Update readme.md.
---
readme.md | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/readme.md b/readme.md
index dce6e193a5d5..945b1d2225da 100644
--- a/readme.md
+++ b/readme.md
@@ -3,8 +3,10 @@
## improvements:
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware.
-2. Fixed some keymapping errors in nuphy keyboard plugin for Air96V2/Air75V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
-3. Add SignalRGB plugin for Air60 v2.
+2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2/Air75 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
+3. Added SignalRGB plugin for Air60 v2.
+4. Added reverse NumLock indicator for Air96 V2.
+5. Changed battery indicator for Air96 v2: Led appears yellow when 50-95%, rather than orange.
## Note: SignalRGB / VIA Issue
(From [document](https://docs.signalrgb.com/qmk) provided by SignalRGB)
From ffcb2d839b9ec21e44bb7fcada3ab83d4642a64f Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 18:02:32 +0800
Subject: [PATCH 20/34] Update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index 945b1d2225da..b348536d425e 100644
--- a/readme.md
+++ b/readme.md
@@ -6,7 +6,7 @@
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2/Air75 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
3. Added SignalRGB plugin for Air60 v2.
4. Added reverse NumLock indicator for Air96 V2.
-5. Changed battery indicator for Air96 v2: Led appears yellow when 50-95%, rather than orange.
+5. Changed battery indicator for Air96 v2: Leds appears yellow when 50-95%, rather than orange.
## Note: SignalRGB / VIA Issue
(From [document](https://docs.signalrgb.com/qmk) provided by SignalRGB)
From 4200bed003ba71cdd86719ddfe562087388b0dc5 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 18:24:52 +0800
Subject: [PATCH 21/34] Add reverse NumLock indicator; Change battery
indicator: yellow when 50-95%.
---
keyboards/nuphy/air96_v2/ansi/side.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/keyboards/nuphy/air96_v2/ansi/side.c b/keyboards/nuphy/air96_v2/ansi/side.c
index b9ac3da9e7c3..3b0941d15a09 100644
--- a/keyboards/nuphy/air96_v2/ansi/side.c
+++ b/keyboards/nuphy/air96_v2/ansi/side.c
@@ -299,10 +299,10 @@ void sys_led_show(void)
{
if (dev_info.link_mode == LINK_USB) {
if (host_keyboard_led_state().caps_lock) {
- set_left_rgb(0X00, SIDE_BLINK_LIGHT / 2, SIDE_BLINK_LIGHT / 2);
+ set_left_rgb(0X00, SIDE_BLINK_LIGHT, SIDE_BLINK_LIGHT);
}
if (!host_keyboard_led_state().num_lock) {
- set_right_rgb(0X00, SIDE_BLINK_LIGHT / 2, SIDE_BLINK_LIGHT / 2);
+ set_right_rgb(0X00, SIDE_BLINK_LIGHT, SIDE_BLINK_LIGHT);
}
}
else {
From 502cc1c6a35c5b9f127117271069f3643e44b1b9 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 18:48:09 +0800
Subject: [PATCH 22/34] Update SignalRGB plugin.
---
SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
index ea9cf60de50e..570f0b9daaf9 100644
--- a/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
+++ b/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
@@ -26,12 +26,12 @@ export function ControllableParameters() {
//Plugin Version: Built for Protocol V1.0.6
const vKeys = [
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, //16
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, //16
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, //15
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, //15
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, //14
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, //14
- 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 //10
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, //14
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, //14
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 //10
];
const vKeyNames = [
From df799676e8df11812befe53b438e402568ebfbb7 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 18:51:11 +0800
Subject: [PATCH 23/34] Update including method.
---
builddefs/common_features.mk | 11 ++++++++---
quantum/rgb_matrix/animations/rgb_matrix_effects.inc | 4 +++-
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 2e5421d6a33d..26a9b1721bb5 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -28,7 +28,6 @@ QUANTUM_SRC += \
$(QUANTUM_DIR)/sync_timer.c \
$(QUANTUM_DIR)/logging/debug.c \
$(QUANTUM_DIR)/logging/sendchar.c \
- $(QUANTUM_DIR)/signalrgb.c \
VPATH += $(QUANTUM_DIR)/logging
# Fall back to lib/printf if there is no platform provided print
@@ -632,12 +631,18 @@ ifeq ($(strip $(LED_TABLES)), yes)
SRC += $(QUANTUM_DIR)/led_tables.c
endif
-#ifeq ($(strip $(VIA_ENABLE)), yes)
+ifeq ($(strip $(VIA_ENABLE)), yes)
DYNAMIC_KEYMAP_ENABLE := yes
RAW_ENABLE := yes
BOOTMAGIC_ENABLE := yes
TRI_LAYER_ENABLE := yes
-#endif
+endif
+
+ifeq ($(strip $(SIGNALRGB_ENABLE)), yes)
+ RAW_ENABLE := yes
+ SRC += $(QUANTUM_DIR)/signalrgb.c
+ OPT_DEFS += -DSIGNALRGB_ENABLE
+endif
VALID_CUSTOM_MATRIX_TYPES:= yes lite no
diff --git a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc
index 00a9731526f1..e2d2e6b67923 100644
--- a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc
+++ b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc
@@ -43,4 +43,6 @@
#include "starlight_dual_sat_anim.h"
#include "starlight_dual_hue_anim.h"
#include "riverflow_anim.h"
-#include "signalrgb_anim.h"
\ No newline at end of file
+#ifdef SIGNALRGB_ENABLE
+ #include "signalrgb_anim.h"
+#endif
\ No newline at end of file
From 860485e6545b9240dae9370b9d4cb0c9a8cf556a Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 18:54:44 +0800
Subject: [PATCH 24/34] Update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index b348536d425e..8251566981a4 100644
--- a/readme.md
+++ b/readme.md
@@ -2,7 +2,7 @@
## improvements:
-1. Added SignalRGB support for Nuphy Keyboards using qmk firmware.
+1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB support, you should set SIGNALRGB_ENABLE = yes in rules.mk.
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2/Air75 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
3. Added SignalRGB plugin for Air60 v2.
4. Added reverse NumLock indicator for Air96 V2.
From e298cabf18a4f25d03537d9909935fd0803b0bb2 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 19:08:42 +0800
Subject: [PATCH 25/34] Update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index 8251566981a4..07c98de17f5d 100644
--- a/readme.md
+++ b/readme.md
@@ -2,7 +2,7 @@
## improvements:
-1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB support, you should set SIGNALRGB_ENABLE = yes in rules.mk.
+1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB, you should set SIGNALRGB_ENABLE = yes in rules.mk.
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2/Air75 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
3. Added SignalRGB plugin for Air60 v2.
4. Added reverse NumLock indicator for Air96 V2.
From c904d2df498c1019a2639f7657e3c2a6708f67fb Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 19:09:43 +0800
Subject: [PATCH 26/34] Update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index 07c98de17f5d..8a000b4c5b00 100644
--- a/readme.md
+++ b/readme.md
@@ -2,7 +2,7 @@
## improvements:
-1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB, you should set SIGNALRGB_ENABLE = yes in rules.mk.
+1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB, you should set "SIGNALRGB_ENABLE = yes" in rules.mk.
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2/Air75 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
3. Added SignalRGB plugin for Air60 v2.
4. Added reverse NumLock indicator for Air96 V2.
From 7fe198413279570327df2142700d608069d6e77f Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 19:10:54 +0800
Subject: [PATCH 27/34] Update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index 8a000b4c5b00..5146084c8075 100644
--- a/readme.md
+++ b/readme.md
@@ -3,7 +3,7 @@
## improvements:
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB, you should set "SIGNALRGB_ENABLE = yes" in rules.mk.
-2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2/Air75 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
+2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
3. Added SignalRGB plugin for Air60 v2.
4. Added reverse NumLock indicator for Air96 V2.
5. Changed battery indicator for Air96 v2: Leds appears yellow when 50-95%, rather than orange.
From 668f5252cc2d3ba5dc692bba1281c8d82e0ca72e Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 19:12:54 +0800
Subject: [PATCH 28/34] Update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index 5146084c8075..f0ca0fd4e3ab 100644
--- a/readme.md
+++ b/readme.md
@@ -1,6 +1,6 @@
# Project forked from nuphy-src/qmk_firmware
-## improvements:
+## Improvements:
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB, you should set "SIGNALRGB_ENABLE = yes" in rules.mk.
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
From 54dd3fc67a1bf6bd487706dab04c8e108f27bea0 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 19:16:21 +0800
Subject: [PATCH 29/34] Update readme.md.
---
readme.md | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/readme.md b/readme.md
index f0ca0fd4e3ab..5b5261c3be7a 100644
--- a/readme.md
+++ b/readme.md
@@ -4,9 +4,10 @@
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB, you should set "SIGNALRGB_ENABLE = yes" in rules.mk.
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
-3. Added SignalRGB plugin for Air60 v2.
-4. Added reverse NumLock indicator for Air96 V2.
-5. Changed battery indicator for Air96 v2: Leds appears yellow when 50-95%, rather than orange.
+3. Added SignalRGB plugin for Air60 v2 (untested).
+5. Improved RGB accuracy of SignalRGB plugin for Air75 v2 (untested).
+6. Added reverse NumLock indicator for Air96 V2.
+7. Changed battery indicator for Air96 v2: Leds appears yellow when 50-95%, rather than orange.
## Note: SignalRGB / VIA Issue
(From [document](https://docs.signalrgb.com/qmk) provided by SignalRGB)
From 86e87199b078e943b90fa3d27b7df33dce8dff19 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 19:18:08 +0800
Subject: [PATCH 30/34] Update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index 5b5261c3be7a..c1a42ce0a7d6 100644
--- a/readme.md
+++ b/readme.md
@@ -5,7 +5,7 @@
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB, you should set "SIGNALRGB_ENABLE = yes" in rules.mk.
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
3. Added SignalRGB plugin for Air60 v2 (untested).
-5. Improved RGB accuracy of SignalRGB plugin for Air75 v2 (untested).
+5. Improved keymap accuracy of SignalRGB plugin for Air75 v2 (untested).
6. Added reverse NumLock indicator for Air96 V2.
7. Changed battery indicator for Air96 v2: Leds appears yellow when 50-95%, rather than orange.
From 1322f1a6990a774dc5be627833bc85c0b5ddf1b4 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 19:22:47 +0800
Subject: [PATCH 31/34] Update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index c1a42ce0a7d6..530f6d02f092 100644
--- a/readme.md
+++ b/readme.md
@@ -1,4 +1,4 @@
-# Project forked from nuphy-src/qmk_firmware
+# QMK Firmware with SignalRGB Support for Nuphy
## Improvements:
From 19cda77521773ff873c12719f54a0d2b2bf75db9 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 20:09:12 +0800
Subject: [PATCH 32/34] Add SRGB keymap for air96v2
---
.../keymaps/srgb/NuPhy Air96 V2 via3.json | 195 ++++++++++++++++++
.../nuphy/air96_v2/ansi/keymaps/srgb/keymap.c | 178 ++++++++++++++++
.../nuphy/air96_v2/ansi/keymaps/srgb/rules.mk | 2 +
3 files changed, 375 insertions(+)
create mode 100644 keyboards/nuphy/air96_v2/ansi/keymaps/srgb/NuPhy Air96 V2 via3.json
create mode 100644 keyboards/nuphy/air96_v2/ansi/keymaps/srgb/keymap.c
create mode 100644 keyboards/nuphy/air96_v2/ansi/keymaps/srgb/rules.mk
diff --git a/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/NuPhy Air96 V2 via3.json b/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/NuPhy Air96 V2 via3.json
new file mode 100644
index 000000000000..2a7e31de21bb
--- /dev/null
+++ b/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/NuPhy Air96 V2 via3.json
@@ -0,0 +1,195 @@
+{
+ "name": "NuPhy Air96 V2",
+ "vendorId": "0x19F5",
+ "productId": "0x3266",
+ "matrix": {
+ "rows": 6,
+ "cols": 21
+ },
+ "layouts": {
+ "keymap": [
+ ["0,0","0,2","0,3","0,4","0,5","0,6","0,7","0,8","0,9","0,10","0,11","0,12","0,13","0,14","2,14","1,15","2,15","1,16","2,16"],
+ ["1,0","1,1","1,2","1,3","1,4","1,5","1,6","1,7","1,8","1,9","1,10","1,11","1,12",{"w":2},"1,13","1,17","1,18","1,19","1,20"],
+ [{"w":1.5},"2,0","2,1","2,2","2,3","2,4","2,5","2,6","2,7","2,8","2,9","2,10","2,11","2,12",{"w":1.5},"2,13","2,17","2,18","2,19",{"h":2},"2,20"],
+ [{"w": 1.75},"3,0","3,1","3,2","3,3","3,4","3,5","3,6","3,7","3,8","3,9","3,10","3,11",{"w":2.25},"3,13","3,17","3,18","3,19"],
+ [{"w":2.25},"4,0","4,2","4,3","4,4","4,5","4,6","4,7","4,8","4,9","4,10","4,11",{"w": 1.75},"4,13","4,15","4,17","4,18","4,19",{"h":2},"4,20"],
+ [{"w":1.25},"5,0",{"w":1.25},"5,1",{"w":1.25},"5,2",{"w":6.25},"5,6","5,9","5,10","5,13","5,14","5,15","5,16","5,17","5,19"]
+ ]
+ },
+ "menus": [
+ {
+ "label": "Lighting",
+ "content": [
+ {
+ "label": "Backlight",
+ "content": [
+ {
+ "label": "Brightness",
+ "type": "range",
+ "options": [0, 255],
+ "content": ["id_qmk_rgb_matrix_brightness", 3, 1]
+ },
+ {
+ "label": "Effect",
+ "type": "dropdown",
+ "content": ["id_qmk_rgb_matrix_effect", 3, 2],
+ "options": [
+ "All Off",
+ "Solid Color",
+ "Gradient Up/Down",
+ "Gradient Left/Right",
+ "Breathing",
+ "Band Sat.",
+ "Band Val.",
+ "Pinwheel Sat.",
+ "Pinwheel Val.",
+ "Spiral Sat.",
+ "Spiral Val.",
+ "Cycle All",
+ "Cycle Left/Right",
+ "Cycle Up/Down",
+ "Rainbow Moving Chevron",
+ "Cycle Out/In",
+ "Cycle Out/In Dual",
+ "Cycle Pinwheel",
+ "Cycle Spiral",
+ "Dual Beacon",
+ "Rainbow Beacon",
+ "Rainbow Pinwheels",
+ "Raindrops",
+ "Jellybean Raindrops",
+ "Hue Breathing",
+ "Hue Pendulum",
+ "Hue Wave",
+ "Typing Heatmap",
+ "Digital Rain",
+ "Reactive Simple",
+ "Reactive",
+ "Reactive Wide",
+ "Reactive Multiwide",
+ "Reactive Cross",
+ "Reactive Multicross",
+ "Reactive Nexus",
+ "Reactive MultiNexus",
+ "Splash",
+ "MultiSplash",
+ "Solid Splash",
+ "Solid MultiSplash"
+ ]
+ },
+ {
+ "showIf": "{id_qmk_rgb_matrix_effect} != 0",
+ "label": "Effect Speed",
+ "type": "range",
+ "options": [0, 255],
+ "content": ["id_qmk_rgb_matrix_effect_speed", 3, 3]
+ },
+ {
+ "showIf": "{id_qmk_rgb_matrix_effect} != 0",
+ "label": "Color",
+ "type": "color",
+ "content": ["id_qmk_rgb_matrix_color", 3, 4]
+ }
+ ]
+ }
+ ]
+ }
+ ],
+"keycodes": [
+ "qmk_lighting"
+],
+"customKeycodes": [
+ {
+ "name": "RF\nDFU",
+ "title": "RF DFU"
+ },
+ {
+ "name": "Link\nUSB",
+ "title": "Link USB"
+ },
+ {
+ "name": "Link\nRF",
+ "title": "Link RF"
+ },
+ {
+ "name": "Link\nBLE_1",
+ "title": "Link BLE_1"
+ },
+ {
+ "name": "Link\nBLE_2",
+ "title": "Link BLE_2"
+ },
+ {
+ "name": "Link\nBLE_3",
+ "title": "Link BLE_3"
+ },
+ {
+ "name": "Mac\nTask",
+ "title": "Mac Task"
+ },
+ {
+ "name": "Mac\nSearch",
+ "title": "Mac Search"
+ },
+ {
+ "name": "Mac\nVoice",
+ "title": "Mac Siri Voice"
+ },
+ {
+ "name": "Mac\nConsole",
+ "title": "Mac Console"
+ },
+ {
+ "name": "Mac\nDnt",
+ "title": "Mac Dnt"
+ },
+ {
+ "name": "Print\n Whole",
+ "title": "Print Whole"
+ },
+ {
+ "name": "Print\n Area",
+ "title": "Print Area"
+ },
+ {
+ "name": "Side\nLight+",
+ "title": "Side Light +"
+ },
+ {
+ "name": "Side\nLight-",
+ "title": "Side Light -"
+ },
+ {
+ "name": "Side\nMode",
+ "title": "Side Next Mode"
+ },
+ {
+ "name": "Side\nColor",
+ "title": "Side Next Color"
+ },
+ {
+ "name": "Side\nFast",
+ "title": "Side Speed +"
+ },
+ {
+ "name": "Side\nSlow",
+ "title": "Side Speed -"
+ },
+ {
+ "name": "Dev\nReset",
+ "title": "Device Reset"
+ },
+ {
+ "name": "Sleep\nMode",
+ "title": "Auto Sleep Mode"
+ },
+ {
+ "name": "Bat\nShow",
+ "title": "Battery Show"
+ },
+ {
+ "name": "RGB\nTest",
+ "title": "Hold for 3 seconds for RGB color test"
+ }
+]
+}
diff --git a/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/keymap.c b/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/keymap.c
new file mode 100644
index 000000000000..fe3dbc5c3729
--- /dev/null
+++ b/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/keymap.c
@@ -0,0 +1,178 @@
+/*
+Copyright 2023 @ Nuphy
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include QMK_KEYBOARD_H
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+// layer 0 Mac
+[0] = LAYOUT(
+ KC_ESC, KC_BRID, KC_BRIU, MAC_TASK, MAC_SEARCH, MAC_VOICE, MAC_DND, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, MAC_PRTA, KC_DEL, KC_HOME, KC_END, KC_PGUP, KC_PGDN,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PPLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT,
+ KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_RGUI, MO(1), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT),
+// layer 1 Mac Fn
+[1] = LAYOUT(
+ _______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, MAC_PRT, KC_INS, _______, _______, _______, _______,
+ _______, LNK_BLE1, LNK_BLE2, LNK_BLE3, LNK_RF, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, DEV_RESET, SLEEP_MODE, BAT_SHOW, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ MO(4), _______, _______, _______, _______, _______, _______, MO(4), RGB_SPD, RGB_SPI, _______, MO(4), RGB_VAI, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, RGB_MOD, RGB_VAD, RGB_HUI, _______, _______),
+// layer 2 win
+[2] = LAYOUT(
+ KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_PSCR, KC_DEL, KC_HOME, KC_END, KC_PGUP, KC_PGDN,
+ KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, KC_NUM, KC_PSLS, KC_PAST, KC_PMNS,
+ KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, KC_P7, KC_P8, KC_P9, KC_PPLS,
+ KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_P4, KC_P5, KC_P6,
+ KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, KC_P1, KC_P2, KC_P3, KC_PENT,
+ KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(3), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT, KC_P0, KC_PDOT),
+// layer 3 win Fn
+[3] = LAYOUT(
+ _______, KC_BRID, KC_BRIU, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, MAC_PRTA, KC_INS, _______, _______, _______, _______,
+ _______, LNK_BLE1, LNK_BLE2, LNK_BLE3, LNK_RF, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, DEV_RESET, SLEEP_MODE, BAT_SHOW, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ MO(4), _______, _______, _______, _______, _______, _______, MO(4), RGB_SPD, RGB_SPI, _______, MO(4), RGB_VAI, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, RGB_MOD, RGB_VAD, RGB_HUI, _______, _______),
+// layer 4 function
+[4] = LAYOUT(
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+ _______, _______, _______, RGB_TEST, _______, _______, _______, _______, SIDE_SPD, SIDE_SPI, _______, _______, SIDE_VAI, _______, _______, _______, _______,
+ _______, _______, _______, _______, _______, MO(4), _______, SIDE_MOD, SIDE_VAD, SIDE_HUI, _______, _______)
+};
+
+
+const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = {
+ {0, A_16, B_16, C_16},
+ {0, A_15, B_15, C_15},
+ {0, A_14, B_14, C_14},
+ {0, A_13, B_13, C_13},
+ {0, A_12, B_12, C_12},
+ {0, D_16, E_16, F_16},
+ {0, D_15, E_15, F_15},
+ {0, D_14, E_14, F_14},
+ {0, D_13, E_13, F_13},
+ {0, D_12, E_12, F_12},
+ {1, D_16, E_16, F_16},
+ {1, D_15, E_15, F_15},
+ {1, D_14, E_14, F_14},
+ {1, D_13, E_13, F_13},
+ {1, G_4, H_4, I_4},
+ {1, D_5, E_5, F_5},
+ {1, G_5, H_5, I_5},
+ {1, D_6, E_6, F_6},
+ {1, G_6, H_6, I_6},
+ {0, A_1, B_1, C_1},
+ {0, A_2, B_2, C_2},
+ {0, A_3, B_3, C_3},
+ {0, A_4, B_4, C_4},
+ {0, A_5, B_5, C_5},
+ {0, A_6, B_6, C_6},
+ {0, A_7, B_7, C_7},
+ {0, A_8, B_8, C_8},
+ {0, A_9, B_9, C_9},
+ {0, A_10, B_10, C_10},
+ {0, A_11, B_11, C_11},
+ {1, D_1, E_1, F_1},
+ {1, D_2, E_2, F_2},
+ {1, D_3, E_3, F_3},
+ {1, D_7, E_7, F_7},
+ {1, D_8, E_8, F_8},
+ {1, D_9, E_9, F_9},
+ {1, D_10, E_10, F_10},
+ {0, D_1, E_1, F_1},
+ {0, D_2, E_2, F_2},
+ {0, D_3, E_3, F_3},
+ {0, D_4, E_4, F_4},
+ {0, D_5, E_5, F_5},
+ {0, D_6, E_6, F_6},
+ {0, D_7, E_7, F_7},
+ {0, D_8, E_8, F_8},
+ {0, D_9, E_9, F_9},
+ {0, D_10, E_10, F_10},
+ {0, D_11, E_11, F_11},
+ {1, G_1, H_1, I_1},
+ {1, G_2, H_2, I_2},
+ {1, G_3, H_3, I_3},
+ {1, G_7, H_7, I_7},
+ {1, G_8, H_8, I_8},
+ {1, G_9, H_9, I_9},
+ {1, G_10, H_10, I_10},
+ {0, G_1, H_1, I_1},
+ {0, G_2, H_2, I_2},
+ {0, G_3, H_3, I_3},
+ {0, G_4, H_4, I_4},
+ {0, G_5, H_5, I_5},
+ {0, G_6, H_6, I_6},
+ {0, G_7, H_7, I_7},
+ {0, G_8, H_8, I_8},
+ {0, G_9, H_9, I_9},
+ {0, G_10, H_10, I_10},
+ {0, G_11, H_11, I_11},
+ {1, G_16, H_16, I_16},
+ {1, G_14, H_14, I_14},
+ {1, G_13, H_13, I_13},
+ {1, G_12, H_12, I_12},
+ {1, G_11, H_11, I_11},
+ {0, J_1, K_1, L_1},
+ {0, J_3, K_3, L_3},
+ {0, J_4, K_4, L_4},
+ {0, J_5, K_5, L_5},
+ {0, J_6, K_6, L_6},
+ {0, J_7, K_7, L_7},
+ {0, J_8, K_8, L_8},
+ {0, J_9, K_9, L_9},
+ {0, J_10, K_10, L_10},
+ {0, J_11, K_11, L_11},
+ {1, J_1, K_1, L_1},
+ {1, J_3, K_3, L_3},
+ {1, J_4, K_4, L_4},
+ {1, J_5, K_5, L_5},
+ {1, J_6, K_6, L_6},
+ {1, J_7, K_7, L_7},
+ {1, J_8, K_8, L_8},
+ {0, J_16, K_16, L_16},
+ {0, J_15, K_15, L_15},
+ {0, J_14, K_14, L_14},
+ {0, J_13, K_13, L_13},
+ {0, J_12, K_12, L_12},
+ {1, J_16, K_16, L_16},
+ {1, J_14, K_14, L_14},
+ {1, J_13, K_13, L_13},
+ {1, J_12, K_12, L_12},
+ {1, J_11, K_11, L_11},
+ {1, J_10, K_10, L_10},
+ {1, J_9, K_9, L_9},
+
+ {1, A_5, B_5, C_5},
+ {1, A_4, B_4, C_4},
+ {1, A_3, B_3, C_3},
+ {1, A_2, B_2, C_2},
+ {1, A_1, B_1, C_1},
+
+ {1, A_6, B_6, C_6},
+ {1, A_7, B_7, C_7},
+ {1, A_8, B_8, C_8},
+ {1, A_9, B_9, C_9},
+ {1, A_10, B_10, C_10}
+};
diff --git a/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/rules.mk b/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/rules.mk
new file mode 100644
index 000000000000..5d69e14570ec
--- /dev/null
+++ b/keyboards/nuphy/air96_v2/ansi/keymaps/srgb/rules.mk
@@ -0,0 +1,2 @@
+VIA_ENABLE = yes
+SIGNALRGB_ENABLE = yes
From a020356103908ddde8772002e775d2dfb41a690f Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 22:09:34 +0800
Subject: [PATCH 33/34] fix led map
---
SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js b/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
index 570f0b9daaf9..cf99befc6a83 100644
--- a/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
+++ b/SRGB_qmk_plugins/NuPhy_Air75v2_QMK_ANSI_Keyboard.js
@@ -27,11 +27,11 @@ export function ControllableParameters() {
const vKeys = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, //16
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, //15
- 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, //15
- 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, //14
- 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, //14
- 74, 75, 76, 77, 78, 79, 80, 81, 82, 83 //10
+ 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, //15
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, //15
+ 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, //14
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, //14
+ 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, //9
];
const vKeyNames = [
From 42453eff154d01aaf30784b7529cdec6698655b2 Mon Sep 17 00:00:00 2001
From: zhouzengming <1548602509@qq.com>
Date: Sun, 16 Mar 2025 22:16:44 +0800
Subject: [PATCH 34/34] update readme.md.
---
readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/readme.md b/readme.md
index 530f6d02f092..902f00310af1 100644
--- a/readme.md
+++ b/readme.md
@@ -5,7 +5,7 @@
1. Added SignalRGB support for Nuphy Keyboards using qmk firmware. To enable SignalRGB, you should set "SIGNALRGB_ENABLE = yes" in rules.mk.
2. Fixed some keymapping errors in nuphy keyboard plugin for Air96 V2 from [SignalRGB](https://github.com/SRGBmods/qmk-plugins/blob/main/Nuphy/NuPhy_Air96v2_QMK_ANSI_Keyboard.js). Plugins are saved in [SRGB_qmk_plugins](/SRGB_qmk_plugins). You should copy .js file to C:\Users\\[YOUR USERNAME]\Documents\WhirlwindFX\Plugins.
3. Added SignalRGB plugin for Air60 v2 (untested).
-5. Improved keymap accuracy of SignalRGB plugin for Air75 v2 (untested).
+5. Improved keymap accuracy of SignalRGB plugin for Air75 v2.
6. Added reverse NumLock indicator for Air96 V2.
7. Changed battery indicator for Air96 v2: Leds appears yellow when 50-95%, rather than orange.