diff --git a/lib/logitech_receiver/settings_templates.py b/lib/logitech_receiver/settings_templates.py index c474d149d..5025f5070 100644 --- a/lib/logitech_receiver/settings_templates.py +++ b/lib/logitech_receiver/settings_templates.py @@ -1646,7 +1646,7 @@ class PerKeyLighting(_Settings): description = _("Control per-key lighting.") feature = _F.PER_KEY_LIGHTING_V2 keys_universe = _special_keys.KEYCODES - choices_universe = _special_keys.COLORS + choices_universe = _special_keys.COLORSPLUS def read(self, cached=True): self._pre_read(cached) @@ -1654,7 +1654,7 @@ def read(self, cached=True): return self._value reply_map = {} for key in self._validator.choices: - reply_map[int(key)] = 0xFFFFFF # can't read so fake a value of white + reply_map[int(key)] = _special_keys.COLORSPLUS["No change"] # this signals no change self._value = reply_map return reply_map @@ -1663,7 +1663,8 @@ def write(self, map, save=True): self.update(map, save) data_bytes = b"" for key, value in map.items(): - data_bytes += key.to_bytes(1, "big") + value.to_bytes(3, "big") + if value != _special_keys.COLORSPLUS["No change"]: # this signals no change + data_bytes += key.to_bytes(1, "big") + value.to_bytes(3, "big") if len(data_bytes) >= 16: # up to four values are packed into a request self._device.feature_request(self.feature, 0x10, data_bytes) data_bytes = b"" @@ -1673,10 +1674,13 @@ def write(self, map, save=True): return map def write_key_value(self, key, value, save=True): - result = super().write_key_value(int(key), value, save) - if self._device.online: - self._device.feature_request(self.feature, 0x70, 0x00) # signal device to make the change - return result + if value != _special_keys.COLORSPLUS["No change"]: # this signals no change + result = super().write_key_value(int(key), value, save) + if self._device.online: + self._device.feature_request(self.feature, 0x70, 0x00) # signal device to make the change + return result + else: + return True class rw_class(_FeatureRWMap): pass diff --git a/lib/logitech_receiver/special_keys.py b/lib/logitech_receiver/special_keys.py index feb85119f..ca351c516 100644 --- a/lib/logitech_receiver/special_keys.py +++ b/lib/logitech_receiver/special_keys.py @@ -1400,6 +1400,10 @@ def persistent_keys(action_ids): } ) +COLORSPLUS = _UnsortedNamedInts({"No change": -1}) +for i in COLORS: + COLORSPLUS[int(i)] = str(i) + KEYCODES = _NamedInts( { "A": 1, diff --git a/tests/logitech_receiver/test_setting_templates.py b/tests/logitech_receiver/test_setting_templates.py index 84fcf090d..f5add57a7 100644 --- a/tests/logitech_receiver/test_setting_templates.py +++ b/tests/logitech_receiver/test_setting_templates.py @@ -110,6 +110,7 @@ class FeatureTest: matched_calls: int = 1 offset: int = 0x04 version: int = 0x00 + rewrite: bool = False simple_tests = [ @@ -596,12 +597,7 @@ def test_simple_template(test, mocker, mock_gethostname): hidpp.Response("01010300", 0x0440, "01010300"), ), Setup( - FeatureTest( - settings_templates.Gesture2Params, - {4: {"scale": 256}}, - {4: {"scale": 128}}, - 2, - ), + FeatureTest(settings_templates.Gesture2Params, {4: {"scale": 256}}, {4: {"scale": 128}}, 2), *hidpp.responses_gestures, hidpp.Response("000100FF000000000000000000000000", 0x0480, "000100FF"), hidpp.Response("000080FF000000000000000000000000", 0x0480, "000080FF"), @@ -615,29 +611,53 @@ def test_simple_template(test, mocker, mock_gethostname): hidpp.Response("E010", 0x0430, "02E010"), hidpp.Response("E018", 0x0430, "02E018"), ), + Setup( + FeatureTest(settings_templates.PerKeyLighting, {1: -1, 2: -1, 9: -1, 10: -1, 113: -1}, {2: 0xFF0000}, 5, 4, 0, 1), + { + common.NamedInt(1, "A"): special_keys.COLORSPLUS, + common.NamedInt(2, "B"): special_keys.COLORSPLUS, + common.NamedInt(9, "I"): special_keys.COLORSPLUS, + common.NamedInt(10, "J"): special_keys.COLORSPLUS, + common.NamedInt(113, "KEY 113"): special_keys.COLORSPLUS, + }, + hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys + hidpp.Response("00000200000000000000000000000000", 0x0400, "0001"), # second group of keys + hidpp.Response("00000000000000000000000000000000", 0x0400, "0002"), # last group of keys + hidpp.Response("00", 0x0470, "00"), # finish + hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value + hidpp.Response("00", 0x0470, "00"), # finish + hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value + hidpp.Response("00", 0x0470, "00"), # finish + ), Setup( FeatureTest( settings_templates.PerKeyLighting, - {1: 0xFFFFFF, 2: 0xFFFFFF, 9: 0xFFFFFF, 10: 0xFFFFFF, 113: 0xFFFFFF, 114: 0xFFFFFF}, - {2: 0xFF0000}, - 5, + {1: -1, 2: -1, 9: -1, 10: -1, 113: -1}, + {2: 0xFF0000, 9: 0xFF0000, 10: 0xFF0000}, + 9, + 4, + 0, + 1, ), { - common.NamedInt(1, "A"): special_keys.COLORS, - common.NamedInt(2, "B"): special_keys.COLORS, - common.NamedInt(9, "I"): special_keys.COLORS, - common.NamedInt(10, "J"): special_keys.COLORS, - common.NamedInt(113, "KEY 113"): special_keys.COLORS, - common.NamedInt(114, "KEY 114"): special_keys.COLORS, + common.NamedInt(1, "A"): special_keys.COLORSPLUS, + common.NamedInt(2, "B"): special_keys.COLORSPLUS, + common.NamedInt(9, "I"): special_keys.COLORSPLUS, + common.NamedInt(10, "J"): special_keys.COLORSPLUS, + common.NamedInt(113, "KEY 113"): special_keys.COLORSPLUS, }, hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys - hidpp.Response("00000600000000000000000000000000", 0x0400, "0001"), # second group of keys + hidpp.Response("00000200000000000000000000000000", 0x0400, "0001"), # second group of keys hidpp.Response("00000000000000000000000000000000", 0x0400, "0002"), # last group of keys - hidpp.Response("01FFFFFF02FFFFFF09FFFFFF0AFFFFFF", 0x0410, "01FFFFFF02FFFFFF09FFFFFF0AFFFFFF"), # write first 4 values - hidpp.Response("71FFFFFF72FFFFFF", 0x0410, "71FFFFFF72FFFFFF"), # write last two values hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value hidpp.Response("00", 0x0470, "00"), # finish + hidpp.Response("09FF0000", 0x0410, "09FF0000"), # write one value + hidpp.Response("00", 0x0470, "00"), # finish + hidpp.Response("0AFF0000", 0x0410, "0AFF0000"), # write one value + hidpp.Response("00", 0x0470, "00"), # finish + hidpp.Response("02FF000009FF00000AFF0000", 0x0410, "02FF000009FF00000AFF0000"), # write three values + hidpp.Response("00", 0x0470, "00"), # finish ), Setup( FeatureTest(settings_templates.ExtendedAdjustableDpi, {0: 256}, {0: 512}, 2, offset=0x9), @@ -706,9 +726,13 @@ def test_key_template(test, mocker): write_value = setting.write(value) assert write_value == tst.initial_value - for key, value in tst.write_value.items(): - write_value = setting.write_key_value(key, value) - assert write_value == value + for key, val in tst.write_value.items(): + write_value = setting.write_key_value(key, val) + assert write_value == val + value[key] = val + + if tst.rewrite: + write_value = setting.write(value) hidpp.match_requests(tst.matched_calls, test.responses, spy_request.call_args_list)