Repository: pwr-Solaar/Solaar

Issue:
M-Keys LEDs not working because of on-board profiles
Distro: Manjaro
Kernel: 5.16.2-2-rt19-MANJARO

If I Enable the LED for the M-Keys they will not glow until i enable the polling rate option.
If I enable the polling rate option, then the hole backlight except the M-Keys does not work.


Discussion:
That's a feature of the keyboard, as far as I can tell.   The keyboard has on-board profiles, which change how it behaves.  The only thing that Solaar does with on-board profiles is disable them so that the report rate can be changed.
I know that already but the backlights do not only stay the same, they go out completely. They do not light at all.
I expect that the on-board profile also controls the backlight.
Can you provide the output of `solaar show` for the keyboard?
The onboard Profile works but it does not autoload one.

Polling-Rate off:
```
Lightspeed Receiver
  Device path  : /dev/hidraw9
  USB id       : 046d:C541
  Serial       : DEE9CA1E
    Firmware   : 01.02.B0028
    Bootloader : 01.27
    Other      : 75.25
  Has 1 paired device(s) out of a maximum of 2.
  Notifications: wireless, software present (0x000900)
  Device activity counters: 1=44

  1: G915 WIRELESS RGB MECHANICAL GAMING KEYBOARD
     Device path  : None
     WPID         : 407C
     Codename     : G915 KEYBOARD
     Kind         : keyboard
     Protocol     : HID++ 4.2
     Polling rate : 8 ms (125Hz)
     Serial number: A502B0E1
     Model ID:      B354407CC33E
     Unit ID:       A502B0E1
        Bootloader: BOT 77.02.B0039
             Other: 
          Firmware: MPK 09.03.B0041
             Other: 
             Other: 
     The power switch is located on the top left corner.
     Supports 38 HID++ 2.0 features:
         0: ROOT                   {0000}   
         1: FEATURE SET            {0001}   
         2: DEVICE FW VERSION      {0003}   
            Firmware: Bootloader BOT 77.02.B0039 0000EC44D534
            Firmware: Other   
            Firmware: Firmware MPK 09.03.B0041 407C3791543D
            Firmware: Other   
            Firmware: Other   
            Unit ID: A502B0E1  Model ID: B354407CC33E  Transport IDs: {'btleid': 'B354', 'wpid': '407C', 'usbid': 'C33E'}
         3: DEVICE NAME            {0005}   
            Name: G915 WIRELESS RGB MECHANICAL GAMING KEYBOARD
            Kind: keyboard
         4: WIRELESS DEVICE STATUS {1D4B}   
         5: RESET                  {0020}   
         6: DEVICE FRIENDLY NAME   {0007}   
            Friendly Name: G915 KEYBOARD
         7: BATTERY VOLTAGE        {1001}   
            Battery: 4118mV, discharging, 90.
         8: CHANGE HOST            {1814}   
            Change Host        : 1:Ni
         9: HOSTS INFO             {1815}   
            Host 0 (paired): Ni
            Host 1 (paired): 
        10: RGB EFFECTS            {8071}   
        11: PER KEY LIGHTING V2    {8081}   
        12: REPROG CONTROLS V4     {1B04}   
            Key/Button Diversion (saved): {Host Switch Channel 1:Regular, Host Switch Channel 2:Regular}
            Key/Button Diversion        : {Host Switch Channel 1:Regular, Host Switch Channel 2:Regular}
        13: REPORT HID USAGE       {1BC0}   
        14: ENCRYPTION             {4100}   
        15: KEYBOARD DISABLE BY USAGE {4522}   
        16: KEYBOARD LAYOUT 2      {4540}   
        17: GKEY                   {8010}   
            Divert G Keys (saved): True
            Divert G Keys        : False
        18: MKEYS                  {8020}   
            M-Key LEDs (saved): {M1:True, M2:False, M3:False}
            M-Key LEDs        : {M1:False, M2:False, M3:False}
        19: MR                     {8030}   
            MR-Key LED (saved): False
            MR-Key LED        : False
        20: BRIGHTNESS CONTROL     {8040}   
        21: ONBOARD PROFILES       {8100}   
            Device Mode: Host
        22: REPORT RATE            {8060}   
            Polling Rate (ms): 1
            Polling Rate (ms) (saved): 1
            Polling Rate (ms)        : 1
        23: DFUCONTROL SIGNED      {00C2}   
        24: DFU                    {00D0}   
        25: DEVICE RESET           {1802}   internal, hidden
        26: unknown:1803           {1803}   internal, hidden
        27: CONFIG DEVICE PROPS    {1806}   internal, hidden
        28: unknown:1813           {1813}   internal, hidden
        29: OOBSTATE               {1805}   internal, hidden
        30: unknown:1830           {1830}   internal, hidden
        31: unknown:1890           {1890}   internal, hidden
        32: unknown:1891           {1891}   internal, hidden
        33: unknown:18A1           {18A1}   internal, hidden
        34: unknown:1E00           {1E00}   hidden
        35: unknown:1EB0           {1EB0}   internal, hidden
        36: unknown:1861           {1861}   internal, hidden
        37: unknown:18B0           {18B0}   internal, hidden
     Has 2 reprogrammable keys:
         0: Host Switch Channel 1     , default: HostSwitch Channel 1        => HostSwitch Channel 1      
             divertable, persistently divertable, pos:1, group:0, group mask:empty
             reporting: default
         1: Host Switch Channel 2     , default: HostSwitch Channel 2        => HostSwitch Channel 2      
             divertable, persistently divertable, pos:2, group:0, group mask:empty
             reporting: default
     Battery: 4118mV, discharging, 90.

```
It looks as if this keyboard has complex lighting features, none of which are supported by Solaar.

Resolving patch:
diff --git a/lib/logitech_receiver/settings_templates.py b/lib/logitech_receiver/settings_templates.py
--- a/lib/logitech_receiver/settings_templates.py
+++ b/lib/logitech_receiver/settings_templates.py
@@ -200,6 +200,7 @@ class K375sFnSwap(FnSwapVirtual):
 
 class Backlight(_Setting):
     name = 'backlight-qualitative'
+    label = _('Backlight')
     description = _('Set illumination time for keyboard.')
     feature = _F.BACKLIGHT
     choices_universe = _NamedInts(Off=0, Short=5, Medium=20, Long=60, VeryLong=180)
@@ -208,14 +209,15 @@ class Backlight(_Setting):
 
 
 class Backlight2(_Setting):
+    name = 'backlight'
     label = _('Backlight')
     description = _('Turn illumination on or off on keyboard.')
-    name = 'backlight'
     feature = _F.BACKLIGHT2
 
 
 class Backlight3(_Setting):
     name = 'backlight-timed'
+    label = _('Backlight')
     description = _('Set illumination time for keyboard.')
     feature = _F.BACKLIGHT3
     rw_options = {'read_fnid': 0x10, 'write_fnid': 0x20, 'suffix': 0x09}
@@ -295,18 +297,29 @@ class ThumbInvert(_Setting):
     validator_options = {'true_value': b'\x00\x01', 'false_value': b'\x00\x00', 'mask': b'\x00\x01'}
 
 
+class OnboardProfiles(_Setting):
+    name = 'onboard_profiles'
+    label = _('Onboard Profiles')
+    description = _('Enable onboard profiles, which often control report rate and keyboard lighting')
+    feature = _F.ONBOARD_PROFILES
+    rw_options = {'read_fnid': 0x20, 'write_fnid': 0x10}
+    choices_universe = _NamedInts(Enable=1, Disable=2)
+    validator_class = _ChoicesV
+    validator_options = {'choices': choices_universe}
+
+
 class ReportRate(_Setting):
     name = 'report_rate'
     label = _('Polling Rate (ms)')
     description = (
         _('Frequency of device polling, in milliseconds') + '\n' +
-        _('Set to ignore if unusual device behaviour is experienced')
+        _('May need Onboard Profiles set to Disable to be effective.')
     )
     feature = _F.REPORT_RATE
     rw_options = {'read_fnid': 0x10, 'write_fnid': 0x20}
     choices_universe = _NamedInts.range(1, 8)
 
-    class rw_class(_FeatureRW):
+    class _rw_class(_FeatureRW):  # no longer needed - set Onboard Profiles to disable
         def write(self, device, data_bytes):
             # Host mode is required for report rate to be adjustable
             if _hidpp20.get_onboard_mode(device) != _hidpp20.ONBOARD_MODES.MODE_HOST:
@@ -316,8 +329,8 @@ def write(self, device, data_bytes):
     class validator_class(_ChoicesV):
         @classmethod
         def build(cls, setting_class, device):
-            if device.wpid == '408E':
-                return None  # host mode borks the function keys on the G915 TKL keyboard
+            # if device.wpid == '408E':
+            #    return None  # host mode borks the function keys on the G915 TKL keyboard
             reply = device.feature_request(_F.REPORT_RATE, 0x00)
             assert reply, 'Oops, report rate choices cannot be retrieved!'
             rate_list = []
@@ -1007,7 +1020,7 @@ def build(cls, setting_class, device):
 class MKeyLEDs(_BitFieldSetting):
     name = 'm-key-leds'
     label = _('M-Key LEDs')
-    description = _('Control the M-Key LEDs.')
+    description = (_('Control the M-Key LEDs.') + '\n' + _('May need Onboard Profiles set to Disable to be effective.'))
     feature = _F.MKEYS
     choices_universe = _NamedInts()
     for i in range(8):
@@ -1108,6 +1121,7 @@ def build(cls, setting_class, device):
     SmartShiftEnhanced,  # simple
     ThumbMode,  # working
     ThumbInvert,  # working
+    OnboardProfiles,
     ReportRate,  # working
     PointerSpeed,  # simple
     AdjustableDpi,  # working


Test patch: