Skip to content

Commit 3becc68

Browse files
WIP, got configs loading from JSON
1 parent caf8101 commit 3becc68

3 files changed

Lines changed: 184 additions & 0 deletions

File tree

Macropad_Macros/code.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import time
2+
import board
3+
import digitalio
4+
import rotaryio
5+
import neopixel
6+
import json
7+
import os
8+
9+
import displayio
10+
import terminalio
11+
from adafruit_display_text import label
12+
13+
import usb_hid
14+
from adafruit_hid.keyboard import Keyboard
15+
from adafruit_hid.keycode import Keycode
16+
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)
27+
28+
group = displayio.Group(max_size=10)
29+
text1 = "0123\n4567\n89AB\nCDEF\n1234\n5678\n9AB"
30+
text_area = label.Label(terminalio.FONT, text=text1, color=0xFFFFFF, x=8, y=8)
31+
group.append(text_area)
32+
33+
DISPLAY.show(group)
34+
35+
class key:
36+
DEBOUNCE_TIME = 1 / 50
37+
38+
def __init__(self, keyname):
39+
self.io = digitalio.DigitalInOut(keyname)
40+
self.io.direction = digitalio.Direction.INPUT
41+
self.io.pull = digitalio.Pull.UP
42+
self.last_value = self.io.value # Initial state
43+
self.last_time = time.monotonic()
44+
45+
def debounce(self):
46+
value = self.io.value
47+
if value != self.last_value:
48+
now = time.monotonic()
49+
elapsed = now - self.last_time
50+
if elapsed >= self.DEBOUNCE_TIME:
51+
self.last_value = value
52+
self.last_time = now
53+
return value
54+
return None
55+
56+
KEYS = []
57+
for keyname in (board.KEY1, board.KEY2, board.KEY3, board.KEY4, board.KEY5,
58+
board.KEY6, board.KEY7, board.KEY8, board.KEY9, board.KEY10,
59+
board.KEY11, board.KEY12, board.ENCODER_SWITCH):
60+
KEYS.append(key(keyname))
61+
62+
63+
class macro:
64+
def __init__(self, desc, color, sequence):
65+
self.desc = desc
66+
self.color = color
67+
self.sequence = sequence
68+
self.in_order = False
69+
for key in sequence:
70+
if key.startswith('-'):
71+
self.in_order = True
72+
break
73+
74+
class app:
75+
def __init__(self, filename):
76+
with open(filename) as jsonfile:
77+
json_data = json.load(jsonfile)
78+
self.name = json_data['name']
79+
default_color = json_data['color'] if 'color' in json_data else None
80+
self.macros = []
81+
for mac in json_data['macros']:
82+
self.macros.append(macro(
83+
mac['desc'] if 'desc' in mac else None,
84+
mac['color'] if 'color' in mac else default_color,
85+
mac['sequence'] if 'sequence' in mac else None))
86+
87+
def activate(self):
88+
# Config screen, button colors, key sequences here
89+
pass
90+
91+
92+
APPS = []
93+
files = os.listdir(MACRO_FOLDER)
94+
files.sort()
95+
for filename in files:
96+
if filename.endswith('.json'):
97+
APPS.append(app(filename))
98+
99+
if not len(APPS):
100+
print('No valid macro files found')
101+
while True:
102+
pass
103+
104+
APP_INDEX = 0
105+
106+
107+
108+
FOO = ((Keycode.A, Keycode.ONE, Keycode.X), Keycode.B, Keycode.C)
109+
110+
111+
last_position = None
112+
while True:
113+
position = ENCODER.position
114+
if position != last_position:
115+
PIXELS.fill(0)
116+
PIXELS[position % len(APPS)] = 0xFFFFFF
117+
PIXELS.show()
118+
print(position)
119+
last_position = position
120+
for i, key in enumerate(KEYS):
121+
action = key.debounce()
122+
if action is not None:
123+
print(i, len(APPS[APP_INDEX].macros))
124+
125+
if i >= len(APPS[APP_INDEX].macros):
126+
continue # Ignore if key # exceeds macro list length
127+
128+
keys = APPS[APP_INDEX].macros[i].sequence
129+
if action is False: # Key pressed
130+
print('Press', i)
131+
if APPS[APP_INDEX].macros[i].in_order:
132+
for x in APPS[APP_INDEX].macros[i].sequence:
133+
if x.startswith('-'):
134+
KEYBOARD.release(eval('Keycode.' + x[1:]))
135+
else:
136+
KEYBOARD.press(eval('Keycode.' + x))
137+
else:
138+
for x in APPS[APP_INDEX].macros[i].sequence:
139+
KEYBOARD.press(eval('Keycode.' + x))
140+
elif action is True: # Key released
141+
print('Release', i)
142+
for x in reversed(APPS[APP_INDEX].macros[i].sequence):
143+
if not x.startswith('-'):
144+
KEYBOARD.release(eval('Keycode.' + x))
145+
146+
147+
META = ('LEFT_CONTROL', 'CONTROL', 'LEFT_SHIFT', 'SHIFT', 'LEFT_ALT', 'ALT',
148+
'OPTION', 'LEFT_GUI', 'GUI', 'WINDOWS', 'COMMAND', 'RIGHT_CONTROL',
149+
'RIGHT_SHIFT', 'RIGHT_ALT', 'RIGHT_GUI', 'modifier_bit')
150+
151+
#>>> print(dir(board))
152+
#['__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']
153+
154+
#>>> print(dir(Keycode))
155+
#['__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']
156+
157+
#>>> print(eval('Keycode.' + 'COMMAND'))
158+

Macropad_Macros/illustrator.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "Illustrator",
3+
"macros": [
4+
{"desc": "Undo",
5+
"color": "0xFF0000",
6+
"sequence": ["COMMAND", "N", "-COMMAND", "ONE", "TWO", "THREE"]
7+
},
8+
{"desc": "Redo",
9+
"color": "0x00FF00",
10+
"sequence": ["FOUR", "FIVE", "SIX"]
11+
}
12+
]
13+
}

Macropad_Macros/photoshop.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "Photoshop",
3+
"macros": [
4+
{"desc": "Undo",
5+
"color": "0xFF0000",
6+
"sequence": ["ONE", "TWO", "THREE"]
7+
},
8+
{"desc": "Redo",
9+
"color": "0x00FF00",
10+
"sequence": ["FOUR", "FIVE", "SIX"]
11+
}
12+
]
13+
}

0 commit comments

Comments
 (0)