logitech_receiver: split Test condition

This commit is contained in:
Vinícius 2022-03-10 17:09:59 -03:00 committed by Peter F. Patel-Schneider
parent 54b79d9f13
commit f327e3ad38
2 changed files with 31 additions and 10 deletions

View File

@ -83,22 +83,22 @@ string argument. Alternatively, if the argument is a list `[name, action]` wher
is either `'pressed'` or `'released'`, the key down or key up events of `name` argument are is either `'pressed'` or `'released'`, the key down or key up events of `name` argument are
matched, respectively. Logitech key and button names are shown in the `Key/Button Diversion` matched, respectively. Logitech key and button names are shown in the `Key/Button Diversion`
setting. Some keyboards have Gn, Mn, or MR keys, which are diverted using the 'Divert G Keys' setting. setting. Some keyboards have Gn, Mn, or MR keys, which are diverted using the 'Divert G Keys' setting.
`Test` conditions are true if their test evaluates to true on the feature, `Test` and `TestBytes` conditions are true if their test evaluates to true on the feature,
report, and data of the current notification. report, and data of the current notification.
Test conditions can return a number instead of a boolean. Test conditions can return a number instead of a boolean.
Test conditions consisting of a sequence of three or four integers use the first `TestBytes` conditions consist of a sequence of three or four integers and use the first
two to select bytes of the notification data. two to select bytes of the notification data.
Writing this kind of test condition is not trivial. Writing this kind of test condition is not trivial.
Three-element test conditions are true if the selected bytes bit-wise anded Three-element `TestBytes` conditions are true if the selected bytes bit-wise anded
with its third element is non-zero. with its third element is non-zero.
The value of these test conditions is the result of the and. The value of these test conditions is the result of the and.
Four-element test conditions are true if the selected bytes form a signed Four-element `TestBytes` conditions are true if the selected bytes form a signed
integer between the third and fourth elements. integer between the third and fourth elements.
The value of these test condition is the signed value of the selected bytes The value of these test condition is the signed value of the selected bytes
if that is non-zero otherwise True. if that is non-zero otherwise True.
The other test conditions are mnemonic shorthands for meaningful feature, `Test` conditions are mnemonic shorthands for meaningful feature,
report, and data combinations in notifications. report, and data combinations in notifications.
A `crown_right` test is the rotation amount of a `CROWN` right rotation notification. A `crown_right` test is the rotation amount of a `CROWN` right rotation notification.
A `crown_left` test is the rotation amount of a `CROWN` left rotation notification. A `crown_left` test is the rotation amount of a `CROWN` left rotation notification.

View File

@ -553,11 +553,10 @@ class Test(Condition):
else: else:
_log.warn('rule Test string argument not name of a test: %s', test) _log.warn('rule Test string argument not name of a test: %s', test)
self.function = TESTS['False'] self.function = TESTS['False']
elif ( elif isinstance(test, list) and all(isinstance(t, int) for t in test):
isinstance(test, list) and 2 < len(test) <= 4 and all(isinstance(t, int) for t in test) and test[0] >= 0 _log.warn('Test rules consisting of numbers are deprecated, converting to a TestBytes condition')
and test[0] <= 16 and test[1] >= 0 and test[1] <= 16 and test[0] < test[1] self.__class__ = TestBytes
): self.__init__(test)
self.function = bit_test(*test) if len(test) == 3 else range_test(*test)
else: else:
_log.warn('rule Test argument not valid %s', test) _log.warn('rule Test argument not valid %s', test)
@ -571,6 +570,27 @@ class Test(Condition):
return {'Test': str(self.test)} return {'Test': str(self.test)}
class TestBytes(Condition):
def __init__(self, test):
self.test = test
if (
isinstance(test, list) and 2 < len(test) <= 4 and all(isinstance(t, int) for t in test) and test[0] >= 0
and test[0] <= 16 and test[1] >= 0 and test[1] <= 16 and test[0] < test[1]
):
self.function = bit_test(*test) if len(test) == 3 else range_test(*test)
else:
_log.warn('rule TestBytes argument not valid %s', test)
def __str__(self):
return 'TestBytes: ' + str(self.test)
def evaluate(self, feature, notification, device, status, last_result):
return self.function(feature, notification.address, notification.data)
def data(self):
return {'TestBytes': str(self.test)}
class MouseGesture(Condition): class MouseGesture(Condition):
MOVEMENTS = [ MOVEMENTS = [
'Mouse Up', 'Mouse Down', 'Mouse Left', 'Mouse Right', 'Mouse Up-left', 'Mouse Up-right', 'Mouse Down-left', 'Mouse Up', 'Mouse Down', 'Mouse Left', 'Mouse Right', 'Mouse Up-left', 'Mouse Up-right', 'Mouse Down-left',
@ -860,6 +880,7 @@ COMPONENTS = {
'Modifiers': Modifiers, 'Modifiers': Modifiers,
'Key': Key, 'Key': Key,
'Test': Test, 'Test': Test,
'TestBytes': TestBytes,
'MouseGesture': MouseGesture, 'MouseGesture': MouseGesture,
'KeyPress': KeyPress, 'KeyPress': KeyPress,
'MouseScroll': MouseScroll, 'MouseScroll': MouseScroll,