using GHelper.Helpers; using HidLibrary; using System.Text; namespace GHelper { public class AuraPower { public bool BootLogo; public bool BootKeyb; public bool AwakeLogo; public bool AwakeKeyb; public bool SleepLogo; public bool SleepKeyb; public bool ShutdownLogo; public bool ShutdownKeyb; public bool BootBar; public bool AwakeBar; public bool SleepBar; public bool ShutdownBar; public bool BootLid; public bool AwakeLid; public bool SleepLid; public bool ShutdownLid; public bool BootRear; public bool AwakeRear; public bool SleepRear; public bool ShutdownRear; } public static class AsusUSB { public const int HEATMAP = 20; public const int ASUS_ID = 0x0b05; public const byte INPUT_HID_ID = 0x5a; public const byte AURA_HID_ID = 0x5d; public static readonly byte[] LED_INIT1 = new byte[] { AURA_HID_ID, 0xb9 }; public static readonly byte[] LED_INIT2 = Encoding.ASCII.GetBytes("]ASUS Tech.Inc."); public static readonly byte[] LED_INIT3 = new byte[] { AURA_HID_ID, 0x05, 0x20, 0x31, 0, 0x1a }; public static readonly byte[] LED_INIT4 = Encoding.ASCII.GetBytes("^ASUS Tech.Inc."); public static readonly byte[] LED_INIT5 = new byte[] { 0x5e, 0x05, 0x20, 0x31, 0, 0x1a }; static byte[] MESSAGE_APPLY = { AURA_HID_ID, 0xb4 }; static byte[] MESSAGE_SET = { AURA_HID_ID, 0xb5, 0, 0, 0 }; static int[] deviceIds = { 0x1a30, 0x1854, 0x1869, 0x1866, 0x19b6, 0x1822, 0x1837, 0x1854, 0x184a, 0x183d, 0x8502, 0x1807, 0x17e0, 0x18c6, 0x1abe }; private static int mode = 0; private static int speed = 1; public static Color Color1 = Color.White; public static Color Color2 = Color.Black; static bool isTuf = AppConfig.IsTUF(); static bool isStrix = AppConfig.IsStrix(); static public bool isSingleColor = false; static bool isOldHeatmap = AppConfig.Is("old_heatmap"); static System.Timers.Timer timer = new System.Timers.Timer(2000); static HidDevice? auraDevice = null; static byte[] AuraPowerMessage(AuraPower flags) { byte keyb = 0, bar = 0, lid = 0, rear = 0; if (flags.BootLogo) keyb |= 1 << 0; if (flags.BootKeyb) keyb |= 1 << 1; if (flags.AwakeLogo) keyb |= 1 << 2; if (flags.AwakeKeyb) keyb |= 1 << 3; if (flags.SleepLogo) keyb |= 1 << 4; if (flags.SleepKeyb) keyb |= 1 << 5; if (flags.ShutdownLogo) keyb |= 1 << 6; if (flags.ShutdownKeyb) keyb |= 1 << 7; if (flags.BootBar) bar |= 1 << 1; if (flags.AwakeBar) bar |= 1 << 2; if (flags.SleepBar) bar |= 1 << 3; if (flags.ShutdownBar) bar |= 1 << 4; if (flags.BootLid) lid |= 1 << 0; if (flags.AwakeLid) lid |= 1 << 1; if (flags.SleepLid) lid |= 1 << 2; if (flags.ShutdownLid) lid |= 1 << 3; if (flags.BootLid) lid |= 1 << 4; if (flags.AwakeLid) lid |= 1 << 5; if (flags.SleepLid) lid |= 1 << 6; if (flags.ShutdownLid) lid |= 1 << 7; if (flags.BootRear) rear |= 1 << 0; if (flags.AwakeRear) rear |= 1 << 1; if (flags.SleepRear) rear |= 1 << 2; if (flags.ShutdownRear) rear |= 1 << 3; if (flags.BootRear) rear |= 1 << 4; if (flags.AwakeRear) rear |= 1 << 5; if (flags.SleepRear) rear |= 1 << 6; if (flags.ShutdownRear) rear |= 1 << 7; return new byte[] { 0x5d, 0xbd, 0x01, keyb, bar, lid, rear, 0xFF }; } static AsusUSB() { timer.Elapsed += Timer_Elapsed; isSingleColor = AppConfig.ContainsModel("GA401") || AppConfig.ContainsModel("X13"); // Mono Color var device = GetDevice(AURA_HID_ID); if (device is not null && device.Attributes.Version == 22 && AppConfig.ContainsModel("GA402X")) isSingleColor = true; } private static void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e) { SetHeatmap(); } static void SetHeatmap(bool init = false) { float cpuTemp = (float)HardwareControl.GetCPUTemp(); int freeze = 20, cold = 40, warm = 65, hot = 90; Color color; //Debug.WriteLine(cpuTemp); if (cpuTemp < cold) color = ColorUtilities.GetWeightedAverage(Color.Blue, Color.Green, ((float)cpuTemp - freeze) / (cold - freeze)); else if (cpuTemp < warm) color = ColorUtilities.GetWeightedAverage(Color.Green, Color.Yellow, ((float)cpuTemp - cold) / (warm - cold)); else if (cpuTemp < hot) color = ColorUtilities.GetWeightedAverage(Color.Yellow, Color.Red, ((float)cpuTemp - warm) / (hot - warm)); else color = Color.Red; ApplyColor(color, init); } public static Dictionary GetSpeeds() { return new Dictionary { { 0, Properties.Strings.AuraSlow }, { 1, Properties.Strings.AuraNormal }, { 2, Properties.Strings.AuraFast } }; } static Dictionary _modes = new Dictionary { { 0, Properties.Strings.AuraStatic }, { 1, Properties.Strings.AuraBreathe }, { 2, Properties.Strings.AuraColorCycle }, { 3, Properties.Strings.AuraRainbow }, { 10, Properties.Strings.AuraStrobe }, { HEATMAP, "Heatmap"} }; static Dictionary _modesStrix = new Dictionary { { 0, Properties.Strings.AuraStatic }, { 1, Properties.Strings.AuraBreathe }, { 2, Properties.Strings.AuraColorCycle }, { 3, Properties.Strings.AuraRainbow }, { 4, "Star" }, { 5, "Rain" }, { 6, "Highlight" }, { 7, "Laser" }, { 8, "Ripple" }, { 10, Properties.Strings.AuraStrobe}, { 11, "Comet" }, { 12, "Flash" }, { HEATMAP, "Heatmap"} }; public static Dictionary GetModes() { if (isTuf) { _modes.Remove(3); } if (isSingleColor) { _modes.Remove(2); _modes.Remove(3); _modes.Remove(HEATMAP); } if (AppConfig.IsAdvantageEdition()) { return _modes; } if (AppConfig.IsStrix()) { return _modesStrix; } return _modes; } public static int Mode { get { return mode; } set { if (GetModes().ContainsKey(value)) mode = value; else mode = 0; } } public static bool HasSecondColor() { return (mode == 1 && !isTuf); } public static int Speed { get { return speed; } set { if (GetSpeeds().ContainsKey(value)) speed = value; else speed = 1; } } public static void SetColor(int colorCode) { Color1 = Color.FromArgb(colorCode); } public static void SetColor2(int colorCode) { Color2 = Color.FromArgb(colorCode); } private static IEnumerable GetHidDevices(int[] deviceIds, int minFeatures = 1) { HidDevice[] HidDeviceList = HidDevices.Enumerate(ASUS_ID, deviceIds).ToArray(); foreach (HidDevice device in HidDeviceList) if (device.IsConnected && device.Capabilities.FeatureReportByteLength >= minFeatures) yield return device; } public static HidDevice? GetDevice(byte reportID = INPUT_HID_ID) { HidDevice[] HidDeviceList = HidDevices.Enumerate(ASUS_ID, deviceIds).ToArray(); HidDevice input = null; foreach (HidDevice device in HidDeviceList) if (device.ReadFeatureData(out byte[] data, reportID)) { input = device; //Logger.WriteLine("HID Device("+ reportID + ")" + + device.Capabilities.FeatureReportByteLength + "|" + device.Capabilities.InputReportByteLength + device.DevicePath); } return input; } public static bool TouchpadToggle() { HidDevice? input = GetDevice(); if (input != null) return input.WriteFeatureData(new byte[] { INPUT_HID_ID, 0xf4, 0x6b }); return false; } public static byte[] AuraMessage(int mode, Color color, Color color2, int speed, bool mono = false) { byte[] msg = new byte[17]; msg[0] = AURA_HID_ID; msg[1] = 0xb3; msg[2] = 0x00; // Zone msg[3] = (byte)mode; // Aura Mode msg[4] = color.R; // R msg[5] = mono ? (byte)0 : color.G; // G msg[6] = mono ? (byte)0 : color.B; // B msg[7] = (byte)speed; // aura.speed as u8; msg[8] = 0; // aura.direction as u8; msg[9] = (mode == 1) ? (byte)1 : (byte)0; msg[10] = color2.R; // R msg[11] = mono ? (byte)0 : color2.G; // G msg[12] = mono ? (byte)0 : color2.B; // B return msg; } public static void Init() { Task.Run(async () => { var devices = GetHidDevices(deviceIds); foreach (HidDevice device in devices) { device.OpenDevice(); device.WriteFeatureData(LED_INIT1); device.WriteFeatureData(LED_INIT2); device.WriteFeatureData(LED_INIT3); device.WriteFeatureData(LED_INIT4); device.WriteFeatureData(LED_INIT5); device.CloseDevice(); } }); } public static void ApplyBrightness(int brightness, string log = "Backlight") { Task.Run(async () => { if (isTuf) Program.acpi.TUFKeyboardBrightness(brightness); byte[] msg = { AURA_HID_ID, 0xba, 0xc5, 0xc4, (byte)brightness }; byte[] msgBackup = { INPUT_HID_ID, 0xba, 0xc5, 0xc4, (byte)brightness }; var devices = GetHidDevices(deviceIds); foreach (HidDevice device in devices) { device.OpenDevice(); if (device.ReadFeatureData(out byte[] data, AURA_HID_ID)) { device.WriteFeatureData(msg); Logger.WriteLine(log + ":" + BitConverter.ToString(msg)); } if (AppConfig.ContainsModel("GA503") && device.ReadFeatureData(out byte[] dataBackkup, INPUT_HID_ID)) { device.WriteFeatureData(msgBackup); Logger.WriteLine(log + ":" + BitConverter.ToString(msgBackup)); } device.CloseDevice(); } // Backup payload for old models /* if (AppConfig.ContainsModel("GA503RW")) { byte[] msgBackup = { INPUT_HID_ID, 0xba, 0xc5, 0xc4, (byte)brightness }; var devicesBackup = GetHidDevices(deviceIds); foreach (HidDevice device in devicesBackup) { device.OpenDevice(); device.WriteFeatureData(msgBackup); device.CloseDevice(); } } */ }); } public static void ApplyAuraPower() { Task.Run(async () => { AuraPower flags = new(); // Keyboard flags.AwakeKeyb = AppConfig.IsNotFalse("keyboard_awake"); flags.BootKeyb = AppConfig.IsNotFalse("keyboard_boot"); flags.SleepKeyb = AppConfig.IsNotFalse("keyboard_sleep"); flags.ShutdownKeyb = AppConfig.IsNotFalse("keyboard_shutdown"); // Logo flags.AwakeLogo = AppConfig.IsNotFalse("keyboard_awake_logo"); flags.BootLogo = AppConfig.IsNotFalse("keyboard_boot_logo"); flags.SleepLogo = AppConfig.IsNotFalse("keyboard_sleep_logo"); flags.ShutdownLogo = AppConfig.IsNotFalse("keyboard_shutdown_logo"); // Lightbar flags.AwakeBar = AppConfig.IsNotFalse("keyboard_awake_bar"); flags.BootBar = AppConfig.IsNotFalse("keyboard_boot_bar"); flags.SleepBar = AppConfig.IsNotFalse("keyboard_sleep_bar"); flags.ShutdownBar = AppConfig.IsNotFalse("keyboard_shutdown_bar"); // Lid flags.AwakeLid = AppConfig.IsNotFalse("keyboard_awake_lid"); flags.BootLid = AppConfig.IsNotFalse("keyboard_boot_lid"); flags.SleepLid = AppConfig.IsNotFalse("keyboard_sleep_lid"); flags.ShutdownLid = AppConfig.IsNotFalse("keyboard_shutdown_lid"); // Rear Bar flags.AwakeRear = AppConfig.IsNotFalse("keyboard_awake_lid"); flags.BootRear = AppConfig.IsNotFalse("keyboard_boot_lid"); flags.SleepRear = AppConfig.IsNotFalse("keyboard_sleep_lid"); flags.ShutdownRear = AppConfig.IsNotFalse("keyboard_shutdown_lid"); var devices = GetHidDevices(deviceIds); byte[] msg = AuraPowerMessage(flags); foreach (HidDevice device in devices) { device.OpenDevice(); if (device.ReadFeatureData(out byte[] data, AURA_HID_ID)) { device.WriteFeatureData(msg); Logger.WriteLine("USB-KB " + device.Attributes.ProductHexId + ":" + BitConverter.ToString(msg)); } device.CloseDevice(); } if (isTuf) Program.acpi.TUFKeyboardPower( flags.AwakeKeyb, flags.BootKeyb, flags.SleepKeyb, flags.ShutdownKeyb); }); } static void GetAuraDevice() { var devices = GetHidDevices(deviceIds); foreach (HidDevice device in devices) { device.OpenDevice(); if (device.ReadFeatureData(out byte[] data, AURA_HID_ID)) { Logger.WriteLine("Aura Device:" + device.DevicePath); auraDevice = device; return; } else { device.CloseDevice(); } } } public static void ApplyColor(Color color, bool init = false) { if (isTuf) { Program.acpi.TUFKeyboardRGB(0, color, 0); return; } if (auraDevice is null || !auraDevice.IsConnected) GetAuraDevice(); if (auraDevice is null || !auraDevice.IsConnected) return; if (isStrix && !isOldHeatmap) { byte[] msg = new byte[0x40]; byte start = 9; byte maxLeds = 0x93; msg[0] = AURA_HID_ID; msg[1] = 0xbc; msg[2] = 0; msg[3] = 1; msg[4] = 1; msg[5] = 1; msg[6] = 0; msg[7] = 0x10; for (byte i = 0; i < 0x12; i++) { msg[start + i * 3] = color.R; // R msg[start + 1 + i * 3] = color.G; // G msg[start + 2 + i * 3] = color.B; // B } if (init) { auraDevice.Write(LED_INIT1); auraDevice.Write(LED_INIT2); auraDevice.Write(LED_INIT3); auraDevice.Write(LED_INIT4); auraDevice.Write(LED_INIT5); auraDevice.Write(new byte[] { AURA_HID_ID, 0xbc }); } for (byte b = 0; b < maxLeds; b += 0x10) { msg[6] = b; auraDevice.Write(msg); } msg[6] = maxLeds; auraDevice.Write(msg); msg[4] = 4; msg[5] = 0; msg[6] = 0; msg[7] = 0; auraDevice.Write(msg); } else { auraDevice.Write(AuraMessage(0, color, color, 0)); auraDevice.Write(MESSAGE_SET); } } public static void ApplyAura() { Mode = AppConfig.Get("aura_mode"); Speed = AppConfig.Get("aura_speed"); SetColor(AppConfig.Get("aura_color", Color.Red.ToArgb())); SetColor2(AppConfig.Get("aura_color2")); if (Mode == HEATMAP) { SetHeatmap(true); timer.Enabled = true; return; } else { timer.Enabled = false; } Task.Run(async () => { int _speed; switch (Speed) { case 1: _speed = 0xeb; break; case 2: _speed = 0xf5; break; default: _speed = 0xe1; break; } byte[] msg; var devices = GetHidDevices(deviceIds); foreach (HidDevice device in devices) { device.OpenDevice(); if (device.ReadFeatureData(out byte[] data, AURA_HID_ID)) { msg = AuraMessage(Mode, Color1, Color2, _speed, isSingleColor); device.WriteFeatureData(msg); device.WriteFeatureData(MESSAGE_APPLY); device.WriteFeatureData(MESSAGE_SET); Logger.WriteLine("USB-KB " + device.Attributes.Version + device.Description + device.DevicePath + ":" + BitConverter.ToString(msg)); } device.CloseDevice(); } if (isTuf) Program.acpi.TUFKeyboardRGB(Mode, Color1, _speed); }); } // Reference : thanks to https://github.com/RomanYazvinsky/ for initial discovery of XGM payloads public static int SetXGM(byte[] msg) { //Logger.WriteLine("XGM Payload :" + BitConverter.ToString(msg)); var payload = new byte[300]; Array.Copy(msg, payload, msg.Length); foreach (HidDevice device in GetHidDevices(new int[] { 0x1970 }, 300)) { device.OpenDevice(); Logger.WriteLine("XGM " + device.Attributes.ProductHexId + "|" + device.Capabilities.FeatureReportByteLength + ":" + BitConverter.ToString(msg)); device.WriteFeatureData(payload); device.CloseDevice(); //return 1; } return 0; } public static void InitXGM() { SetXGM(LED_INIT1); SetXGM(LED_INIT2); SetXGM(LED_INIT3); SetXGM(LED_INIT4); SetXGM(LED_INIT5); } public static void ApplyXGMLight(bool status) { SetXGM(new byte[] { 0x5e, 0xc5, status ? (byte)0x50 : (byte)0 }); } public static int ResetXGM() { return SetXGM(new byte[] { 0x5e, 0xd1, 0x02 }); } public static int SetXGMFan(byte[] curve) { if (AsusACPI.IsInvalidCurve(curve)) return -1; //InitXGM(); byte[] msg = new byte[19]; Array.Copy(new byte[] { 0x5e, 0xd1, 0x01 }, msg, 3); Array.Copy(curve, 0, msg, 3, curve.Length); return SetXGM(msg); } } }