diff --git a/lib/logitech_receiver/settings_templates.py b/lib/logitech_receiver/settings_templates.py index 903c74ff..47021924 100644 --- a/lib/logitech_receiver/settings_templates.py +++ b/lib/logitech_receiver/settings_templates.py @@ -1466,6 +1466,50 @@ class LEDControl(_Setting): validator_options = {"choices": choices_universe} +class BrightnessControl(_Setting): + name = "brightness_control" + label = _("Brightness Control") + description = _("Control overall brightness") + feature = _F.BRIGHTNESS_CONTROL + rw_options = {"read_fnid": 0x10, "write_fnid": 0x20} + validator_class = _RangeV + + def __init__(self, device, rw, validator): + super().__init__(device, rw, validator) + rw.on_off = validator.on_off + rw.min_nonzero_value = validator.min_value + validator.min_value = 0 if validator.on_off else validator.min_value + + class rw_class(_FeatureRW): + def read(self, device, data_bytes=b""): + if self.on_off: + reply = device.feature_request(self.feature, 0x30) + if not reply[0] & 0x01: + return b"\x00\x00" + return super().read(device, data_bytes) + + def write(self, device, data_bytes): + if self.on_off: + off = int.from_bytes(data_bytes, byteorder="big") < self.min_nonzero_value + reply = device.feature_request(self.feature, 0x40, b"\x00" if off else b"\x01", no_reply=False) + if off: + return reply + return super().write(device, data_bytes) + + class validator_class(_RangeV): + @classmethod + def build(cls, setting_class, device): + reply = device.feature_request(_F.BRIGHTNESS_CONTROL) + assert reply, "Oops, brightness range cannot be retrieved!" + if reply: + max_value = int.from_bytes(reply[0:2], byteorder="big") + min_value = int.from_bytes(reply[4:6], byteorder="big") + on_off = bool(reply[3] & 0x04) # separate on/off control + validator = cls(min_value=min_value, max_value=max_value, byte_count=2) + validator.on_off = on_off + return validator + + colors = _special_keys.COLORS _LEDP = hidpp20.LEDParam @@ -1534,6 +1578,7 @@ SETTINGS = [ Backlight3, LEDControl, LEDZoneSetting, + BrightnessControl, FnSwap, # simple NewFnSwap, # simple K375sFnSwap, # working diff --git a/tests/logitech_receiver/test_setting_templates.py b/tests/logitech_receiver/test_setting_templates.py index 25e307f7..64a2285f 100644 --- a/tests/logitech_receiver/test_setting_templates.py +++ b/tests/logitech_receiver/test_setting_templates.py @@ -445,6 +445,43 @@ tests = [ hidpp.Response("0201", 0x0400), hidpp.Response(True, 0x0410, "00"), ], + [ + FeatureTest(settings_templates.BrightnessControl, 0x10, 0x20, 0x20, "0020", False), + [0, 80], + hidpp.Response("040003", 0x0000, "8040"), # BRIGHTNESS_CONTROL + hidpp.Response("00505100000000", 0x0400), # 0 to 80, all acceptable, no separate on/off + hidpp.Response("10", 0x0410), # brightness 16 + hidpp.Response("0020", 0x0420, "0020"), # set brightness 32 + ], + [ + FeatureTest(settings_templates.BrightnessControl, 0x10, 0x00, 0x20, "0000", False), + [0, 80], + hidpp.Response("040003", 0x0000, "8040"), # BRIGHTNESS_CONTROL + hidpp.Response("00505104000000", 0x0400), # 0 to 80, all acceptable, separate on/off + hidpp.Response("10", 0x0410), # brightness 16 + hidpp.Response("01", 0x0430), # on + hidpp.Response("00", 0x0440), # set off + hidpp.Response("0000", 0x0420, "0000"), # set brightness 0 + ], + [ + FeatureTest(settings_templates.BrightnessControl, 0x00, 0x20, 0x20, "0020", False), + [0, 80], + hidpp.Response("040003", 0x0000, "8040"), # BRIGHTNESS_CONTROL + hidpp.Response("00505104000000", 0x0400), # 0 to 80, all acceptable, separate on/off + hidpp.Response("10", 0x0410), # brightness 16 + hidpp.Response("00", 0x0430), # off + hidpp.Response("01", 0x0440), # set on + hidpp.Response("0020", 0x0420, "0020"), # set brightness 32 + ], + [ + FeatureTest(settings_templates.BrightnessControl, 0x20, 0x08, 0x40, "00", False), + [0, 80], + hidpp.Response("040003", 0x0000, "8040"), # BRIGHTNESS_CONTROL + hidpp.Response("00504104001000", 0x0400), # 16 to 80, all acceptable, separate on/off + hidpp.Response("20", 0x0410), # brightness 32 + hidpp.Response("01", 0x0430), # on + hidpp.Response("00", 0x0440, "00"), # set off + ], ]