Last active
December 1, 2018 04:36
-
-
Save TheBlackParrot/858155c978dfca1d678417c44aa21833 to your computer and use it in GitHub Desktop.
Control things/see system stats with a Launchpad (uses launchpad.py)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Txfnums(): | |
def __init__(self): | |
self.nums = [ | |
[ | |
0, 1, 0, | |
1, 0, 1, | |
1, 0, 1, | |
0, 1, 0 | |
], | |
[ | |
1, 1, 0, | |
0, 1, 0, | |
0, 1, 0, | |
1, 1, 1 | |
], | |
[ | |
1, 1, 0, | |
0, 0, 1, | |
0, 1, 0, | |
1, 1, 1 | |
], | |
[ | |
1, 1, 1, | |
0, 1, 1, | |
0, 0, 1, | |
1, 1, 1 | |
], | |
[ | |
1, 0, 0, | |
1, 0, 1, | |
1, 1, 1, | |
0, 0, 1 | |
], | |
[ | |
1, 1, 1, | |
1, 1, 0, | |
0, 0, 1, | |
1, 1, 0 | |
], | |
[ | |
1, 0, 0, | |
1, 1, 1, | |
1, 0, 1, | |
1, 1, 1 | |
], | |
[ | |
1, 1, 1, | |
0, 0, 1, | |
0, 1, 0, | |
1, 0, 0 | |
], | |
[ | |
1, 1, 1, | |
0, 1, 0, | |
1, 0, 1, | |
1, 1, 1 | |
], | |
[ | |
1, 1, 1, | |
1, 0, 1, | |
1, 1, 1, | |
0, 0, 1 | |
] | |
] | |
def __getitem__(self, index): | |
return self.nums[index] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python2 | |
from __future__ import division | |
from __future__ import print_function | |
''' | |
I apologize in advance for the terrible coding job. It works, at least. | |
...to an extent, mostly. | |
''' | |
''' | |
REQUIREMENTS | |
============ | |
* recent version of python 2.x | |
* python-mpd2 | |
* psutil | |
* launchpad.py (https://github.com/FMMT666/launchpad.py) | |
* pygame | |
''' | |
from launchpad import Launchpad | |
from pygame import time | |
import time as _time | |
import random | |
import math | |
import threading | |
# settings | |
import _settings as settings | |
from _3x4_nums import Txfnums | |
# custom stuff | |
import psutil | |
from mpd import MPDClient | |
mpd = MPDClient() | |
mpd.connect(settings.mpd["address"], settings.mpd["port"]) | |
mpd.password(settings.mpd["password"]) | |
print("MPD: {}".format(mpd.mpd_version)) | |
lp = Launchpad() | |
lp.Open() | |
lp.Reset() | |
def clamp(n, smallest, largest): | |
return max(smallest, min(n, largest)) | |
class StoppableThread(threading.Thread): | |
"""Thread class with a stop() method. The thread itself has to check | |
regularly for the stopped() condition.""" | |
def __init__(self): | |
super(StoppableThread, self).__init__() | |
self._stop = threading.Event() | |
def stop(self): | |
self._stop.set() | |
def stopped(self): | |
return self._stop.isSet() | |
class PageError(Exception): | |
def __init__(self, value): | |
self.value = value | |
def __str__(self): | |
return repr(self.value) | |
class LaunchpadButtonDefs(): | |
def __init__(self): | |
self.close = 120 | |
self.page_indicators = [8, 24, 40, 56, 72, 88, 104] | |
self.session = 204 | |
self.page_prev = 202 | |
self.page_next = 203 | |
self.row = [ | |
[0, 1, 2, 3, 4, 5, 6, 7], | |
[16, 17, 18, 19, 20, 21, 22, 23], | |
[32, 33, 34, 35, 36, 37, 38, 39], | |
[48, 49, 50, 51, 52, 53, 54, 55], | |
[64, 65, 66, 67, 68, 69, 70, 71], | |
[80, 81, 82, 83, 84, 85, 86, 87], | |
[96, 97, 98, 99, 100, 101, 102, 103], | |
[112, 113, 114, 115, 116, 117, 118, 119] | |
] | |
self.user_1 = 205 | |
self.user_2 = 206 | |
self.user_3 = 207 | |
self.ctrl_up = 200 | |
self.ctrl_down = 201 | |
def getPressed(self, val): | |
if self.close == val: | |
return "close" | |
try: | |
page = self.page_indicators.index(val) | |
except ValueError: | |
pass | |
else: | |
return "page.{}".format(page) | |
if self.session == val: | |
return "session" | |
if self.page_prev == val: | |
return "page_prev" | |
if self.page_next == val: | |
return "page_next" | |
if self.user_1 == val: | |
return "user_1" | |
if self.user_2 == val: | |
return "user_2" | |
if self.user_3 == val: | |
return "user_3" | |
if self.ctrl_up == val: | |
return "ctrl_up" | |
if self.ctrl_down == val: | |
return "ctrl_down" | |
row = int((val - (val % 16))/16) | |
col = int(val % 16) | |
try: | |
if val == self.row[row][col]: | |
return "grid.{}.{}".format(row, col) | |
except IndexError: | |
pass | |
return "undf.{}".format(val) | |
def reset_grid(): | |
lp.LedCtrlRaw(button_defs.user_1, 0, 0) | |
lp.LedCtrlRaw(button_defs.user_2, 0, 0) | |
lp.LedCtrlRaw(button_defs.user_3, 0, 0) | |
lp.LedCtrlRaw(button_defs.ctrl_up, 0, 0) | |
lp.LedCtrlRaw(button_defs.ctrl_down, 0, 0) | |
lp.LedCtrlRaw(button_defs.page_next, 3, 2) | |
lp.LedCtrlRaw(button_defs.page_prev, 3, 2) | |
for x in range(0, 8): | |
for y in range(0, 8): | |
lp.LedCtrlRaw(button_defs.row[x][y], 0, 0) | |
def get_color_gradient(val, _min, _max): | |
''' | |
red (highest): [3, 0] | |
yellow (mid): [3, 3] | |
green(lowest): [0, 3] | |
[0, 3], [1, 3], [2, 3], [3, 3], [3, 2], [3, 1], [3, 0] | |
''' | |
actual_max = _max - _min | |
actual_val = val - _min | |
if actual_val == actual_max: | |
return [3, 0] | |
x = clamp(int((actual_val/actual_max)*7), 0, 7) | |
return [clamp(x, 0, 3), clamp(math.fabs(x-6), 0, 3)] | |
class LaunchpadPage1(): | |
''' | |
Some paint crap | |
''' | |
def __init__(self, parent): | |
self.parent = parent | |
self.color = [random.randint(1, 3), random.randint(0, 3)] | |
self.session_status = True | |
self.button_states = [] | |
for x in range(0, 8): | |
col = [0, 0, 0, 0, 0, 0, 0, 0] | |
self.button_states.append(col) | |
def on_page_activated(self): | |
self.refresh() | |
def on_page_deactivated(self): | |
return | |
def on_button(self, button): | |
if button[0:4] == "grid": | |
row = int(button[5]) | |
col = int(button[7]) | |
state = self.button_states[row][col] | |
if not state: | |
lp.LedCtrlRaw(button_defs.row[row][col], self.color[0], self.color[1]) | |
state = 1 | |
else: | |
lp.LedCtrlRaw(button_defs.row[row][col], 0, 0) | |
state = 0 | |
self.button_states[row][col] = state | |
if row == 7 and col == 7: | |
raise ValueError | |
elif button in ["user_1", "user_2"]: | |
new_col = self.color[int(button[5])-1] + 1 | |
if new_col > 3: | |
new_col = 0 | |
self.color[int(button[5])-1] = new_col | |
self.refresh() | |
def refresh(self): | |
lp.LedCtrlRaw(button_defs.user_1, self.color[0], 0) | |
lp.LedCtrlRaw(button_defs.user_2, 0, self.color[1]) | |
lp.LedCtrlRaw(button_defs.user_3, self.color[0], self.color[1]) | |
for x in range(0, 8): | |
for y in range(0, 8): | |
state = self.button_states[x][y] | |
if state: | |
lp.LedCtrlRaw(button_defs.row[x][y], self.color[0], self.color[1]) | |
else: | |
lp.LedCtrlRaw(button_defs.row[x][y], 0, 0) | |
class LaunchpadPage2(): | |
''' | |
CPU Usage | |
''' | |
def __init__(self, parent): | |
self.parent = parent | |
self.session_status = True | |
self.thread = threading.Thread(target=self.loop) | |
self.thread.daemon = True | |
self.thread.start() | |
def draw(self): | |
if self.parent.active_page != 1: | |
return | |
try: | |
lp.LedCtrlRaw(button_defs.session, 3, 3) | |
cpu = psutil.cpu_percent(interval=1, percpu=True) | |
except: | |
self.session_status = False | |
return | |
self.session_status = True | |
lp.LedCtrlRaw(button_defs.session, 0, 3) | |
reset_grid() | |
print(cpu) | |
for x in range(0, clamp(len(cpu), 0, 8)): | |
print(x) | |
cols = int(math.floor((cpu[x]/100)*8)) | |
if cols > 3: | |
green = clamp(math.fabs(cols-6), 0, 3) | |
red = clamp(cols-3, 0, 3) | |
else: | |
green = clamp(cols, 1, 3) | |
red = 0 | |
for y in range(0, cols): | |
lp.LedCtrlRaw(button_defs.row[x][y], red, green) | |
def loop(self): | |
while True: | |
_time.sleep(1) | |
if self.parent.active_page == 1: | |
print("drawing cpu...") | |
self.draw() | |
def on_page_activated(self): | |
return | |
def on_page_deactivated(self): | |
return | |
class LaunchpadPage3(): | |
''' | |
MPD elapsed | |
''' | |
def __init__(self, parent): | |
self.parent = parent | |
self.session_status = True | |
self.button_states = [] | |
for x in range(0, 8): | |
col = [0, 0, 0, 0, 0, 0, 0, 0] | |
self.button_states.append(col) | |
self.thread = threading.Thread(target=self.loop) | |
self.thread.daemon = True | |
self.thread.start() | |
status = mpd.status() | |
self.old_id = status["songid"] | |
self.vol = int(status["volume"]) | |
def reset_state(self): | |
for x in range(0, 8): | |
for y in range(0, 8): | |
self.button_states[x][y] = 0 | |
def draw(self): | |
status = mpd.status() | |
time = status["time"] | |
cur_id = status["songid"] | |
elapsed = int(time.split(":")[0]) | |
duration = int(time.split(":")[1]) | |
if self.old_id != cur_id: | |
self.old_id = cur_id | |
self.reset_state() | |
''' | |
row = int((val - (val % 16))/16) | |
col = int(val % 16) | |
''' | |
squares = int(math.ceil((elapsed/duration)*64)) | |
for x in range(0, squares): | |
self.button_states[int(math.floor(x / 8))][x % 8] = 1 | |
if self.parent.active_page == 2: | |
for x in range(0, 8): | |
for y in range(0, 8): | |
lp.LedCtrlRaw(button_defs.row[x][y], 0, 3*self.button_states[x][y]) | |
def draw_vol(self): | |
col = get_color_gradient(self.vol, 0, 100) | |
lp.LedCtrlRaw(button_defs.user_3, col[0], col[1]) | |
def loop(self): | |
while True: | |
_time.sleep(1) | |
if self.parent.active_page == 2: | |
print("drawing mpd...") | |
self.draw() | |
def on_button(self, button): | |
if button[0:4] == "grid": | |
row = int(button[5]) | |
col = int(button[7]) | |
status = mpd.status() | |
time = status["time"] | |
duration = int(time.split(":")[1]) | |
squares = (row*8) + col | |
for x in range(0, squares): | |
self.button_states[int(math.floor(x / 8))][x % 8] = 1 | |
for x in reversed(range(squares, 64)): | |
self.button_states[int(math.floor(x / 8))][x % 8] = 0 | |
mpd.seekcur((squares/64)*duration) | |
self.draw() | |
elif button in ["ctrl_up", "ctrl_down"]: | |
if button == "ctrl_up": | |
offset = 5 | |
if button == "ctrl_down": | |
offset = -5 | |
self.vol = clamp(self.vol+offset, 0, 100) | |
mpd.setvol(self.vol) | |
self.draw_vol() | |
elif button == "user_1": | |
if int(mpd.status()["time"]) > 5: | |
mpd.seekcur(0) | |
else: | |
mpd.previous() | |
elif button == "user_2": | |
mpd.next() | |
elif button == "user_3": | |
mpd.pause() | |
def on_page_activated(self): | |
lp.LedCtrlRaw(button_defs.ctrl_up, 0, 1) | |
lp.LedCtrlRaw(button_defs.ctrl_down, 0, 1) | |
lp.LedCtrlRaw(button_defs.user_1, 1, 1) | |
lp.LedCtrlRaw(button_defs.user_2, 1, 1) | |
for x in range(0, 8): | |
for y in range(0, 8): | |
lp.LedCtrlRaw(button_defs.row[x][y], 0, 3*self.button_states[x][y]) | |
self.draw_vol() | |
def on_page_deactivated(self): | |
return | |
class LaunchpadPage4(): | |
''' | |
debug | |
''' | |
def __init__(self, parent): | |
self.parent = parent | |
self.session_status = True | |
def draw(self): | |
for x in range(0, 8): | |
for y in range(0, 8): | |
color = get_color_gradient((x*8)+y, 0, 63) | |
lp.LedCtrlRaw(button_defs.row[x][y], color[0], color[1]) | |
def on_page_activated(self): | |
self.draw() | |
def on_page_deactivated(self): | |
return | |
class LaunchpadPage5(): | |
''' | |
Clock | |
''' | |
def __init__(self, parent): | |
self.parent = parent | |
self.session_status = True | |
self.thread = threading.Thread(target=self.loop) | |
self.thread.daemon = True | |
self.thread.start() | |
self.button_states = [] | |
for x in range(0, 8): | |
col = [0, 0, 0, 0, 0, 0, 0, 0] | |
self.button_states.append(col) | |
self.nums = Txfnums() | |
self.old_min = int(_time.strftime("%M", _time.localtime())) | |
def update_states(self): | |
self.time = _time.strftime("%H.%M", _time.localtime()).split(".") | |
hr_1 = str(self.time[0])[0] | |
hr_2 = str(self.time[0])[1] | |
mn_1 = str(self.time[1])[0] | |
mn_2 = str(self.time[1])[1] | |
print("{}{}:{}{}".format(hr_1, hr_2, mn_1, mn_2)) | |
for y in range(0, 3): | |
for x in range(0, 4): | |
self.button_states[x][y] = self.nums[int(hr_1)][(x*3)+y] | |
self.button_states[x][y+4] = self.nums[int(hr_2)][(x*3)+y] | |
self.button_states[x+4][y] = self.nums[int(mn_1)][(x*3)+y] | |
self.button_states[x+4][y+4] = self.nums[int(mn_2)][(x*3)+y] | |
def draw(self): | |
for y in range(0, 8): | |
for x in range(0, 4): | |
lp.LedCtrlRaw(button_defs.row[x][y], self.button_states[x][y]*3, 0) | |
for y in range(0, 8): | |
for x in range(4, 8): | |
lp.LedCtrlRaw(button_defs.row[x][y], self.button_states[x][y]*3, self.button_states[x][y]*3) | |
def on_page_activated(self): | |
self.update_states() | |
self.draw() | |
def on_page_deactivated(self): | |
return | |
def loop(self): | |
while True: | |
_time.sleep(1) | |
new_min = int(_time.strftime("%M", _time.localtime())) | |
if self.old_min != new_min: | |
self.update_states() | |
self.old_min = new_min | |
if self.parent.active_page == 4: | |
print("drawing clock...") | |
self.draw() | |
class LaunchpadPages(): | |
def __init__(self): | |
lp.LedCtrlRaw(button_defs.session, 3, 3) | |
self.pages = [ | |
LaunchpadPage1(self), | |
LaunchpadPage2(self), | |
LaunchpadPage3(self), | |
LaunchpadPage4(self), | |
LaunchpadPage5(self) | |
] | |
self.switch_page("init") | |
def switch_page(self, button): | |
lp.LedCtrlRaw(button_defs.session, 3, 3) | |
print(button) | |
try: | |
old_page = self.active_page | |
except: | |
old_page = 0 | |
if button == "init": | |
new_page = 0 | |
self.active_page = 0 | |
elif button == "page_next": | |
new_page = self.active_page + 1 | |
elif button == "page_prev": | |
new_page = self.active_page - 1 | |
else: | |
if button[0:5] == "page.": | |
new_page = int(button[5]) | |
else: | |
return | |
if old_page != new_page: | |
reset_grid() | |
try: | |
self.active_page = clamp(new_page, 0, len(self.pages)-1) | |
self.pages[old_page].on_page_deactivated() | |
self.pages[self.active_page].on_page_activated() | |
except: | |
raise | |
elif button == "init": | |
try: | |
self.pages[self.active_page].on_page_activated() | |
except: | |
raise | |
for x in range(0, len(self.pages)): | |
strength = 1 | |
if x == self.active_page: | |
strength = 3 | |
lp.LedCtrlRaw(button_defs.page_indicators[x], 0, strength) | |
if self.pages[self.active_page].session_status: | |
lp.LedCtrlRaw(button_defs.session, 0, 3) | |
else: | |
lp.LedCtrlRaw(button_defs.session, 3, 0) | |
def on_button(self, button): | |
if button[0:4] == "page": | |
self.switch_page(button) | |
return | |
#self.pages[self.active_page].on_button(button) | |
try: | |
self.pages[self.active_page].on_button(button) | |
except: | |
lp.LedCtrlRaw(button_defs.session, 3, 0) | |
#pass | |
else: | |
lp.LedCtrlRaw(button_defs.session, 0, 3) | |
button_defs = LaunchpadButtonDefs() | |
pages = LaunchpadPages() | |
lp.LedCtrlRaw(button_defs.close, 3, 0) | |
lp.LedCtrlRaw(button_defs.page_next, 3, 2) | |
lp.LedCtrlRaw(button_defs.page_prev, 3, 2) | |
def shutdown(): | |
lp.Reset() | |
lp.Close() | |
mpd.close() | |
mpd.disconnect() | |
while 1: | |
time.wait(10) | |
raw = lp.ButtonStateRaw() | |
if raw != []: | |
print(raw) | |
if raw[1]: | |
button = button_defs.getPressed(raw[0]) | |
print(button); | |
if raw[0] == button_defs.close: | |
shutdown() | |
else: | |
pages.on_button(button) | |
shutdown() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mpd = { | |
"address": "localhost", | |
"port": 6600, | |
"password": None | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment