-
Notifications
You must be signed in to change notification settings - Fork 3
/
code.py
162 lines (135 loc) · 5.3 KB
/
code.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import time
import math
import usb_cdc
from pimoroni_rgbkeypad import RGBKeypad
# Generated via https://medialab.github.io/iwanthue/
COLORS = [
[229, 133, 154],
[236, 123, 70],
[213, 165, 120],
[213, 172, 61],
[208, 226, 69],
[213, 225, 154],
[143, 185, 73],
[108, 218, 71],
[139, 175, 125],
[101, 216, 128],
[103, 217, 173],
[85, 179, 178],
[120, 223, 235],
[120, 166, 224],
[201, 157, 216],
[220, 110, 223],
]
PAUSE_KEY_INDEX = 15
VOLUME_DOWN_KEY_INDEX = 12
VOLUME_UP_KEY_INDEX = 13
ACTIVATED_KEY_BRIGHTNESS = 0.6
DEACTIVATED_KEY_BRIGHTNESS = 0.2
BRIGHTNESS_FLUCTUATION_CYCLE_MS = 3000
def fluctuating_brightness(t, cycle):
brightness = abs(math.cos(math.pi * t / cycle))
return flatten(value=brightness, min_value=0.05, max_value=0.90)
def flatten(value, min_value, max_value):
if value < min_value:
return min_value
elif value > max_value:
return max_value
return value
def send_message(message):
print(message)
def initialize_keys(keypad):
for i, key in enumerate(keypad.keys):
key.color = COLORS[i]
key.brightness = DEACTIVATED_KEY_BRIGHTNESS
def advertise_keys_colors():
while not usb_cdc.console.connected:
time.sleep(0.1)
send_message('{"state": "init", "colors": %s}\n' % (str(COLORS[:12])))
def main():
start_time = time.monotonic()
activated_keys = {}
keys_being_pressed = {}
paused = False
keypad = RGBKeypad()
initialize_keys(keypad)
advertise_keys_colors()
while True:
# This is faster than iterating over all the keys everytime
# BUT while the operator presses on the key, the key will be
# marked as pressed multiple times. We need to keep track of
# the keys that are _being_ pressed and only light them up once,
# to avoid a flicker effect
keys_pressed = keypad.get_keys_pressed()
if len([pressed for pressed in keys_pressed if pressed]) == 2 and (
keys_pressed[VOLUME_DOWN_KEY_INDEX] is True
or keys_pressed[VOLUME_UP_KEY_INDEX] is True
):
key_index = [
i
for (i, pressed) in enumerate(keys_pressed)
if pressed
if i < VOLUME_DOWN_KEY_INDEX
][0]
if not keys_being_pressed.get(key_index):
keys_being_pressed[key_index] = True
state = (
"vol_down"
if keys_pressed[VOLUME_DOWN_KEY_INDEX] is True
else "vol_up"
)
message = '{"key": "%s", "state": "%s"}\n' % (str(key_index), state)
send_message(message) # That sends the message over the usb port
for key_index, key_pressed in enumerate(keys_pressed):
# De-register a key that was being pressed if their state indicates
# that they are not being pressed.
if not key_pressed:
if key_index in keys_being_pressed:
keys_being_pressed.pop(key_index)
# When a key was activated, make its brightness fluctuate,
# except if the pause button is activated itself. In that case,
# only make the pause button fluctuate and deactivate all other
# activated keys, while keeping their activated state, to make it
# easy to restore
if PAUSE_KEY_INDEX in activated_keys and key_index != PAUSE_KEY_INDEX:
key = keypad.keys[key_index]
key.brightness = DEACTIVATED_KEY_BRIGHTNESS
elif key_index in activated_keys:
elapsed_ms = (time.monotonic() - start_time) * 1000
key = keypad.keys[key_index]
key.brightness = fluctuating_brightness(
elapsed_ms, cycle=BRIGHTNESS_FLUCTUATION_CYCLE_MS
)
continue
if key_index in (VOLUME_DOWN_KEY_INDEX, VOLUME_UP_KEY_INDEX):
continue
# Don't modify a key that is still being pressed, to avoid making it flicker
if key_index in keys_being_pressed:
continue
# When a key was pressed, send the associated keyboard event from the
# keypad to the computed it is connected to
key = keypad.keys[key_index]
keys_being_pressed[key_index] = True
# keyboard.send(KEY_INDEX_TO_KEYBOARD_KEY[key_index])
# Toggle the key activation state after it was pressed
if key_index in activated_keys:
activated_keys.pop(key_index)
key.brightness = DEACTIVATED_KEY_BRIGHTNESS
state = "off"
else:
activated_keys[key_index] = True
key.brightness = ACTIVATED_KEY_BRIGHTNESS
state = "on"
if key_index == PAUSE_KEY_INDEX:
if paused:
state = "unpause"
else:
state = "pause"
paused = not paused
message = '{"key": "%s", "state": "%s"}\n' % (
str(key_index),
state,
)
send_message(message) # That sends the message over the usb port
if __name__ == "__main__":
main()