diff --git a/kmk/extensions/rgb.py b/kmk/extensions/rgb.py index 43e51ab..ad55384 100644 --- a/kmk/extensions/rgb.py +++ b/kmk/extensions/rgb.py @@ -3,6 +3,7 @@ import time from math import e, exp, pi, sin from kmk.extensions import Extension +from kmk.handlers.stock import passthrough as handler_passthrough from kmk.keys import make_key rgb_config = {} @@ -71,24 +72,63 @@ class RGB(Extension): self.disable_auto_write = disable_auto_write self.loopcounter = loopcounter - make_key(names=('RGB_TOG',), on_press=self._rgb_tog) - make_key(names=('RGB_HUI',), on_press=self._rgb_hui) - make_key(names=('RGB_HUD',), on_press=self._rgb_hud) - make_key(names=('RGB_SAI',), on_press=self._rgb_sai) - make_key(names=('RGB_SAD',), on_press=self._rgb_sad) - make_key(names=('RGB_VAI',), on_press=self._rgb_vai) - make_key(names=('RGB_VAD',), on_press=self._rgb_vad) - make_key(names=('RGB_ANI',), on_press=self._rgb_ani) - make_key(names=('RGB_AND',), on_press=self._rgb_and) - make_key(names=('RGB_MODE_PLAIN', 'RGB_M_P'), on_press=self._rgb_mode_static) - make_key(names=('RGB_MODE_BREATHE', 'RGB_M_B'), on_press=self._rgb_mode_breathe) - make_key(names=('RGB_MODE_RAINBOW', 'RGB_M_R'), on_press=self._rgb_mode_rainbow) + make_key( + names=('RGB_TOG',), on_press=self._rgb_tog, on_release=handler_passthrough + ) + make_key( + names=('RGB_HUI',), on_press=self._rgb_hui, on_release=handler_passthrough + ) + make_key( + names=('RGB_HUD',), on_press=self._rgb_hud, on_release=handler_passthrough + ) + make_key( + names=('RGB_SAI',), on_press=self._rgb_sai, on_release=handler_passthrough + ) + make_key( + names=('RGB_SAD',), on_press=self._rgb_sad, on_release=handler_passthrough + ) + make_key( + names=('RGB_VAI',), on_press=self._rgb_vai, on_release=handler_passthrough + ) + make_key( + names=('RGB_VAD',), on_press=self._rgb_vad, on_release=handler_passthrough + ) + make_key( + names=('RGB_ANI',), on_press=self._rgb_ani, on_release=handler_passthrough + ) + make_key( + names=('RGB_AND',), on_press=self._rgb_and, on_release=handler_passthrough + ) + make_key( + names=('RGB_MODE_PLAIN', 'RGB_M_P'), + on_press=self._rgb_mode_static, + on_release=handler_passthrough, + ) + make_key( + names=('RGB_MODE_BREATHE', 'RGB_M_B'), + on_press=self._rgb_mode_breathe, + on_release=handler_passthrough, + ) + make_key( + names=('RGB_MODE_RAINBOW', 'RGB_M_R'), + on_press=self._rgb_mode_rainbow, + on_release=handler_passthrough, + ) make_key( names=('RGB_MODE_BREATHE_RAINBOW', 'RGB_M_BR'), on_press=self._rgb_mode_breathe_rainbow, + on_release=handler_passthrough, + ) + make_key( + names=('RGB_MODE_SWIRL', 'RGB_M_S'), + on_press=self._rgb_mode_swirl, + on_release=handler_passthrough, + ) + make_key( + names=('RGB_MODE_KNIGHT', 'RGB_M_K'), + on_press=self._rgb_mode_knight, + on_release=handler_passthrough, ) - make_key(names=('RGB_MODE_SWIRL', 'RGB_M_S'), on_press=self._rgb_mode_swirl) - make_key(names=('RGB_MODE_KNIGHT', 'RGB_M_K'), on_press=self._rgb_mode_knight) def during_bootup(self, keyboard): pass @@ -500,69 +540,69 @@ class RGB(Extension): return self def _rgb_tog(self, key, state, *args, **kwargs): - if state.pixels.animation_mode == 'static_standby': - state.pixels.animation_mode = 'static' - state.pixels.enabled = not state.pixels.enabled + if self.animation_mode == AnimationModes.STATIC: + self.animation_mode = AnimationModes.STATIC_STANDBY + self.enable = not self.enable return state def _rgb_hui(self, key, state, *args, **kwargs): - state.pixels.increase_hue() + self.increase_hue() return state def _rgb_hud(self, key, state, *args, **kwargs): - state.pixels.decrease_hue() + self.decrease_hue() return state def _rgb_sai(self, key, state, *args, **kwargs): - state.pixels.increase_sat() + self.increase_sat() return state def _rgb_sad(self, key, state, *args, **kwargs): - state.pixels.decrease_sat() + self.decrease_sat() return state def _rgb_vai(self, key, state, *args, **kwargs): - state.pixels.increase_val() + self.increase_val() return state def _rgb_vad(self, key, state, *args, **kwargs): - state.pixels.decrease_val() + self.decrease_val() return state def _rgb_ani(self, key, state, *args, **kwargs): - state.pixels.increase_ani() + self.increase_ani() return state def _rgb_and(self, key, state, *args, **kwargs): - state.pixels.decrease_ani() + self.decrease_ani() return state def _rgb_mode_static(self, key, state, *args, **kwargs): - state.pixels.effect_init = True - state.pixels.animation_mode = 'static' + self.effect_init = True + self.animation_mode = 'static' return state def _rgb_mode_breathe(self, key, state, *args, **kwargs): - state.pixels.effect_init = True - state.pixels.animation_mode = 'breathing' + self.effect_init = True + self.animation_mode = 'breathing' return state def _rgb_mode_breathe_rainbow(self, key, state, *args, **kwargs): - state.pixels.effect_init = True - state.pixels.animation_mode = 'breathing_rainbow' + self.effect_init = True + self.animation_mode = 'breathing_rainbow' return state def _rgb_mode_rainbow(self, key, state, *args, **kwargs): - state.pixels.effect_init = True - state.pixels.animation_mode = 'rainbow' + self.effect_init = True + self.animation_mode = 'rainbow' return state def _rgb_mode_swirl(self, key, state, *args, **kwargs): - state.pixels.effect_init = True - state.pixels.animation_mode = 'swirl' + self.effect_init = True + self.animation_mode = 'swirl' return state def _rgb_mode_knight(self, key, state, *args, **kwargs): - state.pixels.effect_init = True - state.pixels.animation_mode = 'knight' + self.effect_init = True + self.animation_mode = 'knight' return state diff --git a/kmk/hid.py b/kmk/hid.py index cdfcf2a..7fdcb24 100644 --- a/kmk/hid.py +++ b/kmk/hid.py @@ -1,46 +1,48 @@ +import usb_hid +from micropython import const + from kmk.keys import FIRST_KMK_INTERNAL_KEY, ConsumerKey, ModifierKey -from mycropython import const class HIDModes: - NOOP = const(0) # currently unused; for testing? - USB = const(1) - BLE = const(2) # currently unused; for bluetooth + NOOP = 0 # currently unused; for testing? + USB = 1 + BLE = 2 # currently unused; for bluetooth ALL_MODES = (NOOP, USB, BLE) class HIDReportTypes: - KEYBOARD = const(1) - MOUSE = const(2) - CONSUMER = const(3) - SYSCONTROL = const(4) + KEYBOARD = 1 + MOUSE = 2 + CONSUMER = 3 + SYSCONTROL = 4 class HIDUsage: - KEYBOARD = const(0x06) - MOUSE = const(0x02) - CONSUMER = const(0x01) - SYSCONTROL = const(0x80) + KEYBOARD = 0x06 + MOUSE = 0x02 + CONSUMER = 0x01 + SYSCONTROL = 0x80 class HIDUsagePage: - CONSUMER = const(0x0C) - KEYBOARD = MOUSE = SYSCONTROL = const(0x01) + CONSUMER = 0x0C + KEYBOARD = MOUSE = SYSCONTROL = 0x01 HID_REPORT_SIZES = { - HIDReportTypes.KEYBOARD: const(8), - HIDReportTypes.MOUSE: const(4), - HIDReportTypes.CONSUMER: const(2), - HIDReportTypes.SYSCONTROL: const(8), # TODO find the correct value for this + HIDReportTypes.KEYBOARD: 8, + HIDReportTypes.MOUSE: 4, + HIDReportTypes.CONSUMER: 2, + HIDReportTypes.SYSCONTROL: 8, # TODO find the correct value for this } class AbstractHID: - REPORT_BYTES = const(8) + REPORT_BYTES = 8 - def __init__(self, **kwargs): + def __init__(self): self._evt = bytearray(self.REPORT_BYTES) self.report_device = memoryview(self._evt)[0:1] self.report_device[0] = HIDReportTypes.KEYBOARD @@ -54,7 +56,7 @@ class AbstractHID: self.report_mods = memoryview(self._evt)[1:2] self.report_non_mods = memoryview(self._evt)[3:] - self.post_init(**kwargs) + self.post_init() def __repr__(self): return '{}(REPORT_BYTES={})'.format(self.__class__.__name__, self.REPORT_BYTES) @@ -188,14 +190,12 @@ class AbstractHID: class USBHID(AbstractHID): - import usb_hid + REPORT_BYTES = 9 - REPORT_BYTES = const(9) - - def post_init(self, **kwargs): + def post_init(self): self.devices = {} - for device in self.usb_hid.devices: + for device in usb_hid.devices: us = device.usage up = device.usage_page @@ -225,101 +225,106 @@ class USBHID(AbstractHID): class BLEHID(AbstractHID): - from adafruit_ble import BLERadio - from adafruit_ble.advertising.standard import ProvideServicesAdvertisement - from adafruit_ble.services.standard.hid import HIDService + try: + # TODO FIXME This is wrapped in a try block to prevent crashes on M4 devices + from adafruit_ble import BLERadio + from adafruit_ble.advertising.standard import ProvideServicesAdvertisement + from adafruit_ble.services.standard.hid import HIDService - BLE_APPEARANCE_HID_KEYBOARD = const(961) - # Hardcoded in CPy - MAX_CONNECTIONS = const(2) + BLE_APPEARANCE_HID_KEYBOARD = const(961) + # Hardcoded in CPy + MAX_CONNECTIONS = const(2) - def post_init(self, ble_name='KMK Keyboard', **kwargs): - self.conn_id = -1 + def post_init(self, ble_name='KMK Keyboard', **kwargs): + self.conn_id = -1 - self.ble = self.BLERadio() - self.ble.name = ble_name - self.hid = self.HIDService() - self.hid.protocol_mode = 0 # Boot protocol + self.ble = self.BLERadio() + self.ble.name = ble_name + self.hid = self.HIDService() + self.hid.protocol_mode = 0 # Boot protocol - # Security-wise this is not right. While you're away someone turns - # on your keyboard and they can pair with it nice and clean and then - # listen to keystrokes. - # On the other hand we don't have LESC so it's like shouting your - # keystrokes in the air - if not self.ble.connected or not self.hid.devices: - self.start_advertising() + # Security-wise this is not right. While you're away someone turns + # on your keyboard and they can pair with it nice and clean and then + # listen to keystrokes. + # On the other hand we don't have LESC so it's like shouting your + # keystrokes in the air + if not self.ble.connected or not self.hid.devices: + self.start_advertising() - self.conn_id = 0 + self.conn_id = 0 - @property - def devices(self): - '''Search through the provided list of devices to find the ones with the - send_report attribute.''' - if not self.ble.connected: - return [] + @property + def devices(self): + '''Search through the provided list of devices to find the ones with the + send_report attribute.''' + if not self.ble.connected: + return [] - result = [] - # Security issue: - # This introduces a race condition. Let's say you have 2 active - # connections: Alice and Bob - Alice is connection 1 and Bob 2. - # Now Chuck who has already paired with the device in the past - # (this assumption is needed only in the case of LESC) - # wants to gather the keystrokes you send to Alice. You have - # selected right now to talk to Alice (1) and you're typing a secret. - # If Chuck kicks Alice off and is quick enough to connect to you, - # which means quicker than the running interval of this function, - # he'll be earlier in the `self.hid.devices` so will take over the - # selected 1 position in the resulted array. - # If no LESC is in place, Chuck can sniff the keystrokes anyway - for device in self.hid.devices: - if hasattr(device, 'send_report'): - result.append(device) + result = [] + # Security issue: + # This introduces a race condition. Let's say you have 2 active + # connections: Alice and Bob - Alice is connection 1 and Bob 2. + # Now Chuck who has already paired with the device in the past + # (this assumption is needed only in the case of LESC) + # wants to gather the keystrokes you send to Alice. You have + # selected right now to talk to Alice (1) and you're typing a secret. + # If Chuck kicks Alice off and is quick enough to connect to you, + # which means quicker than the running interval of this function, + # he'll be earlier in the `self.hid.devices` so will take over the + # selected 1 position in the resulted array. + # If no LESC is in place, Chuck can sniff the keystrokes anyway + for device in self.hid.devices: + if hasattr(device, 'send_report'): + result.append(device) - return result + return result - def _check_connection(self): - devices = self.devices - if not devices: - return False + def _check_connection(self): + devices = self.devices + if not devices: + return False - if self.conn_id >= len(devices): - self.conn_id = len(devices) - 1 + if self.conn_id >= len(devices): + self.conn_id = len(devices) - 1 - if self.conn_id < 0: - return False + if self.conn_id < 0: + return False - if not devices[self.conn_id]: - return False + if not devices[self.conn_id]: + return False - return True + return True - def hid_send(self, evt): - if not self._check_connection(): - return + def hid_send(self, evt): + if not self._check_connection(): + return - device = self.devices[self.conn_id] + device = self.devices[self.conn_id] - while len(evt) < len(device._characteristic.value) + 1: - evt.append(0) + while len(evt) < len(device._characteristic.value) + 1: + evt.append(0) - return device.send_report(evt[1:]) + return device.send_report(evt[1:]) - def clear_bonds(self): - import _bleio + def clear_bonds(self): + import _bleio - _bleio.adapter.erase_bonding() + _bleio.adapter.erase_bonding() - def next_connection(self): - self.conn_id = (self.conn_id + 1) % len(self.devices) + def next_connection(self): + self.conn_id = (self.conn_id + 1) % len(self.devices) - def previous_connection(self): - self.conn_id = (self.conn_id - 1) % len(self.devices) + def previous_connection(self): + self.conn_id = (self.conn_id - 1) % len(self.devices) - def start_advertising(self): - advertisement = self.ProvideServicesAdvertisement(self.hid) - advertisement.appearance = self.BLE_APPEARANCE_HID_KEYBOARD + def start_advertising(self): + advertisement = self.ProvideServicesAdvertisement(self.hid) + advertisement.appearance = self.BLE_APPEARANCE_HID_KEYBOARD - self.ble.start_advertising(advertisement) + self.ble.start_advertising(advertisement) - def stop_advertising(self): - self.ble.stop_advertising() + def stop_advertising(self): + self.ble.stop_advertising() + + except ImportError: + pass diff --git a/kmk/kmk_keyboard.py b/kmk/kmk_keyboard.py index fd834d9..4b00d64 100644 --- a/kmk/kmk_keyboard.py +++ b/kmk/kmk_keyboard.py @@ -325,6 +325,7 @@ class KMKKeyboard: self._hid_helper = BLEHID else: self._hid_helper = AbstractHID + self._hid_helper = self._hid_helper() def _init_matrix(self): self.matrix = MatrixScanner( @@ -340,7 +341,7 @@ class KMKKeyboard: self._extensions = [] + getattr(self, 'extensions', []) try: - del self._extensions + del self.extensions except Exception: pass finally: diff --git a/user_keymaps/kdb424/nyquist_r2.py b/user_keymaps/kdb424/nyquist_r2.py index ad5fbd6..80610d2 100644 --- a/user_keymaps/kdb424/nyquist_r2.py +++ b/user_keymaps/kdb424/nyquist_r2.py @@ -1,4 +1,6 @@ from kmk.boards.converter.keebio.nyquist_r2 import KMKKeyboard +from kmk.extensions.leader import Leader, LeaderMode +from kmk.extensions.rgb import RGB from kmk.handlers.sequences import send_string, simple_key_sequence from kmk.keys import KC @@ -10,6 +12,7 @@ keyboard.leader_timeout = 2000 keyboard.debug_enabled = False # RGB Config (underglow) +''' keyboard.rgb_config['num_pixels'] = 12 keyboard.rgb_config['val_limit'] = 150 keyboard.rgb_config['hue_step'] = 10 @@ -22,7 +25,7 @@ keyboard.rgb_config['knight_effect_length'] = 4 keyboard.rgb_config['animation_mode'] = 'static' keyboard.rgb_config['animation_speed'] = 1 keyboard.debug_enabled = False - +''' _______ = KC.TRNS XXXXXXX = KC.NO SHFT_INS = KC.LSHIFT(KC.INS)