feat: Added automatic loading of Apps from the macropad_apps/python directory at load time.

Performance improvements to the lighting system.
Renamed app_router to macropad_os.
This commit is contained in:
Lucas Oskorep
2022-09-20 00:44:42 -04:00
parent d95d351bfd
commit 26ce2d1734
8 changed files with 72 additions and 34 deletions
+1
View File
@@ -116,3 +116,4 @@ dmypy.json
.idea* .idea*
config.json
+28 -10
View File
@@ -1,22 +1,40 @@
from macropad_os import AppRouter, SerialComms, Config import os
from macropad_os import MacropadOS, SerialComms, Config, App
from adafruit_macropad import MacroPad from adafruit_macropad import MacroPad
from macropad_apps.python import NumpadApp
macropad = MacroPad() macropad = MacroPad()
default_config = Config("default_config.json").load() default_config = Config("default_config.json").load()
config = Config("config.json").load(default_config) config = Config("config.json").load(default_config)
ar = AppRouter(macropad, config, [ PYTHON_APP_FOLDER = "./macropad_apps/python"
NumpadApp(macropad, config),
# Arrow Keys
# Script Runner
])
sc = SerialComms(config) apps = []
files = os.listdir(PYTHON_APP_FOLDER)
files.sort()
app_classes = []
for filename in files:
if filename.endswith('.py') and not filename.startswith('._'):
try:
print(filename)
module = __import__(PYTHON_APP_FOLDER + '/' + filename[:-3])
classes = [getattr(module, a) for a in dir(module)
if isinstance(getattr(module, a), type)]
for cls in classes:
if issubclass(cls, App) and cls.__name__ != "App":
app_classes.append(cls)
print(app_classes)
except (SyntaxError, ImportError, AttributeError, KeyError, NameError, IndexError, TypeError) as err:
print("ERROR in", filename)
import traceback
traceback.print_exception(err, err, err.__traceback__)
ar = MacropadOS(macropad, config, apps=app_classes)
# sc = SerialComms(config)
# _thread.start_new_thread(sc.run, (sc)) # _thread.start_new_thread(sc.run, (sc))
ar.start() ar.start()
-1
View File
@@ -1 +0,0 @@
from .numpad import NumpadApp
+12 -4
View File
@@ -1,8 +1,10 @@
from time import monotonic_ns
import terminalio import terminalio
from adafruit_display_text.bitmap_label import Label from adafruit_display_text.bitmap_label import Label
from adafruit_display_text.scrolling_label import ScrollingLabel
from adafruit_displayio_layout.layouts.grid_layout import GridLayout from adafruit_displayio_layout.layouts.grid_layout import GridLayout
from adafruit_hid.keycode import Keycode
from rainbowio import colorwheel from rainbowio import colorwheel
from macropad_os import App from macropad_os import App
@@ -24,6 +26,8 @@ modified_labels = [
] ]
COLOR_UPDATE_RATE = 50000000 # .05 seconds
class NumpadApp(App): class NumpadApp(App):
def __init__(self, macropad, config): def __init__(self, macropad, config):
@@ -34,6 +38,7 @@ class NumpadApp(App):
self.labels = [] self.labels = []
self.title = "Numpad" self.title = "Numpad"
self.modifier_pressed = False self.modifier_pressed = False
self.last_color_update = 0
def on_start(self): def on_start(self):
print("on start from the app!") print("on start from the app!")
@@ -65,6 +70,10 @@ class NumpadApp(App):
def update_key_colors(self): def update_key_colors(self):
self.wheel_offset += 1 self.wheel_offset += 1
colors = [] colors = []
last_update_ago = monotonic_ns() - self.last_color_update
if last_update_ago > COLOR_UPDATE_RATE:
self.last_color_update = monotonic_ns()
for pixel in range(12): for pixel in range(12):
if self.lit_keys[pixel]: if self.lit_keys[pixel]:
(r, g, b) = rgb_from_int(colorwheel((pixel / 12 * 256) + self.wheel_offset)) (r, g, b) = rgb_from_int(colorwheel((pixel / 12 * 256) + self.wheel_offset))
@@ -74,12 +83,11 @@ class NumpadApp(App):
self.set_colors(colors) self.set_colors(colors)
def process_keys_pressed_callback(self, keyevent): def process_keys_pressed_callback(self, keyevent):
print("PROCESS KEYS CALLBACK FROM DEBUG")
print(keyevent) print(keyevent)
self.keyboard.send(Keycode.SHIFT,Keycode.SHIFT,Keycode.SHIFT, Keycode.A)
def process_keys_released_callback(self, keyevent): def process_keys_released_callback(self, keyevent):
print("PROCESS KEYS RELEASED CALLBACK FROM DEBUG")
print(keyevent) print(keyevent)
def process_enbcoder_changed(self, keyevent): def process_enbcoder_changed(self, keyevent):
print("PROCESS Encoder Changed Callback FROM DEBUG")
print(keyevent) print(keyevent)
+1 -1
View File
@@ -2,4 +2,4 @@ from .serial_communications import SerialComms
from .configuration import Config, ConfigItem from .configuration import Config, ConfigItem
from .app_state import AppState, InvalidStateUpdateError from .app_state import AppState, InvalidStateUpdateError
from .abstract_app import App from .abstract_app import App
from .app_router import AppRouter from .macropad_os import MacropadOS
+19 -14
View File
@@ -1,4 +1,4 @@
import time from time import monotonic_ns
import displayio import displayio
import terminalio import terminalio
@@ -12,6 +12,9 @@ DISPLAY = displayio.Group()
def convert_to_keynum(x, y): def convert_to_keynum(x, y):
return 3 * x + y return 3 * x + y
#TODO: Limit sounds to a similar rate as well for better performance
MAX_LIGHTING_UPDATE_RATE = 50000000 # .05 seconds
class App(object): class App(object):
@@ -42,10 +45,12 @@ class App(object):
self._state = AppState.STOPPED self._state = AppState.STOPPED
self._name = "app" self._name = "app"
self._key_tones = {} self._key_tones = {}
self._last_lighting_update = 0
self._current_brightness = config.brightness() self._current_brightness = config.brightness()
self.macropad = macropad self.macropad = macropad
self.keyboard = macropad.keyboard
self.config = config self.config = config
def start(self) -> None: def start(self) -> None:
@@ -86,7 +91,7 @@ class App(object):
self._state = AppState.PAUSED self._state = AppState.PAUSED
def _on_pause(self) -> None: def _on_pause(self) -> None:
self.macropad.keyboard.release_all() self.keyboard.release_all()
self.macropad.consumer_control.release() self.macropad.consumer_control.release()
self.macropad.mouse.release_all() self.macropad.mouse.release_all()
self.macropad.stop_tone() self.macropad.stop_tone()
@@ -116,7 +121,6 @@ class App(object):
if key_event.key_number < 12: if key_event.key_number < 12:
if key_event.pressed: if key_event.pressed:
self.macropad.stop_tone() self.macropad.stop_tone()
print(self.config.get_items())
self._play_tone_for_key(key_event.key_number) self._play_tone_for_key(key_event.key_number)
if self._key_pressed_callbacks: if self._key_pressed_callbacks:
for callback in self._key_pressed_callbacks: for callback in self._key_pressed_callbacks:
@@ -124,7 +128,7 @@ class App(object):
else: else:
self._stop_tone_for_key(key_event.key_number) self._stop_tone_for_key(key_event.key_number)
if self._key_released_callbacks: if self._key_released_callbacks:
for callback in self._key_pressed_callbacks: for callback in self._key_released_callbacks:
callback(key_event.key_number) callback(key_event.key_number)
def _play_tone_for_key(self, key_number): def _play_tone_for_key(self, key_number):
@@ -169,16 +173,17 @@ class App(object):
raise NotImplementedError("on_stop not implemented.") raise NotImplementedError("on_stop not implemented.")
def _update_lighting(self) -> None: def _update_lighting(self) -> None:
new_brightness = self.config.brightness() last_update_ago = monotonic_ns() - self._last_lighting_update
if self._current_brightness != new_brightness: if last_update_ago > MAX_LIGHTING_UPDATE_RATE:
print("SETTING BRIGHTNESS!!!!") self._last_lighting_update = monotonic_ns()
print(self._key_lights) new_brightness = self.config.brightness()
self._key_lights = [tuple(rgb_val * new_brightness / self._current_brightness for rgb_val in color) for if self._current_brightness != new_brightness:
color in self._key_lights] # Setting the brightness here
print(self._key_lights) self._key_lights = [tuple(rgb_val * new_brightness / self._current_brightness for rgb_val in color) for
self._current_brightness = self.config.brightness() color in self._key_lights]
for index, color in enumerate(self._key_lights): self._current_brightness = self.config.brightness()
self.macropad.pixels[index] = color for index, color in enumerate(self._key_lights):
self.macropad.pixels[index] = color
def add_displays_to_group(self) -> None: def add_displays_to_group(self) -> None:
self._display_group.append(self._title_label) self._display_group.append(self._title_label)
+6
View File
@@ -0,0 +1,6 @@
from adafruit_hid.keycode import Keycode
class Key(object):
def __init__(self, name, keycode:Keycodes):
self.name = name
self.code = keycode
@@ -4,14 +4,14 @@ from .app_state import AppState
from macropad_os.system_apps import OptionsApp, DebugApp from macropad_os.system_apps import OptionsApp, DebugApp
class AppRouter(object): class MacropadOS(object):
def __init__(self, macropad, config, apps): def __init__(self, macropad, config, apps):
print("app router") print("app router")
self.macropad = macropad self.macropad = macropad
self.app_index = 0 self.app_index = 0
self.apps = apps self.apps = [a(macropad, config) for a in apps]
self.options = OptionsApp(macropad, config) self.options = OptionsApp(macropad, config)
self.current_app = apps[self.app_index] self.current_app = self.apps[self.app_index]
self.config = config self.config = config
self.encoder_state = False self.encoder_state = False
self.options_time = 500000000 # .5 seconds in nanoseconds self.options_time = 500000000 # .5 seconds in nanoseconds
@@ -39,6 +39,7 @@ class AppRouter(object):
self.current_app.resume() self.current_app.resume()
def start(self) -> None: def start(self) -> None:
print(self.current_app)
self.current_app.start() self.current_app.start()
self.current_app.resume() self.current_app.resume()