Skip to content

Instantly share code, notes, and snippets.

@TheBlackParrot
Last active December 1, 2018 04:36
Show Gist options
  • Save TheBlackParrot/858155c978dfca1d678417c44aa21833 to your computer and use it in GitHub Desktop.
Save TheBlackParrot/858155c978dfca1d678417c44aa21833 to your computer and use it in GitHub Desktop.
Control things/see system stats with a Launchpad (uses launchpad.py)
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]
#!/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()
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