attempt to merge sofubi/static-type-checking, albeit incompletely

This commit is contained in:
Josh Klar
2021-09-27 15:22:23 -07:00
23 changed files with 1436 additions and 290 deletions

View File

@@ -11,3 +11,17 @@ class UnicodeMode:
LINUX = IBUS = const(1)
MACOS = OSX = RALT = const(2)
WINC = const(3)
TYPING_PLATFORMS = [
'linux',
'linux2',
'win32',
'cygwin',
'msys',
'darwin',
'freebsd7',
'freebsd8',
'freebsdN',
'openbsd6',
]

View File

@@ -1,16 +1,21 @@
from kmk.kmk_keyboard import KMKKeyboard
class InvalidExtensionEnvironment(Exception):
pass
class Extension:
_enabled = True
_enabled = True # type: bool
def enable(self, keyboard):
# type: (KMKKeyboard) -> None
self._enabled = True
self.on_runtime_enable(keyboard)
def disable(self, keyboard):
# type (KMKKeyboard) -> None
self._enabled = False
self.on_runtime_disable(keyboard)
@@ -18,34 +23,43 @@ class Extension:
# The below methods should be implemented by subclasses
def on_runtime_enable(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def on_runtime_disable(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def during_bootup(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def before_matrix_scan(self, keyboard):
# type: (KMKKeyboard) -> None
'''
Return value will be injected as an extra matrix update
'''
raise NotImplementedError
def after_matrix_scan(self, keyboard):
# type: (KMKKeyboard) -> None
'''
Return value will be replace matrix update if supplied
'''
raise NotImplementedError
def before_hid_send(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def after_hid_send(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def on_powersave_enable(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError
def on_powersave_disable(self, keyboard):
# type: (KMKKeyboard) -> None
raise NotImplementedError

View File

@@ -1,6 +1,7 @@
'''Adds international keys'''
from kmk.extensions import Extension
from kmk.keys import make_key
from kmk.kmk_keyboard import KMKKeyboard
class International(Extension):
@@ -32,28 +33,37 @@ class International(Extension):
make_key(code=152, names=('LANG9',))
def on_runtime_enable(self, sandbox):
# type: (KMKKeyboard) -> None
return
def on_runtime_disable(self, sandbox):
# type: (KMKKeyboard) -> None
return
def during_bootup(self, sandbox):
# type: (KMKKeyboard) -> None
return
def before_matrix_scan(self, sandbox):
# type: (KMKKeyboard) -> None
return
def after_matrix_scan(self, sandbox):
# type: (KMKKeyboard) -> None
return
def before_hid_send(self, sandbox):
# type: (KMKKeyboard) -> None
return
def after_hid_send(self, sandbox):
# type: (KMKKeyboard) -> None
return
def on_powersave_enable(self, sandbox):
# type: (KMKKeyboard) -> None
return
def on_powersave_disable(self, sandbox):
# type: (KMKKeyboard) -> None
return

View File

@@ -1,11 +1,29 @@
import sys
from time import sleep
from kmk.consts import TYPING_PLATFORMS
if sys.platform in TYPING_PLATFORMS:
from typing import Any, Optional
from kmk.keys import Key, KeyAttrDict
from kmk.kmk_keyboard import KMKKeyboard # Avoid cyclical imports
def passthrough(key, keyboard, *args, **kwargs):
return keyboard
def default_pressed(key, keyboard, KC, coord_int=None, coord_raw=None, *args, **kwargs):
def default_pressed(
key, # type: Key
keyboard, # type: KMKKeyboard
KC, # type: KeyAttrDict
coord_int=None, # type: Optional[int]
coord_raw=None, # type: Optional[str]
*args, # type: Any
**kwargs, # type: Any
):
# type: (...) -> KMKKeyboard
keyboard.hid_pending = True
keyboard.keys_pressed.add(key)
@@ -14,8 +32,15 @@ def default_pressed(key, keyboard, KC, coord_int=None, coord_raw=None, *args, **
def default_released(
key, keyboard, KC, coord_int=None, coord_raw=None, *args, **kwargs # NOQA
key, # type: Key
keyboard, # type: KMKKeyboard
KC, # type: KeyAttrDict
coord_int=None, # type: Optional[int]
coord_raw=None, # type: Optional[str]
*args, # type: Any
**kwargs, # type: Any # NOQA
):
# type: (...) -> KMKKeyboard
keyboard.hid_pending = True
keyboard.keys_pressed.discard(key)

View File

@@ -1,3 +1,6 @@
import sys
from kmk.consts import TYPING_PLATFORMS
from kmk.types import (
KeySeqSleepMeta,
LayerKeyMeta,
@@ -6,12 +9,20 @@ from kmk.types import (
UnicodeModeKeyMeta,
)
if sys.platform in TYPING_PLATFORMS:
from typing import List, Optional
# Avoid cyclical imports
from kmk.keys import Key
def key_seq_sleep_validator(ms):
# type: (float) -> KeySeqSleepMeta
return KeySeqSleepMeta(ms)
def layer_key_validator(layer, kc=None):
# type: (int, Optional[Key]) -> LayerKeyMeta
'''
Validates the syntax (but not semantics) of a layer key call. We won't
have access to the keymap here, so we can't verify much of anything useful
@@ -22,7 +33,8 @@ def layer_key_validator(layer, kc=None):
return LayerKeyMeta(layer=layer, kc=kc)
def mod_tap_validator(kc, mods=None):
def mod_tap_validator(kc, mods):
# type: (Key, Optional[List[Key]]) -> ModTapKeyMeta
'''
Validates that mod tap keys are correctly used
'''
@@ -30,8 +42,10 @@ def mod_tap_validator(kc, mods=None):
def tap_dance_key_validator(*codes):
# type: (*Key) -> TapDanceKeyMeta
return TapDanceKeyMeta(codes)
def unicode_mode_key_validator(mode):
# type: (int) -> UnicodeModeKeyMeta
return UnicodeModeKeyMeta(mode)

View File

@@ -1,3 +1,8 @@
from typing import NoReturn
from kmk.kmk_keyboard import KMKKeyboard
class InvalidExtensionEnvironment(Exception):
pass
@@ -12,29 +17,29 @@ class Module:
# The below methods should be implemented by subclasses
def during_bootup(self, keyboard):
def during_bootup(self, keyboard: KMKKeyboard) -> NoReturn:
raise NotImplementedError
def before_matrix_scan(self, keyboard):
def before_matrix_scan(self, keyboard: KMKKeyboard) -> NoReturn:
'''
Return value will be injected as an extra matrix update
'''
raise NotImplementedError
def after_matrix_scan(self, keyboard):
def after_matrix_scan(self, keyboard: KMKKeyboard) -> NoReturn:
'''
Return value will be replace matrix update if supplied
'''
raise NotImplementedError
def before_hid_send(self, keyboard):
def before_hid_send(self, keyboard: KMKKeyboard) -> NoReturn:
raise NotImplementedError
def after_hid_send(self, keyboard):
def after_hid_send(self, keyboard: KMKKeyboard) -> NoReturn:
raise NotImplementedError
def on_powersave_enable(self, keyboard):
def on_powersave_enable(self, keyboard: KMKKeyboard) -> NoReturn:
raise NotImplementedError
def on_powersave_disable(self, keyboard):
def on_powersave_disable(self, keyboard: KMKKeyboard) -> NoReturn:
raise NotImplementedError

View File

@@ -1,66 +1,89 @@
import digitalio
from supervisor import ticks_ms
from typing import Any, ClassVar, Dict, List, Optional, Tuple, Union
from kmk.keys import Key
from kmk.kmk_keyboard import KMKKeyboard
from kmk.kmktime import ticks_ms
from kmk.modules import Module
EncoderMap = Tuple[
List[Tuple[Key, Key, int]],
List[Tuple[Key, Key, int]],
List[Tuple[None, None, int]],
]
class EncoderPadState:
OFF = False
ON = True
OFF: bool = False
ON: bool = True
class EndcoderDirection:
Left = False
Right = True
Left: bool = False
Right: bool = True
class Encoder:
def __init__(
self,
pad_a,
pad_b,
button_pin=None,
):
self.pad_a = self.PreparePin(pad_a) # board pin for enc pin a
self.pad_a_state = False
self.pad_b = self.PreparePin(pad_b) # board pin for enc pin b
self.pad_b_state = False
self.button_pin = self.PreparePin(button_pin) # board pin for enc btn
pad_a: Any,
pad_b: Any,
button_pin: Optional[Any] = None,
) -> None:
self.pad_a: Union[digitalio.DigitalInOut, None] = self.PreparePin(
pad_a
) # board pin for enc pin a
self.pad_a_state: bool = False
self.pad_b: Union[digitalio.DigitalInOut, None] = self.PreparePin(
pad_b
) # board pin for enc pin b
self.pad_b_state: bool = False
self.button_pin: Union[digitalio.DigitalInOut, None] = self.PreparePin(
button_pin
) # board pin for enc btn
self.button_state = None # state of pushbutton on encoder if enabled
self.encoder_value = 0 # clarify what this value is
self.encoder_state = (
self.encoder_value: int = 0 # clarify what this value is
self.encoder_state: Tuple[bool, bool] = (
self.pad_a_state,
self.pad_b_state,
) # quaderature encoder state
self.encoder_direction = None # arbitrary, tells direction of knob
self.last_encoder_state = None # not used yet
self.resolution = 2 # number of keys sent per position change
self.revolution_count = 20 # position changes per revolution
self.has_button = False # enable/disable button functionality
self.encoder_data = None # 6tuple containing all encoder data
self.position_change = None # revolution count, inc/dec as knob turns
self.last_encoder_value = 0 # not used
self.is_inverted = False # switch to invert knob direction
self.vel_mode = False # enable the velocity output
self.vel_ts = None # velocity timestamp
self.last_vel_ts = 0 # last velocity timestamp
self.encoder_speed = None # ms per position change(4 states)
self.encoder_map = None
self.eps = EncoderPadState()
self.encoder_pad_lookup = {
self.encoder_direction: Optional[
bool
] = None # arbitrary, tells direction of knob
self.last_encoder_state: Optional[Tuple[bool, bool]] = None # not used yet
self.resolution: int = 2 # number of keys sent per position change
self.revolution_count: int = 20 # position changes per revolution
self.has_button: bool = False # enable/disable button functionality
self.encoder_data: Optional[Tuple] = None # 6tuple containing all encoder data
self.position_change: Optional[
int
] = None # revolution count, inc/dec as knob turns
self.last_encoder_value: int = 0 # not used
self.is_inverted: bool = False # switch to invert knob direction
self.vel_mode: bool = False # enable the velocity output
self.vel_ts: Optional[float] = None # velocity timestamp
self.last_vel_ts: float = 0 # last velocity timestamp
self.encoder_speed: Optional[float] = None # ms per position change(4 states)
self.encoder_map: Optional[EncoderMap] = None
self.eps: EncoderPadState = EncoderPadState()
self.encoder_pad_lookup: Dict[bool, bool] = {
False: self.eps.OFF,
True: self.eps.ON,
}
self.edr = EndcoderDirection() # lookup for current encoder direction
self.encoder_dir_lookup = {
self.edr: EndcoderDirection = (
EndcoderDirection()
) # lookup for current encoder direction
self.encoder_dir_lookup: Dict[bool, bool] = {
False: self.edr.Left,
True: self.edr.Right,
}
def __repr__(self, idx):
def __repr__(self, idx: int) -> str:
return 'ENCODER_{}({})'.format(idx, self._to_dict())
def _to_dict(self):
def _to_dict(self) -> Dict[str, Any]:
return {
'Encoder_State': self.encoder_state,
'Direction': self.encoder_direction,
@@ -71,7 +94,7 @@ class Encoder:
}
# adapted for CircuitPython from raspi
def PreparePin(self, num):
def PreparePin(self, num: Union[Any, None]) -> Union[digitalio.DigitalInOut, None]:
if num is not None:
pad = digitalio.DigitalInOut(num)
pad.direction = digitalio.Direction.INPUT
@@ -81,7 +104,7 @@ class Encoder:
return None
# checks encoder pins, reports encoder data
def report(self):
def report(self) -> Union[int, None]:
new_encoder_state = (
self.encoder_pad_lookup[int(self.pad_a.value)],
self.encoder_pad_lookup[int(self.pad_b.value)],
@@ -143,14 +166,14 @@ class Encoder:
return None
# invert knob direction if encoder pins are soldered backwards
def invert_rotation(self, new, old):
def invert_rotation(self, new: int, old: int) -> int:
if self.is_inverted:
return -(new - old)
else:
return new - old
# returns knob velocity as milliseconds between position changes(detents)
def vel_report(self):
def vel_report(self) -> float:
self.encoder_speed = self.vel_ts - self.last_vel_ts
self.last_vel_ts = self.vel_ts
return self.encoder_speed
@@ -158,50 +181,54 @@ class Encoder:
class EncoderHandler(Module):
encoders = []
debug_enabled = False # not working as inttended, do not use for now
encoders: ClassVar[List[Encoder]] = []
debug_enabled: ClassVar[
bool
] = False # not working as inttended, do not use for now
def __init__(self, pad_a, pad_b, encoder_map):
self.pad_a = pad_a
self.pad_b = pad_b
self.encoder_count = len(self.pad_a)
self.encoder_map = encoder_map
def __init__(
self, pad_a: List[Any], pad_b: List[Any], encoder_map: EncoderMap
) -> None:
self.pad_a: List[Any] = pad_a
self.pad_b: List[Any] = pad_b
self.encoder_count: int = len(self.pad_a)
self.encoder_map: EncoderMap = encoder_map
self.make_encoders()
def on_runtime_enable(self, keyboard):
def on_runtime_enable(self, keyboard: KMKKeyboard) -> None:
return
def on_runtime_disable(self, keyboard):
def on_runtime_disable(self, keyboard: KMKKeyboard) -> None:
return
def during_bootup(self, keyboard):
def during_bootup(self, keyboard: KMKKeyboard) -> None:
return
def before_matrix_scan(self, keyboard):
def before_matrix_scan(self, keyboard: KMKKeyboard) -> Union[KMKKeyboard, None]:
'''
Return value will be injected as an extra matrix update
'''
return self.get_reports(keyboard)
def after_matrix_scan(self, keyboard):
def after_matrix_scan(self, keyboard: KMKKeyboard) -> None:
'''
Return value will be replace matrix update if supplied
'''
return
def before_hid_send(self, keyboard):
def before_hid_send(self, keyboard: KMKKeyboard) -> None:
return
def after_hid_send(self, keyboard):
def after_hid_send(self, keyboard: KMKKeyboard) -> None:
return
def on_powersave_enable(self, keyboard):
def on_powersave_enable(self, keyboard: KMKKeyboard) -> None:
return
def on_powersave_disable(self, keyboard):
def on_powersave_disable(self, keyboard: KMKKeyboard) -> None:
return
def make_encoders(self):
def make_encoders(self) -> None:
for i in range(self.encoder_count):
self.encoders.append(
Encoder(
@@ -210,7 +237,9 @@ class EncoderHandler(Module):
)
)
def send_encoder_keys(self, keyboard, encoder_key, encoder_idx):
def send_encoder_keys(
self, keyboard: KMKKeyboard, encoder_key: int, encoder_idx: int
) -> KMKKeyboard:
# position in the encoder map tuple
encoder_resolution = 2
for _ in range(
@@ -221,7 +250,7 @@ class EncoderHandler(Module):
)
return keyboard
def get_reports(self, keyboard):
def get_reports(self, keyboard: KMKKeyboard) -> Union[KMKKeyboard, None]:
for idx in range(self.encoder_count):
if self.debug_enabled: # not working as inttended, do not use for now
print(self.encoders[idx].__repr__(idx))

View File

@@ -4,21 +4,24 @@ from supervisor import ticks_ms
from time import sleep
from typing import Any, Dict, Optional
from kmk.handlers.stock import passthrough as handler_passthrough
from kmk.keys import make_key
from kmk.keys import Key, make_key
from kmk.kmk_keyboard import KMKKeyboard
from kmk.kmktime import check_deadline
from kmk.modules import Module
class Power(Module):
def __init__(self, powersave_pin=None):
self.enable = False
def __init__(self, powersave_pin: Optional[Any] = None) -> None:
self.enable: bool = False
self.powersave_pin = powersave_pin # Powersave pin board object
self._powersave_start = ticks_ms()
self._usb_last_scan = ticks_ms() - 5000
self._psp = None # Powersave pin object
self._i2c = 0
self._loopcounter = 0
self._powersave_start: float = ticks_ms()
self._usb_last_scan: float = ticks_ms() - 5000
self._psp: Optional[digitalio.DigitalInOut] = None # Powersave pin object
self._i2c: int = 0
self._loopcounter: int = 0
make_key(
names=('PS_TOG',), on_press=self._ps_tog, on_release=handler_passthrough
@@ -30,10 +33,10 @@ class Power(Module):
names=('PS_OFF',), on_press=self._ps_disable, on_release=handler_passthrough
)
def __repr__(self):
def __repr__(self) -> str:
return f'Power({self._to_dict()})'
def _to_dict(self):
def _to_dict(self) -> Dict[str, Any]:
return {
'enable': self.enable,
'powersave_pin': self.powersave_pin,
@@ -42,24 +45,24 @@ class Power(Module):
'_psp': self._psp,
}
def during_bootup(self, keyboard):
def during_bootup(self, keyboard: KMKKeyboard) -> None:
self._i2c_scan()
def before_matrix_scan(self, keyboard):
def before_matrix_scan(self, keyboard: KMKKeyboard) -> None:
return
def after_matrix_scan(self, keyboard):
def after_matrix_scan(self, keyboard: KMKKeyboard) -> None:
if keyboard.matrix_update or keyboard.secondary_matrix_update:
self.psave_time_reset()
def before_hid_send(self, keyboard):
def before_hid_send(self, keyboard: KMKKeyboard) -> None:
return
def after_hid_send(self, keyboard):
def after_hid_send(self, keyboard: KMKKeyboard) -> None:
if self.enable:
self.psleep()
def on_powersave_enable(self, keyboard):
def on_powersave_enable(self, keyboard: KMKKeyboard) -> None:
'''Gives 10 cycles to allow other extensions to clean up before powersave'''
if self._loopcounter > 10:
self.enable_powersave(keyboard)
@@ -68,11 +71,11 @@ class Power(Module):
self._loopcounter += 1
return
def on_powersave_disable(self, keyboard):
def on_powersave_disable(self, keyboard: KMKKeyboard) -> None:
self.disable_powersave(keyboard)
return
def enable_powersave(self, keyboard):
def enable_powersave(self, keyboard: KMKKeyboard) -> None:
'''Enables power saving features'''
if keyboard.i2c_deinit_count >= self._i2c and self.powersave_pin:
# Allows power save to prevent RGB drain.
@@ -88,7 +91,7 @@ class Power(Module):
keyboard._trigger_powersave_enable = False
return
def disable_powersave(self, keyboard):
def disable_powersave(self, keyboard: KMKKeyboard) -> None:
'''Disables power saving features'''
if self._psp:
self._psp.value = False
@@ -99,7 +102,7 @@ class Power(Module):
self.enable = False
return
def psleep(self):
def psleep(self) -> None:
'''
Sleeps longer and longer to save power the more time in between updates.
'''
@@ -109,10 +112,10 @@ class Power(Module):
sleep(180 / 1000)
return
def psave_time_reset(self):
def psave_time_reset(self) -> None:
self._powersave_start = ticks_ms()
def _i2c_scan(self):
def _i2c_scan(self) -> None:
i2c = board.I2C()
while not i2c.try_lock():
pass
@@ -122,28 +125,46 @@ class Power(Module):
i2c.unlock()
return
def usb_rescan_timer(self):
def usb_rescan_timer(self) -> bool:
return bool(check_deadline(ticks_ms(), self._usb_last_scan) > 5000)
def usb_time_reset(self):
def usb_time_reset(self) -> None:
self._usb_last_scan = ticks_ms()
return
def usb_scan(self):
def usb_scan(self) -> bool:
# TODO Add USB detection here. Currently lies that it's connected
# https://github.com/adafruit/circuitpython/pull/3513
return True
def _ps_tog(self, key, keyboard, *args, **kwargs):
def _ps_tog(
self,
key: Key,
keyboard: KMKKeyboard,
*args: Any,
**kwargs: Any,
) -> None:
if self.enable:
keyboard._trigger_powersave_disable = True
else:
keyboard._trigger_powersave_enable = True
def _ps_enable(self, key, keyboard, *args, **kwargs):
def _ps_enable(
self,
key: Key,
keyboard: KMKKeyboard,
*args: Any,
**kwargs: Any,
) -> None:
if not self.enable:
keyboard._trigger_powersave_enable = True
def _ps_disable(self, key, keyboard, *args, **kwargs):
def _ps_disable(
self,
key: Key,
keyboard: KMKKeyboard,
*args: Any,
**kwargs: Any,
) -> None:
if self.enable:
keyboard._trigger_powersave_disable = True

View File

@@ -4,22 +4,26 @@ from micropython import const
from supervisor import ticks_ms
from storage import getmount
from typing import Any, List, Optional, Type, Union
from kmk.kmk_keyboard import KMKKeyboard
from kmk.kmktime import check_deadline
from kmk.matrix import intify_coordinate
from kmk.modules import Module
UartBuffer = List[Optional[Union[bytes, None]]]
class SplitSide:
LEFT = const(1)
RIGHT = const(2)
LEFT: int = const(1)
RIGHT: int = const(2)
class SplitType:
UART = const(1)
I2C = const(2) # unused
ONEWIRE = const(3) # unused
BLE = const(4)
UART: int = const(1)
I2C: int = const(2) # unused
ONEWIRE: int = const(3) # unused
BLE: int = const(4)
class Split(Module):
@@ -27,56 +31,58 @@ class Split(Module):
def __init__(
self,
split_flip=True,
split_side=None,
split_type=SplitType.UART,
split_target_left=True,
uart_interval=20,
data_pin=None,
data_pin2=None,
target_left=True,
uart_flip=True,
debug_enabled=False,
):
self._is_target = True
self._uart_buffer = []
self.split_flip = split_flip
self.split_side = split_side
self.split_type = split_type
self.split_target_left = split_target_left
self.split_offset = None
self.data_pin = data_pin
self.data_pin2 = data_pin2
self.target_left = target_left
self.uart_flip = uart_flip
self._is_target = True
self._uart = None
self._uart_interval = uart_interval
self._debug_enabled = debug_enabled
split_flip: bool = True,
split_side: Optional[int] = None,
split_type: int = SplitType.UART,
split_target_left: bool = True,
uart_interval: int = 20,
data_pin: Optional[Any] = None,
data_pin2: Optional[Any] = None,
target_left: bool = True,
uart_flip: bool = True,
debug_enabled: bool = False,
) -> None:
self._is_target: bool = True
self._uart_buffer: UartBuffer = []
self.split_flip: bool = split_flip
self.split_side: Optional[int] = split_side
self.split_type: int = split_type
self.split_target_left: bool = split_target_left
self.split_offset: Optional[int] = None
self.data_pin: Optional[Any] = data_pin
self.data_pin2: Optional[Any] = data_pin2
self.target_left: bool = target_left
self.uart_flip: bool = uart_flip
self._is_target: bool = True
self._uart: Optional[busio.UART] = None
self._uart_interval: int = uart_interval
self._debug_enabled: bool = debug_enabled
if self.split_type == SplitType.BLE:
try:
from adafruit_ble import BLERadio
from adafruit_ble import BLEConnection, BLERadio
from adafruit_ble.advertising.standard import (
ProvideServicesAdvertisement,
)
from adafruit_ble.services.nordic import UARTService
self.ProvideServicesAdvertisement = ProvideServicesAdvertisement
self.UARTService = UARTService
self.ProvideServicesAdvertisement: Type[
ProvideServicesAdvertisement
] = ProvideServicesAdvertisement
self.UARTService: Type[UARTService] = UARTService
except ImportError:
print('BLE Import error')
return # BLE isn't supported on this platform
self._ble = BLERadio()
self._ble_last_scan = ticks_ms() - 5000
self._connection_count = 0
self._uart_connection = None
self._advertisment = None
self._advertising = False
self._psave_enable = False
self._ble: BLERadio = BLERadio()
self._ble_last_scan: float = ticks_ms() - 5000
self._connection_count: int = 0
self._uart_connection: Optional[BLEConnection] = None
self._advertisment: Optional[ProvideServicesAdvertisement] = None
self._advertising: bool = False
self._psave_enable: bool = False
def during_bootup(self, keyboard):
def during_bootup(self, keyboard: KMKKeyboard) -> None:
# Set up name for target side detection and BLE advertisment
name = str(getmount('/').label)
name: str = str(getmount('/').label)
if self.split_type == SplitType.BLE:
self._ble.name = name
else:
@@ -128,7 +134,7 @@ class Split(Module):
for cidx in range(cols_to_calc):
keyboard.coord_mapping.append(intify_coordinate(ridx, cidx))
def before_matrix_scan(self, keyboard):
def before_matrix_scan(self, keyboard: KMKKeyboard) -> None:
if self.split_type == SplitType.BLE:
self._check_all_connections()
self._receive_ble(keyboard)
@@ -139,7 +145,7 @@ class Split(Module):
pass # Protocol needs written
return
def after_matrix_scan(self, keyboard):
def after_matrix_scan(self, keyboard: KMKKeyboard) -> None:
if keyboard.matrix_update:
if self.split_type == SplitType.UART and self._is_target:
pass # explicit pass just for dev sanity...
@@ -156,28 +162,28 @@ class Split(Module):
return
def before_hid_send(self, keyboard):
def before_hid_send(self, keyboard: KMKKeyboard) -> None:
if not self._is_target:
keyboard.hid_pending = False
return
def after_hid_send(self, keyboard):
def after_hid_send(self, keyboard: KMKKeyboard) -> None:
return
def on_powersave_enable(self, keyboard):
def on_powersave_enable(self, keyboard: KMKKeyboard) -> None:
if self.split_type == SplitType.BLE:
if self._uart_connection and not self._psave_enable:
self._uart_connection.connection_interval = self._uart_interval
self._psave_enable = True
def on_powersave_disable(self, keyboard):
def on_powersave_disable(self, keyboard: KMKKeyboard) -> None:
if self.split_type == SplitType.BLE:
if self._uart_connection and self._psave_enable:
self._uart_connection.connection_interval = 11.25
self._psave_enable = False
def _check_all_connections(self):
def _check_all_connections(self) -> None:
'''Validates the correct number of BLE connections'''
self._connection_count = len(self._ble.connections)
if self._is_target and self._connection_count < 2:
@@ -185,7 +191,7 @@ class Split(Module):
elif not self._is_target and self._connection_count < 1:
self._initiator_scan()
def _initiator_scan(self):
def _initiator_scan(self) -> None:
'''Scans for target device'''
self._uart = None
self._uart_connection = None
@@ -218,7 +224,7 @@ class Split(Module):
break
self._ble.stop_scan()
def _target_advertise(self):
def _target_advertise(self) -> None:
'''Advertises the target for the initiator to find'''
self._ble.stop_advertising()
if self._debug_enabled:
@@ -240,15 +246,15 @@ class Split(Module):
break
self._ble.stop_advertising()
def ble_rescan_timer(self):
def ble_rescan_timer(self) -> bool:
'''If true, the rescan timer is up'''
return bool(check_deadline(ticks_ms(), self._ble_last_scan) > 5000)
def ble_time_reset(self):
def ble_time_reset(self) -> None:
'''Resets the rescan timer'''
self._ble_last_scan = ticks_ms()
def _send_ble(self, update):
def _send_ble(self, update: List) -> None:
if self._uart:
try:
if not self._is_target:
@@ -266,7 +272,7 @@ class Split(Module):
self._uart_connection = None
self._uart = None
def _receive_ble(self, keyboard):
def _receive_ble(self, keyboard: KMKKeyboard) -> None:
if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
while self._uart.in_waiting >= 3:
self._uart_buffer.append(self._uart.read(3))
@@ -274,7 +280,7 @@ class Split(Module):
keyboard.secondary_matrix_update = bytearray(self._uart_buffer.pop(0))
return
def _send_uart(self, update):
def _send_uart(self, update: List) -> None:
# Change offsets depending on where the data is going to match the correct
# matrix location of the receiever
if self._is_target:
@@ -291,7 +297,7 @@ class Split(Module):
if self._uart is not None:
self._uart.write(update)
def _receive_uart(self, keyboard):
def _receive_uart(self, keyboard: KMKKeyboard) -> None:
if self._uart is not None and self._uart.in_waiting > 0 or self._uart_buffer:
if self._uart.in_waiting >= 60:
# This is a dirty hack to prevent crashes in unrealistic cases

View File

@@ -1,3 +1,14 @@
import sys
from kmk.consts import TYPING_PLATFORMS
if sys.platform in TYPING_PLATFORMS:
from typing import List, Optional, Tuple, Union
# Avoid cyclical imports
from kmk.keys import ConsumerKey, Key, ModifierKey
class AttrDict(dict):
'''
Primitive support for accessing dictionary entries in dot notation.
@@ -8,36 +19,43 @@ class AttrDict(dict):
'''
def __getattr__(self, key):
# type: (str) -> Optional[Union[Key, ModifierKey, ConsumerKey]]
return self[key]
class LayerKeyMeta:
def __init__(self, layer, kc=None):
self.layer = layer
self.kc = kc
# type: (int, Optional[Key]) -> None
self.layer = layer # type: int
self.kc = kc # type: Optional[Key]
class ModTapKeyMeta:
def __init__(self, kc=None, mods=None):
self.mods = mods
self.kc = kc
# type: (Optional[Key], Optional[List[Key]]) -> None
self.mods = mods # type: Optional[List[Key]]
self.kc = kc # type: Optional[Key]
class KeySequenceMeta:
def __init__(self, seq):
self.seq = seq
# type: (List[Key]) -> None
self.seq = seq # type: List[Key]
class KeySeqSleepMeta:
def __init__(self, ms):
self.ms = ms
# type: (float) -> None
self.ms = ms # type: float
class UnicodeModeKeyMeta:
def __init__(self, mode):
self.mode = mode
# type: (int) -> None
self.mode = mode # type: int
class TapDanceKeyMeta:
def __init__(self, codes):
self.codes = codes
# type: (Tuple[Key, ...]) -> None
self.codes = codes # type: Tuple[Key, ...]