Files
macropad/KeyboardStateManager.py

117 lines
3.4 KiB
Python
Executable File

from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.keycode import Keycode
from adafruit_rgbled import RGBLED
import digitalio
from adafruit_mcp230xx.mcp23017 import MCP23017
import busio
import board
import usb_hid
PRESSED = False
UNPRESSED = True
MCP_ADDRESS = 32
PINOUT = [
[7, 11, 15, 0],
[8, 4, 14, 1],
[6, 10, 13, 2],
[9, 5, 12, 3]
]
class KeyboardStateManager:
active_layer: int
state: list[list[int]]
keymap: list[list[Keycode]]
pinout: list[list[int]]
pins: list[list[digitalio.DigitalInOut]]
keyboard: Keyboard
keyboard_layout: KeyboardLayoutUS
mcp: MCP23017
led: RGBLED
def __init__(self, keymap: list[list[Keycode]]):
self.keymap = keymap
self.keyboard = Keyboard(usb_hid.devices)
self.keyboard_layout = KeyboardLayoutUS(self.keyboard)
self.initialize_io_extender()
self.initialize_pins(PINOUT)
self.initialize_led()
def initialize_led(self) -> None:
self.led = RGBLED(board.LED_R, board.LED_G, board.LED_B, True)
self.reset_led()
def initialize_io_extender(self) -> None:
self.mcp = MCP23017(busio.I2C(board.GP1, board.GP0), MCP_ADDRESS)
def initialize_pins(self, pinout: list[list[int]]) -> None:
self.pinout = pinout
self.pins = []
self.state = []
for pinout_row in self.pinout:
pin_row = []
previous_state_row = []
for pinout in pinout_row:
pin = self.mcp.get_pin(pinout)
pin.direction = digitalio.Direction.INPUT
pin.pull = digitalio.Pull.UP
pin_row.append(pin)
previous_state_row.append(UNPRESSED)
self.pins.append(pin_row)
self.state.append(previous_state_row)
def loop(self):
for row in self.pins:
for pin in row:
row_index, pin_index = self.pins.index(row), row.index(pin)
keycode = self.keymap[row_index][pin_index]
previously = self.state[row_index][pin_index]
key = pin.value == UNPRESSED
if key is PRESSED:
if previously is UNPRESSED:
self.keyboard.press(keycode)
self.set_led((1, 0, 0))
if key is UNPRESSED:
if previously is PRESSED:
self.keyboard.release(keycode)
self.reset_led()
self.state[row_index][pin_index] = key
def set_led(self, value: tuple[int, int, int]):
self.led.color = value
def reset_led(self):
self.led.color = (0, 255, 0)
# Create interface for key of different type
# interface has method to handle keypress and release and gets access to key keyboards state and keyboard instance
# keyboard state should be increased with layer
# layer keys take a type, a set layer, and a color combination
# class LayerKeyType(Enum):
# hold = 1
# toggle = 2
# def handle_key(raw_keymap:list[list]]):
# for row in raw_keymap:
# for key in row:
# if key in Keycode:
# # handle as keycode
# pass
# if key.
# class LayerKey:
# type: LayerKeyType
# def __init__(self, type: LayerKeyType, layer: int):
# class KeycodeKey:
# def __init__(self):
# pass