settings: optimize write for per-key lighting

This commit is contained in:
Peter F. Patel-Schneider 2024-04-30 13:10:39 -04:00
parent e5967edc66
commit da1cb53c1b
2 changed files with 35 additions and 18 deletions

View File

@ -1661,16 +1661,34 @@ class PerKeyLighting(_Settings):
def write(self, map, save=True): def write(self, map, save=True):
if self._device.online: if self._device.online:
self.update(map, save) self.update(map, save)
data_bytes = b"" table = {}
for key, value in map.items(): for key, value in map.items():
if value != _special_keys.COLORSPLUS["No change"]: # this signals no change if value in table:
data_bytes += key.to_bytes(1, "big") + value.to_bytes(3, "big") table[value].append(key) # keys will be in order from small to large
if len(data_bytes) >= 16: # up to four values are packed into a request else:
table[value] = [key]
if len(table) == 1: # use range update
for value, keys in table.items(): # only one, of course
if value != _special_keys.COLORSPLUS["No change"]: # this signals no change, so don't update at all
data_bytes = keys[0].to_bytes(1, "big") + keys[-1].to_bytes(1, "big") + value.to_bytes(3, "big")
self._device.feature_request(self.feature, 0x50, data_bytes) # range update command to update all keys
self._device.feature_request(self.feature, 0x70, 0x00) # signal device to make the changes
else:
data_bytes = b""
for value, keys in table.items(): # only one, of course
if value != _special_keys.COLORSPLUS["No change"]: # this signals no change, so ignore it
while len(keys) > 3: # use an optimized update command that can update up to 13 keys
data = value.to_bytes(3, "big") + b"".join([key.to_bytes(1, "big") for key in keys[0:13]])
self._device.feature_request(self.feature, 0x60, data) # single-value multiple-keys update
keys = keys[13:]
for key in keys:
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 regular update
self._device.feature_request(self.feature, 0x10, data_bytes)
data_bytes = b""
if len(data_bytes) > 0: # update any remaining keys
self._device.feature_request(self.feature, 0x10, data_bytes) self._device.feature_request(self.feature, 0x10, data_bytes)
data_bytes = b"" self._device.feature_request(self.feature, 0x70, 0x00) # signal device to make the changes
if len(data_bytes) > 0:
self._device.feature_request(self.feature, 0x10, data_bytes)
self._device.feature_request(self.feature, 0x70, 0x00) # signal device to make the changes
return map return map
def write_key_value(self, key, value, save=True): def write_key_value(self, key, value, save=True):

View File

@ -612,7 +612,7 @@ key_tests = [
hidpp.Response("E018", 0x0430, "02E018"), hidpp.Response("E018", 0x0430, "02E018"),
), ),
Setup( Setup(
FeatureTest(settings_templates.PerKeyLighting, {1: -1, 2: -1, 9: -1, 10: -1, 113: -1}, {2: 0xFF0000}, 5, 4, 0, 1), FeatureTest(settings_templates.PerKeyLighting, {1: -1, 2: -1, 9: -1, 10: -1, 113: -1}, {2: 0xFF0000}, 4, 4, 0, 1),
{ {
common.NamedInt(1, "A"): special_keys.COLORSPLUS, common.NamedInt(1, "A"): special_keys.COLORSPLUS,
common.NamedInt(2, "B"): special_keys.COLORSPLUS, common.NamedInt(2, "B"): special_keys.COLORSPLUS,
@ -623,7 +623,6 @@ key_tests = [
hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys
hidpp.Response("00000200000000000000000000000000", 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("00000000000000000000000000000000", 0x0400, "0002"), # last group of keys
hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value
@ -634,7 +633,7 @@ key_tests = [
settings_templates.PerKeyLighting, settings_templates.PerKeyLighting,
{1: -1, 2: -1, 9: -1, 10: -1, 113: -1}, {1: -1, 2: -1, 9: -1, 10: -1, 113: -1},
{2: 0xFF0000, 9: 0xFF0000, 10: 0xFF0000}, {2: 0xFF0000, 9: 0xFF0000, 10: 0xFF0000},
9, 8,
4, 4,
0, 0,
1, 1,
@ -649,7 +648,6 @@ key_tests = [
hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys
hidpp.Response("00000200000000000000000000000000", 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("00000000000000000000000000000000", 0x0400, "0002"), # last group of keys
hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("09FF0000", 0x0410, "09FF0000"), # write one value hidpp.Response("09FF0000", 0x0410, "09FF0000"), # write one value
@ -663,8 +661,8 @@ key_tests = [
FeatureTest( FeatureTest(
settings_templates.PerKeyLighting, settings_templates.PerKeyLighting,
{1: -1, 2: -1, 9: -1, 10: -1, 113: -1, 114: -1}, {1: -1, 2: -1, 9: -1, 10: -1, 113: -1, 114: -1},
{2: 0xFF0000, 9: 0xFF0000, 10: 0xFF0000, 113: 0xFF0000, 114: 0x00FF00}, {1: 0xFF0000, 2: 0xFF0000, 9: 0xFF0000, 10: 0xFF0000, 113: 0x00FF00, 114: 0xFF0000},
14, 15,
4, 4,
0, 0,
1, 1,
@ -680,6 +678,7 @@ key_tests = [
hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys hidpp.Response("00000606000000000000000000000000", 0x0400, "0000"), # first group of keys
hidpp.Response("00000600000000000000000000000000", 0x0400, "0001"), # second group of keys hidpp.Response("00000600000000000000000000000000", 0x0400, "0001"), # second group of keys
hidpp.Response("00000000000000000000000000000000", 0x0400, "0002"), # last group of keys hidpp.Response("00000000000000000000000000000000", 0x0400, "0002"), # last group of keys
hidpp.Response("01FF0000", 0x0410, "01FF0000"), # write one value
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value hidpp.Response("02FF0000", 0x0410, "02FF0000"), # write one value
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
@ -687,12 +686,12 @@ key_tests = [
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("0AFF0000", 0x0410, "0AFF0000"), # write one value hidpp.Response("0AFF0000", 0x0410, "0AFF0000"), # write one value
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("71FF0000", 0x0410, "71FF0000"), # write one value hidpp.Response("7100FF00", 0x0410, "7100FF00"), # write one value
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("7200FF00", 0x0410, "7200FF00"), # write one value hidpp.Response("72FF0000", 0x0410, "72FF0000"), # write one value
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
hidpp.Response("02FF000009FF00000AFF000071FF0000", 0x0410, "02FF000009FF00000AFF000071FF0000"), # write four values hidpp.Response("FF00000102090A72", 0x460, "FF00000102090A72"), # write one value for five keys
hidpp.Response("7200FF00", 0x0410, "7200FF00"), # write one value hidpp.Response("7100FF00", 0x0410, "7100FF00"), # write one value
hidpp.Response("00", 0x0470, "00"), # finish hidpp.Response("00", 0x0470, "00"), # finish
), ),
Setup( Setup(