Repository: pwr-Solaar/Solaar

Issue:
Back-light settings/timeouts for k830 and k800
I'd like my k830 to:

First, always use the brightest back-light setting (I've tried put tape over the light sensor but pressing the light  key over rides it, I'd light the light key to just toggle brightest setting on/off)

Second, increase the back-light time out, ideally at least 30 sec. when unplugged and 30min. when =plugged in..

Third, I'd like be able toggle on/off the left click on the top corner, and the touchpad, both are good for more accidental inputs than intentional, and I use this with a g700s mouse so I couls do without mouse functionality all together..

Lastly, I assume using this from a live cd is no problem, but do the the changes commit to the keyboard and persist across various Os's or are they stored in an external file??

Thanks..


Discussion:
Are these requested features something that's available in the official software from Logitech? Especially the control of the backlight timer sound to me like something that might not be possible due to lack of support for it in the hardware, but I might be wrong.
 No logitech does not support this, I went ahead and tried solaar/unbuntu live cd setup and it looks like it's a no go.  I read a thread about someone getting to the back-light timeout on a k800 via solaar, but the k800 is based off a k520 vs the k830 being based on a k400 so no crossover in the settings. 

And while logitech is great at telling you what they can't/won't do asking the most basic ? go unanswered. So maybe you might know, when I install ":setpoint" on my win 10 machine I can pair the k830 no problem but their is no "keyboard" tab in setpoint, the ? is there supposed to  be?
Putting tape over your sensor puts the backlight to dimmed instead of the by you desired bright. You better glue a permanent lit led to the sensor or bridge it internally with an adequate resistor
There have been several changes to solaar over the past couple of years so this issue may have already been addressed.

If you are still using solaar and this issue has not been resolved please download and run the current version from this github repository. If the problem still persists add a new comment here, providing the output of `solaar -V` and `solaar show` and any new information about the issue.

If you are still using solaar you should be able to download and run its current version (in Linux) as follows:

1. Install git on your machine if it is not already installed. This is generally done via `sudo apt install git` or `sudo dnf install git`
2. Change to a directory where you want the code.
3. Download solaar via `git clone https://github.com/pwr-Solaar/Solaar.git`
4. Run solaar via `Solaar/bin/solaar`

For more information on installing solaar from github see https://github.com/pwr-Solaar/Solaar/blob/master/docs/installation.md

Closing due to no response from original poster.
Yes, setting a light timeout is a Logitech-supported feature: https://support.logi.com/hc/en-us/articles/360023396093-Customizing-my-K800-keyboard-with-Logitech-SetPoint-Software.

Could you re-consider this feature, please.

Thank you for Solaar (either way).
For Solaar to support this feature, we'll need the output of `solaar show` for the keyboard to see what interfaces the keyboard supports.
FYI: SetPoint is older software from Logitech. "Options" is supposedly newer:
- https://support.logi.com/hc/en-sg/articles/360025141274-SetPoint for Windows 10/11 6.70.55 Last Update: 2021-02-01
- https://support.logi.com/hc/en-us/articles/360025297893 for Windows 10  9.40.86 Last Update: 2021-09-28
Both are self-extracting EXE's. If you open them (from Firefox) on (Manjaro) Linux, it opens them in an archive extractor app.

However, neither runs with WINE, nor with PlayOnLinux 4 (out of the box as they come for current Manjaro 5.16.0-1); I don't have Phoenicis/PlayOnLinux 5 working well, but I don't think it would run it (out of the box) either. Two other people reported that they couldn't run SetPoint in WINE (years ago). So if you want to run it for comparison... you most likely need Windows.
The Logitech software includes Windows low-level drivers and is thus likely not to run on Linux without a lot of work.

