Repository: pwr-Solaar/Solaar

Issue:
Logitech Craft - switch off background light permanently
Switching off background light with the fn key is not permanently. light is on after keyboard has slept. Is there a way to switch the light off permanently? If not, it would be a nice to have function, like the fn switch, in solaar.


Discussion:
someone would have to sniff it out from Logitech options on either mac or windows I guess [ which have such option ]
Here are the sniffed out packets, when disabling and enabling back-light via Logitech Options [ with Wireshark/USBPcap ] 
it's a wireshark file, not sure how useful as I'm completely green to this
[backlight.pcapng.gz](https://github.com/pwr-Solaar/Solaar/files/3512411/backlight.pcapng.gz)

P.S. noticed that there are even more options now, like disabling certain keys [ caps, win, etc. ]

Can you paste the output of `solaar show`?
@FFY00 

```
Unifying Receiver
  Device path  : /dev/hidraw3
  USB id       : 046d:c52b
  Serial       : BC36E202
    Firmware   : 24.10.B0036
    Bootloader : 01.08
    Other      : AA.AC
  Has 2 paired device(s) out of a maximum of 6.
  Notifications: (none)
  Device activity counters: 1=194, 2=162

  1: Craft Advanced Keyboard
     Codename     : Craft
     Kind         : keyboard
     Wireless PID : 4066
     Protocol     : HID++ 4.5
     Polling rate : 8 ms (125Hz)
     Serial number: 40163908
        Bootloader: BOT 41.00.B0014
          Firmware: MPK 07.01.B0015
             Other: 
             Other: 
     The power switch is located on the edge of top right corner.
     Supports 39 HID++ 2.0 features:
         0: ROOT                   {0000}   
         1: FEATURE SET            {0001}   
         2: DEVICE FW VERSION      {0003}   
         3: DEVICE NAME            {0005}   
         4: WIRELESS DEVICE STATUS {1D4B}   
         5: RESET                  {0020}   
         6: unknown:0007           {0007}   
         7: BATTERY STATUS         {1000}   
         8: CHANGE HOST            {1814}   
         9: unknown:1815           {1815}   
        10: unknown:1982           {1982}   
        11: REPROG CONTROLS V4     {1B04}   
        12: unknown:1C00           {1C00}   
        13: K375S FN INVERSION     {40A3}   
        14: ENCRYPTION             {4100}   
        15: LOCK KEY STATE         {4220}   
        16: KEYBOARD DISABLE       {4521}   
        17: unknown:4531           {4531}   
        18: unknown:4600           {4600}   
        19: unknown:00C2           {00C2}   
        20: unknown:1803           {1803}   internal, hidden
        21: unknown:1806           {1806}   internal, hidden
        22: unknown:1813           {1813}   internal, hidden
        23: unknown:1805           {1805}   internal, hidden
        24: unknown:1830           {1830}   internal, hidden
        25: unknown:1890           {1890}   internal, hidden
        26: unknown:1891           {1891}   internal, hidden
        27: unknown:1801           {1801}   internal, hidden
        28: unknown:18A1           {18A1}   internal, hidden
        29: unknown:9280           {9280}   internal, hidden
        30: unknown:1A20           {1A20}   internal, hidden
        31: unknown:1DF3           {1DF3}   internal, hidden
        32: unknown:1E00           {1E00}   hidden
        33: unknown:1EB0           {1EB0}   internal, hidden
        34: unknown:1861           {1861}   internal, hidden
        35: unknown:18B0           {18B0}   internal, hidden
        36: unknown:92C0           {92C0}   internal, hidden
        37: unknown:9203           {9203}   internal, hidden
        38: unknown:3615           {3615}   internal, hidden
     Has 24 reprogrammable keys:
         0: unknown:00D1              , default: unknown:00AE                => unknown:00D1              
             divertable, nonstandard, persistently divertable, pos:0, group:0, gmask:0
         1: unknown:00D2              , default: unknown:00AF                => unknown:00D2              
             divertable, nonstandard, persistently divertable, pos:0, group:0, gmask:0
         2: unknown:00D3              , default: unknown:00B0                => unknown:00D3              
             divertable, nonstandard, persistently divertable, pos:0, group:0, gmask:0
         3: unknown:00C7              , default: unknown:00A3                => unknown:00C7              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:1, group:0, gmask:0
         4: unknown:00C8              , default: unknown:00A4                => unknown:00C8              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:2, group:0, gmask:0
         5: unknown:00E0              , default: unknown:00BF                => unknown:00E0              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:3, group:0, gmask:0
         6: unknown:00E1              , default: unknown:00C0                => unknown:00E1              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:4, group:0, gmask:0
         7: SHOW DESKTOP              , default: ShowDesktop                 => SHOW DESKTOP              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:5, group:0, gmask:0
         8: unknown:00E2              , default: unknown:00C1                => unknown:00E2              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:6, group:0, gmask:0
         9: unknown:00E3              , default: unknown:00C2                => unknown:00E3              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:7, group:0, gmask:0
        10: unknown:00E4              , default: Previous                    => unknown:00E4              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:8, group:0, gmask:0
        11: unknown:00E5              , default: Play/Pause                  => unknown:00E5              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:9, group:0, gmask:0
        12: unknown:00E6              , default: Next                        => unknown:00E6              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:10, group:0, gmask:0
        13: unknown:00E7              , default: Mute                        => unknown:00E7              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:11, group:0, gmask:0
        14: unknown:00E8              , default: Volume Down                 => unknown:00E8              
             divertable, is FN, FN sensitive, persistently divertable, reprogrammable, pos:12, group:0, gmask:0
        15: unknown:00E9              , default: Volume Up                   => unknown:00E9              
             divertable, nonstandard, persistently divertable, reprogrammable, pos:0, group:0, gmask:0
        16: Calculator                , default: Calculator                  => Calculator                
             divertable, nonstandard, persistently divertable, reprogrammable, pos:0, group:0, gmask:0
        17: unknown:00BF              , default: unknown:009B                => unknown:00BF              
             divertable, nonstandard, persistently divertable, reprogrammable, pos:0, group:0, gmask:0
        18: unknown:00EA              , default: unknown:00C3                => unknown:00EA              
             divertable, nonstandard, persistently divertable, reprogrammable, pos:0, group:0, gmask:0
        19: Lock PC                   , default: WindowsLock                 => Lock PC                   
             divertable, nonstandard, persistently divertable, reprogrammable, pos:0, group:0, gmask:0
        20: unknown:00EC              , default: unknown:00B8                => unknown:00EC              
             divertable, nonstandard, persistently divertable, pos:0, group:0, gmask:0
        21: unknown:00EB              , default: unknown:00B6                => unknown:00EB              
             divertable, nonstandard, persistently divertable, pos:0, group:0, gmask:0
        22: unknown:00DE              , default: Do Nothing One              => unknown:00DE              
             is FN, pos:0, group:0, gmask:0
        23: unknown:0034              , default: Do Nothing One              => unknown:0034              
             nonstandard, pos:0, group:0, gmask:0
     Battery: 50%, discharging.

```
It uses the `0x1982` (`Backlight 2`) HID++ 2.0 feature. We need to add support for that.

Resolving patch:
diff --git a/lib/logitech_receiver/descriptors.py b/lib/logitech_receiver/descriptors.py
--- a/lib/logitech_receiver/descriptors.py
+++ b/lib/logitech_receiver/descriptors.py
@@ -220,11 +220,7 @@ def _D(name, codename=None, kind=None, wpid=None, protocol=None, registers=None,
 							_FS.new_fn_swap()
 						],
 				)
-_D('Craft Advanced Keyboard', protocol=4.5, wpid='4066',
-				settings=[
-							_FS.new_fn_swap()
-						],
-				)
+_D('Craft Advanced Keyboard', protocol=4.5, wpid='4066')
 
 
 # Mice
diff --git a/lib/logitech_receiver/hidpp20.py b/lib/logitech_receiver/hidpp20.py
--- a/lib/logitech_receiver/hidpp20.py
+++ b/lib/logitech_receiver/hidpp20.py
@@ -60,6 +60,7 @@
 	LED_CONTROL=0x1300,
 	CHANGE_HOST=0x1814,
 	BACKLIGHT=0x1981,
+	BACKLIGHT2=0x1982,
 	REPROG_CONTROLS=0x1B00,
 	REPROG_CONTROLS_V2=0x1B01,
 	REPROG_CONTROLS_V2_2=0x1B02, # LogiOptions 2.10.73 features.xml
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
@@ -140,6 +140,9 @@ def feature_range(name, feature, min_value, max_value,
 						 	"and you must hold the FN key to activate their special function."))
 _HAND_DETECTION = ('hand-detection', _("Hand Detection"),
 							_("Turn on illumination when the hands hover over the keyboard."))
+_BACKLIGHT = ('backlight', _("Backlight"),
+				   _("Turn illumination on or off on keyboard."))
+
 _SMART_SHIFT = ('smart-shift', _("Smart Shift"),
 							_("Automatically switch the mouse wheel between ratchet and freespin mode.\n"
 							"The mouse wheel is always free at 0, and always locked at 50"))
@@ -189,6 +192,12 @@ def _feature_k375s_fn_swap():
 					label=_FN_SWAP[1], description=_FN_SWAP[2],
 					device_kind=(_DK.keyboard,))
 
+# FIXME: This will enable all supported backlight settings, we should allow the users to select which settings they want to enable.
+def _feature_backlight2():
+	return feature_toggle(_BACKLIGHT[0], _F.BACKLIGHT2,
+						  label=_BACKLIGHT[1], description=_BACKLIGHT[2],
+						  device_kind=(_DK.keyboard,))
+
 def _feature_hi_res_scroll():
 	return feature_toggle(_HI_RES_SCROLL[0], _F.HI_RES_SCROLLING,
 					label=_HI_RES_SCROLL[1], description=_HI_RES_SCROLL[2],
@@ -312,6 +321,7 @@ def _feature_pointer_speed():
 					'dpi',
 					'pointer_speed',
 					'hand_detection',
+					'backlight',
 					'typing_illumination',
 					'smart_shift',
 					])
@@ -330,6 +340,7 @@ def _feature_pointer_speed():
 				dpi=_register_dpi,
 				pointer_speed=None,
 				hand_detection=_register_hand_detection,
+				backlight=None,
 				typing_illumination=None,
 				smart_shift=None,
 			)
@@ -346,6 +357,7 @@ def _feature_pointer_speed():
 				dpi=_feature_adjustable_dpi,
 				pointer_speed=_feature_pointer_speed,
 				hand_detection=None,
+				backlight=_feature_backlight2,
 				typing_illumination=None,
 				smart_shift=_feature_smart_shift,
 			)
@@ -391,3 +403,4 @@ def check_feature(name, featureId, field_name=None):
 	check_feature(_DPI[0],           _F.ADJUSTABLE_DPI)
 	check_feature(_POINTER_SPEED[0], _F.POINTER_SPEED)
 	check_feature(_SMART_SHIFT[0],   _F.SMART_SHIFT)
+	check_feature(_BACKLIGHT[0],   	 _F.BACKLIGHT2)


Test patch: