1
+ """
2
+ Add description here
3
+ """
4
+
5
+ # pylint: disable=import-error, unused-import, too-few-public-methods, eval-used
6
+
7
+ import json
8
+ import os
1
9
import time
2
10
import board
3
11
import digitalio
4
- import rotaryio
5
- import neopixel
6
- import json
7
- import os
8
-
9
12
import displayio
13
+ import neopixel
14
+ import rotaryio
10
15
import terminalio
11
- from adafruit_display_text import label
12
-
13
16
import usb_hid
17
+ from adafruit_display_text import label
14
18
from adafruit_hid .keyboard import Keyboard
15
19
from adafruit_hid .keycode import Keycode
16
20
17
- #from adafruit_hid.mouse import Mouse
18
- #from adafruit_hid.consumer_control import ConsumerControl
19
- #from adafruit_hid.consumer_control_code import ConsumerControlCode
20
-
21
- MACRO_FOLDER = '/'
22
-
23
- DISPLAY = board .DISPLAY
24
- ENCODER = rotaryio .IncrementalEncoder (board .ENCODER_B , board .ENCODER_A )
25
- PIXELS = neopixel .NeoPixel (board .NEOPIXEL , 12 , auto_write = False )
26
- KEYBOARD = Keyboard (usb_hid .devices )
21
+ # CONFIGURABLES ------------------------
27
22
28
- group = displayio .Group (max_size = 13 )
29
- text_area = label .Label (terminalio .FONT , text = 'M' , color = 0xFFFFFF , x = DISPLAY .width // 2 , y = 0 , anchor_point = (0.5 , 0.0 ), max_glyphs = 30 )
30
- group .append (text_area )
31
- # Use baseline alignment for these!
32
- #labels = []
33
- #for i in range(13):
34
- # labels.append = label.Label(terminalio.FONT, text='M', color=0xFFFFFF, x=0, y=0, max_glyphs=15)
23
+ MACRO_FOLDER = '/macros'
35
24
36
- DISPLAY . show ( group )
25
+ # CLASSES AND FUNCTIONS ----------------
37
26
38
- class key :
27
+ class Key :
28
+ """ Add class doccstring here"""
39
29
DEBOUNCE_TIME = 1 / 50
40
30
41
31
def __init__ (self , keyname ):
42
- self .io = digitalio .DigitalInOut (keyname )
43
- self .io .direction = digitalio .Direction .INPUT
44
- self .io .pull = digitalio .Pull .UP
45
- self .last_value = self .io .value # Initial state
32
+ self .pin = digitalio .DigitalInOut (keyname )
33
+ self .pin .direction = digitalio .Direction .INPUT
34
+ self .pin .pull = digitalio .Pull .UP
35
+ self .last_value = self .pin .value # Initial state
46
36
self .last_time = time .monotonic ()
47
37
48
38
def debounce (self ):
49
- value = self .io .value
39
+ """ Add function docstring here """
40
+ value = self .pin .value
50
41
if value != self .last_value :
51
42
now = time .monotonic ()
52
43
elapsed = now - self .last_time
@@ -56,14 +47,8 @@ def debounce(self):
56
47
return value
57
48
return None
58
49
59
- KEYS = []
60
- for keyname in (board .KEY1 , board .KEY2 , board .KEY3 , board .KEY4 , board .KEY5 ,
61
- board .KEY6 , board .KEY7 , board .KEY8 , board .KEY9 , board .KEY10 ,
62
- board .KEY11 , board .KEY12 , board .ENCODER_SWITCH ):
63
- KEYS .append (key (keyname ))
64
-
65
-
66
- class macro :
50
+ class Macro :
51
+ """ Add class doccstring here"""
67
52
def __init__ (self , desc , color , sequence ):
68
53
self .desc = desc
69
54
self .color = eval (color )
@@ -74,69 +59,96 @@ def __init__(self, desc, color, sequence):
74
59
self .in_order = True
75
60
break
76
61
77
- class app :
62
+ class App :
63
+ """ Add class doccstring here"""
78
64
def __init__ (self , filename ):
79
- with open (filename ) as jsonfile :
65
+ with open (MACRO_FOLDER + '/' + filename ) as jsonfile :
80
66
json_data = json .load (jsonfile )
81
67
self .name = json_data ['name' ]
82
68
default_color = json_data ['color' ] if 'color' in json_data else '0'
83
69
self .macros = []
84
70
for mac in json_data ['macros' ]:
85
- self .macros .append (macro (
71
+ self .macros .append (Macro (
86
72
mac ['desc' ] if 'desc' in mac else None ,
87
73
mac ['color' ] if 'color' in mac else default_color ,
88
74
mac ['sequence' ] if 'sequence' in mac else None ))
89
75
90
76
def switch (self ):
91
- # Set up LED colors
92
- PIXELS .fill (0 )
93
- for i , mac in enumerate (self .macros ):
94
- PIXELS [i ] = mac .color
77
+ """ Add function docstring here """
78
+ GROUP [12 ].text = self .name
79
+ for i in range (12 ):
80
+ if i < len (self .macros ):
81
+ PIXELS [i ] = self .macros [i ].color
82
+ GROUP [i ].text = self .macros [i ].desc
83
+ else :
84
+ PIXELS [i ] = 0
85
+ GROUP [i ].text = ''
95
86
PIXELS .show ()
96
- # Set up screen
97
- text_area .text = self .name
98
87
88
+ # Convert key code name (e.g. "COMMAND") to a numeric value for press/release
89
+ def code (name ):
90
+ """ Add function doccstring here"""
91
+ return eval ('Keycode.' + name .upper ())
92
+
93
+ # INITIALIZATION -----------------------
94
+
95
+ DISPLAY = board .DISPLAY
96
+ ENCODER = rotaryio .IncrementalEncoder (board .ENCODER_B , board .ENCODER_A )
97
+ PIXELS = neopixel .NeoPixel (board .NEOPIXEL , 12 , auto_write = False )
98
+ KEYBOARD = Keyboard (usb_hid .devices )
99
+
100
+ GROUP = displayio .Group (max_size = 13 )
101
+ for KEY_INDEX in range (12 ):
102
+ x = KEY_INDEX % 3
103
+ y = KEY_INDEX // 3
104
+ GROUP .append (label .Label (terminalio .FONT , text = '' , color = 0xFFFFFF ,
105
+ anchored_position = ((DISPLAY .width - 1 ) * x / 2 ,
106
+ DISPLAY .height - 1 -
107
+ (3 - y ) * 11 ),
108
+ anchor_point = (x / 2 , 1.0 ), max_glyphs = 15 ))
109
+ GROUP .append (label .Label (terminalio .FONT , text = '' , color = 0xFFFFFF ,
110
+ anchored_position = (DISPLAY .width // 2 , 0 ),
111
+ anchor_point = (0.5 , 0.0 ), max_glyphs = 30 ))
112
+ DISPLAY .show (GROUP )
113
+
114
+ KEYS = []
115
+ for pin in (board .KEY1 , board .KEY2 , board .KEY3 , board .KEY4 , board .KEY5 ,
116
+ board .KEY6 , board .KEY7 , board .KEY8 , board .KEY9 , board .KEY10 ,
117
+ board .KEY11 , board .KEY12 , board .ENCODER_SWITCH ):
118
+ KEYS .append (Key (pin ))
99
119
100
120
APPS = []
101
- files = os .listdir (MACRO_FOLDER )
102
- files .sort ()
103
- for filename in files :
104
- if filename .endswith ('.json' ):
105
- APPS .append (app ( filename ))
121
+ FILES = os .listdir (MACRO_FOLDER )
122
+ FILES .sort ()
123
+ for FILENAME in FILES :
124
+ if FILENAME .endswith ('.json' ):
125
+ APPS .append (App ( FILENAME ))
106
126
107
- if not len ( APPS ) :
127
+ if not APPS :
108
128
print ('No valid macro files found' )
109
129
while True :
110
130
pass
111
131
112
- # Convert key code name (e.g. "COMMAND") to a numeric value for press/release
113
- def code (name ):
114
- return eval ('Keycode.' + name .upper ())
115
-
116
132
LAST_POSITION = None
117
133
APP_INDEX = 0
118
134
APPS [APP_INDEX ].switch ()
119
135
136
+ # MAIN LOOP ----------------------------
137
+
120
138
while True :
121
- position = ENCODER .position
122
- if position != LAST_POSITION :
123
- APP_INDEX = position % len (APPS )
139
+ POSITION = ENCODER .position
140
+ if POSITION != LAST_POSITION :
141
+ APP_INDEX = POSITION % len (APPS )
124
142
APPS [APP_INDEX ].switch ()
125
- LAST_POSITION = position
143
+ LAST_POSITION = POSITION
126
144
127
- for i , key in enumerate (KEYS ):
128
- action = key .debounce ()
145
+ for KEY_INDEX , KEY in enumerate (KEYS [ 0 : len ( APPS [ APP_INDEX ]. macros )] ):
146
+ action = KEY .debounce ()
129
147
if action is not None :
130
- print (i , len (APPS [APP_INDEX ].macros ))
131
-
132
- if i >= len (APPS [APP_INDEX ].macros ):
133
- continue # Ignore if key # exceeds macro list length
134
-
135
- keys = APPS [APP_INDEX ].macros [i ].sequence
148
+ keys = APPS [APP_INDEX ].macros [KEY_INDEX ].sequence
136
149
if action is False : # Macro key pressed
137
- print ('Press' , i )
138
- if APPS [APP_INDEX ].macros [i ].in_order :
139
- for x in APPS [APP_INDEX ].macros [i ].sequence :
150
+ if APPS [APP_INDEX ].macros [KEY_INDEX ].in_order :
151
+ for x in APPS [APP_INDEX ].macros [KEY_INDEX ].sequence :
140
152
if x .startswith ('+' ): # Press and hold key
141
153
KEYBOARD .press (code (x [1 :]))
142
154
elif x .startswith ('-' ): # Release key
@@ -145,27 +157,12 @@ def code(name):
145
157
KEYBOARD .press (code (x ))
146
158
KEYBOARD .release (code (x ))
147
159
else :
148
- for x in APPS [APP_INDEX ].macros [i ].sequence :
160
+ for x in APPS [APP_INDEX ].macros [KEY_INDEX ].sequence :
149
161
KEYBOARD .press (code (x ))
150
162
elif action is True : # Macro key released
151
- print ('Release' , i )
152
163
# Release all keys in reverse order
153
- for x in reversed (APPS [APP_INDEX ].macros [i ].sequence ):
164
+ for x in reversed (APPS [APP_INDEX ].macros [KEY_INDEX ].sequence ):
154
165
if x .startswith ('+' ) or x .startswith ('-' ):
155
166
KEYBOARD .release (code (x [1 :]))
156
167
else :
157
168
KEYBOARD .release (code (x ))
158
-
159
-
160
- META = ('LEFT_CONTROL' , 'CONTROL' , 'LEFT_SHIFT' , 'SHIFT' , 'LEFT_ALT' , 'ALT' ,
161
- 'OPTION' , 'LEFT_GUI' , 'GUI' , 'WINDOWS' , 'COMMAND' , 'RIGHT_CONTROL' ,
162
- 'RIGHT_SHIFT' , 'RIGHT_ALT' , 'RIGHT_GUI' , 'modifier_bit' )
163
-
164
- #>>> print(dir(board))
165
- #['__class__', 'BUTTON', 'DISPLAY', 'ENCODER_A', 'ENCODER_B', 'ENCODER_SWITCH', 'I2C', 'KEY1', 'KEY10', 'KEY11', 'KEY12', 'KEY2', 'KEY3', 'KEY4', 'KEY5', 'KEY6', 'KEY7', 'KEY8', 'KEY9', 'LED', 'MISO', 'MOSI', 'NEOPIXEL', 'OLED_CS', 'OLED_DC', 'OLED_RESET', 'ROTA', 'ROTB', 'SCK', 'SCL', 'SDA', 'SPEAKER', 'SPEAKER_SHUTDOWN', 'SPI']
166
-
167
- #>>> print(dir(Keycode))
168
- #['__class__', '__module__', '__name__', '__qualname__', '__bases__', '__dict__', 'C', 'M', 'A', 'B', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'ONE', 'TWO', 'THREE', 'FOUR', 'FIVE', 'SIX', 'SEVEN', 'EIGHT', 'NINE', 'ZERO', 'ENTER', 'RETURN', 'ESCAPE', 'BACKSPACE', 'TAB', 'SPACEBAR', 'SPACE', 'MINUS', 'EQUALS', 'LEFT_BRACKET', 'RIGHT_BRACKET', 'BACKSLASH', 'POUND', 'SEMICOLON', 'QUOTE', 'GRAVE_ACCENT', 'COMMA', 'PERIOD', 'FORWARD_SLASH', 'CAPS_LOCK', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'PRINT_SCREEN', 'SCROLL_LOCK', 'PAUSE', 'INSERT', 'HOME', 'PAGE_UP', 'DELETE', 'END', 'PAGE_DOWN', 'RIGHT_ARROW', 'LEFT_ARROW', 'DOWN_ARROW', 'UP_ARROW', 'KEYPAD_NUMLOCK', 'KEYPAD_FORWARD_SLASH', 'KEYPAD_ASTERISK', 'KEYPAD_MINUS', 'KEYPAD_PLUS', 'KEYPAD_ENTER', 'KEYPAD_ONE', 'KEYPAD_TWO', 'KEYPAD_THREE', 'KEYPAD_FOUR', 'KEYPAD_FIVE', 'KEYPAD_SIX', 'KEYPAD_SEVEN', 'KEYPAD_EIGHT', 'KEYPAD_NINE', 'KEYPAD_ZERO', 'KEYPAD_PERIOD', 'KEYPAD_BACKSLASH', 'APPLICATION', 'POWER', 'KEYPAD_EQUALS', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'LEFT_CONTROL', 'CONTROL', 'LEFT_SHIFT', 'SHIFT', 'LEFT_ALT', 'ALT', 'OPTION', 'LEFT_GUI', 'GUI', 'WINDOWS', 'COMMAND', 'RIGHT_CONTROL', 'RIGHT_SHIFT', 'RIGHT_ALT', 'RIGHT_GUI', 'modifier_bit']
169
-
170
- #>>> print(eval('Keycode.' + 'COMMAND'))
171
-
0 commit comments