The way to start to get backlight working for K830 under Solaar is for someone with the keyboard to install a recent version of Solaar, ideally the one in this repository, and run `solaar show`.
From GIT master. (I have it paired with two K800 keyboards, one at my girlfriend's house).
```
Solaar version 1.1.1

Unifying Receiver
  Device path  : /dev/hidraw2
  USB id       : 046d:C52B
  Serial       : 90479C9A
    Firmware   : 12.11.B0032
    Bootloader : 04.16
    Other      : AA.AA
  Has 3 paired device(s) out of a maximum of 6.
  Notifications: wireless, software present (0x000900)
  Device activity counters: 3=235, 4=120

  2: Wireless Illuminated Keyboard K800 new
     Device path  : /dev/hidraw3
     WPID         : 406E
     Codename     : K800 new
     Kind         : keyboard
     Protocol     : HID++ 4.5
     Polling rate : 20 ms (50Hz)
     Serial number: 313FBE10
     The power switch is located on the top right corner.
     Battery: unknown (device is offline).

  3: Wireless Illuminated Keyboard K800 new
     Device path  : /dev/hidraw4
     WPID         : 406E
     Codename     : K800 new
     Kind         : keyboard
     Protocol     : HID++ 4.5
     Polling rate : 20 ms (50Hz)
     Serial number: 55BC980D
     Model ID:      406E00000000
     Unit ID:       0EB87B3B
        Bootloader: BOT 60.00.B0002
          Firmware: RQK 68.01.B0009
     The power switch is located on the top right corner.
     Supports 25 HID++ 2.0 features:
         0: ROOT                   {0000}   
         1: FEATURE SET            {0001}   
         2: DEVICE FW VERSION      {0003}   
            Firmware: Bootloader BOT 60.00.B0002 406ED4E7454501
            Firmware: Firmware RQK 68.01.B0009 406ED4E7454501
            Unit ID: 0EB87B3B  Model ID: 406E00000000  Transport IDs: {'wpid': '406E'}
         3: DEVICE NAME            {0005}   
            Name: Wireless Illuminated Keyboard K800
            Kind: keyboard
         4: WIRELESS DEVICE STATUS {1D4B}   
         5: RESET                  {0020}   
         6: BATTERY STATUS         {1000}   
            Battery: 50%, discharging, next level 20%.
         7: BACKLIGHT3             {1983}   
         8: REPROG CONTROLS V4     {1B04}   
            Key/Button Diversion (saved): {'1': 0, '10': 0, '14': 0, '2': 0, '226': 0, '227': 0, '3': 0, '34': 0, '4': 0, '40': 0, '5': 0, '6': 0, '62': 0, '64': 0, '8': 0}
            Key/Button Diversion        : {'34': 0, '14': 0, '62': 0, '8': 0, '226': 0, '227': 0, '64': 0, '40': 0, '6': 0, '4': 0, '5': 0, '1': 0, '2': 0, '3': 0, '10': 0}
         9: FN INVERSION           {40A0}   
            Swap Fx function (saved): False
            Swap Fx function        : False
        10: ENCRYPTION             {4100}   
        11: KEYBOARD DISABLE KEYS  {4521}   
            Disable keys (saved): {'1': False, '16': False, '2': False, '4': False, '8': False}
            Disable keys        : {'1': False, '2': False, '4': False, '8': False, '16': False}
        12: DFUCONTROL SIGNED      {00C2}   
        13: unknown:1803           {1803}   internal, hidden
        14: CONFIG DEVICE PROPS    {1806}   internal, hidden
        15: unknown:1811           {1811}   internal, hidden
        16: unknown:1830           {1830}   internal, hidden
        17: unknown:1890           {1890}   internal, hidden
        18: unknown:18A1           {18A1}   internal, hidden
        19: unknown:1DF3           {1DF3}   internal, hidden
        20: unknown:1E00           {1E00}   hidden
        21: unknown:1EB0           {1EB0}   internal, hidden
        22: unknown:1861           {1861}   internal, hidden
        23: unknown:1A20           {1A20}   internal, hidden
        24: unknown:18B0           {18B0}   internal, hidden
     Has 15 reprogrammable keys:
         0: My Home                   , default: HomePage                    => HomePage                  
             is FN, FN sensitive, reprogrammable, divertable, pos:1, group:0, group mask:empty
             reporting: default
         1: Mail                      , default: Email                       => Email                     
             is FN, FN sensitive, reprogrammable, divertable, pos:2, group:0, group mask:empty
             reporting: default
         2: Search                    , default: Search Files                => Search Files              
             is FN, FN sensitive, reprogrammable, divertable, pos:3, group:0, group mask:empty
             reporting: default
         3: Application Switcher      , default: Application Switcher        => Application Switcher      
             is FN, FN sensitive, reprogrammable, divertable, pos:4, group:0, group mask:empty
             reporting: default
         4: Backlight Down            , default: Backlight Down              => Backlight Down            
             is FN, FN sensitive, divertable, pos:5, group:0, group mask:empty
             reporting: default
         5: Backlight Up              , default: Backlight Up                => Backlight Up              
             is FN, FN sensitive, divertable, pos:6, group:0, group mask:empty
             reporting: default
         6: Sleep                     , default: Sleep                       => Sleep                     
             is FN, FN sensitive, reprogrammable, divertable, pos:8, group:0, group mask:empty
             reporting: default
         7: Media Player              , default: Music                       => Music                     
             is FN, FN sensitive, reprogrammable, divertable, pos:9, group:0, group mask:empty
             reporting: default
         8: Previous                  , default: Previous                    => Previous                  
             is FN, FN sensitive, divertable, pos:10, group:0, group mask:empty
             reporting: default
         9: Play/Pause                , default: Play/Pause                  => Play/Pause                
             is FN, FN sensitive, divertable, pos:11, group:0, group mask:empty
             reporting: default
        10: Next                      , default: Next                        => Next                      
             is FN, FN sensitive, divertable, pos:12, group:0, group mask:empty
             reporting: default
        11: Volume Up                 , default: Volume Up                   => Volume Up                 
             nonstandard, divertable, pos:0, group:0, group mask:empty
             reporting: default
        12: Volume Down               , default: Volume Down                 => Volume Down               
             nonstandard, divertable, pos:0, group:0, group mask:empty
             reporting: default
        13: Mute                      , default: Mute                        => Mute                      
             nonstandard, divertable, pos:0, group:0, group mask:empty
             reporting: default
        14: Calculator                , default: Calculator                  => Calculator                
             nonstandard, reprogrammable, divertable, pos:0, group:0, group mask:empty
             reporting: default
     Battery: 50%, discharging, next level 20%.

  4: Wireless Mouse M325
  ...
```
Thanks.   I'll try to find documentation of the feature BACKLIGHT3  {1983}.
You guys think it would be possible to use something like AutoHotKey, or Java, or Python to write a script to press a key at a set interval? Or even a touch of the touchpad to keep the backlight on or prevent the kb from sleeping?

Resolving patch:
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
@@ -71,6 +71,7 @@
     DFUCONTROL_LEGACY=0x00C0,
     DFUCONTROL_UNSIGNED=0x00C1,
     DFUCONTROL_SIGNED=0x00C2,
+    DFUCONTROL=0x00C3,
     DFU=0x00D0,
     BATTERY_STATUS=0x1000,
     BATTERY_VOLTAGE=0x1001,
@@ -161,6 +162,7 @@
     LATENCY_MONITORING=0x8111,
     GAMING_ATTACHMENTS=0x8120,
     FORCE_FEEDBACK=0x8123,
+    # Headsets
     SIDETONE=0x8300,
     EQUALIZER=0x8310,
     HEADSET_OUT=0x8320,
diff --git a/lib/logitech_receiver/settings.py b/lib/logitech_receiver/settings.py
--- a/lib/logitech_receiver/settings.py
+++ b/lib/logitech_receiver/settings.py
@@ -687,15 +687,12 @@ def write(self, device, data_bytes):
 
 
 class FeatureRW:
-    __slots__ = ('feature', 'read_fnid', 'write_fnid', 'prefix', 'no_reply')
-
     kind = _NamedInt(0x02, _('feature'))
     default_read_fnid = 0x00
     default_write_fnid = 0x10
-    default_prefix = b''
 
     def __init__(
-        self, feature, read_fnid=default_read_fnid, write_fnid=default_write_fnid, prefix=default_prefix, no_reply=False
+        self, feature, read_fnid=default_read_fnid, write_fnid=default_write_fnid, prefix=b'', suffix=b'', no_reply=False
     ):
         assert isinstance(feature, _NamedInt)
         self.feature = feature
@@ -703,6 +700,7 @@ def __init__(
         self.write_fnid = write_fnid
         self.no_reply = no_reply
         self.prefix = prefix
+        self.suffix = suffix
 
     def read(self, device, data_bytes=b''):
         assert self.feature is not None
@@ -710,7 +708,9 @@ def read(self, device, data_bytes=b''):
 
     def write(self, device, data_bytes):
         assert self.feature is not None
-        reply = device.feature_request(self.feature, self.write_fnid, self.prefix, data_bytes, no_reply=self.no_reply)
+        reply = device.feature_request(
+            self.feature, self.write_fnid, self.prefix, data_bytes, self.suffix, no_reply=self.no_reply
+        )
         return reply if not self.no_reply else True
 
 
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
@@ -197,14 +197,33 @@ class K375sFnSwap(FnSwapVirtual):
     validator_options = {'true_value': b'\x01', 'false_value': b'\x00', 'read_skip_byte_count': 1}
 
 
-# we should allow the users to select which settings they want to enable.
+class Backlight(_Setting):
+    name = 'backlight-qualitative'
+    description = _('Set illumination time for keyboard.')
+    feature = _F.BACKLIGHT
+    choices_universe = _NamedInts(Off=0, Short=5, Medium=20, Long=60, VeryLong=180)
+    validator_class = _ChoicesV
+    validator_options = {'choices': choices_universe}
+
+
 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'
+    description = _('Set illumination time for keyboard.')
+    feature = _F.BACKLIGHT3
+    rw_options = {'read_fnid': 0x10, 'write_fnid': 0x20, 'suffix': 0x09}
+    validator_class = _RangeV
+    min_value = 0
+    max_value = 1000
+    validator_options = {'byte_count': 2}
+
+
 class HiResScroll(_Setting):
     name = 'hi-res-scroll'
     label = _('Scroll Wheel High Resolution')
@@ -1045,7 +1064,9 @@ def read(self, device):  # no way to read, so just assume off
     DpiSliding,  # working
     SpeedChange,
     MouseGesture,  # working
+    Backlight,
     Backlight2,  # working
+    Backlight3,
     FnSwap,  # simple
     NewFnSwap,  # simple
     K375sFnSwap,  # working


Test patch: