Skip to content

Commit

Permalink
ColorThreads now correctly get the color from the GUI. Some slight fi…
Browse files Browse the repository at this point in the history
…xes to make music less flickery.
  • Loading branch information
samclane committed May 3, 2018
1 parent 2132d0d commit 62d2cc4
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 27 deletions.
4 changes: 2 additions & 2 deletions audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
RATE = 44100

# RMS -> Brightness control constants
SCALE = 100
EXPONENT = 2
SCALE = 15 # Change if too dim/bright
EXPONENT = 2 # Change if too little/too much difference between loud and quiet sounds

# Init stream on module load
p = pyaudio.PyAudio()
Expand Down
11 changes: 7 additions & 4 deletions color_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,23 @@ def stopped(self):


class ColorThreadRunner:
def __init__(self, bulb, color_function, initial_color):
def __init__(self, bulb, color_function, parent):
self.bulb = bulb
self.color_function = color_function
self.initial_color = initial_color
self.parent = parent # couple to parent frame
self.t = ColorThread(target=self.match_color, args=(self.bulb,))
self.t.setDaemon(True)

def match_color(self, bulb):
duration_secs = 1 / 30
self.prev_color = self.parent.get_color() # coupling to LightFrame from gui.py here
duration_secs = 1 / 15
transition_time_ms = duration_secs * 1000
while not self.t.stopped():
try:
bulb.set_color(self.color_function(initial_color=self.initial_color), transition_time_ms,
color = self.color_function(initial_color=self.prev_color)
bulb.set_color(color, transition_time_ms,
True if duration_secs < 1 else False)
self.prev_color = color
except OSError:
# This is dirty, but we really don't care, just keep going
continue
Expand Down
38 changes: 17 additions & 21 deletions gui.pyw
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,10 @@ class LightFrame(ttk.Labelframe):
self.hsbk_display = (
Canvas(self, background='#%02x%02x%02x' % HueToRGB(360 * (h / 65535)), width=20, height=20),
Canvas(self, background='#%02x%02x%02x' % (
int(255 * (s / 65535)), int(255 * (s / 65535)), int(255 * (s / 65535))),
int(255 * (s / 65535)), int(255 * (s / 65535)), int(255 * (s / 65535))),
width=20, height=20),
Canvas(self, background='#%02x%02x%02x' % (
int(255 * (b / 65535)), int(255 * (b / 65535)), int(255 * (b / 65535))),
int(255 * (b / 65535)), int(255 * (b / 65535)), int(255 * (b / 65535))),
width=20, height=20),
Canvas(self, background='#%02x%02x%02x' % KelvinToRGB(k), width=20, height=20)
)
Expand All @@ -112,24 +112,29 @@ class LightFrame(ttk.Labelframe):
self.hsbk_labels[key].grid(row=key + 1, column=2)
self.hsbk_display[key].grid(row=key + 1, column=3)

self.threads = {}

# Add buttons for pre-made colors and routines
Button(self, text="White", command=lambda: self.set_color(WHITE)).grid(row=5, column=0)
Button(self, text="Warm White", command=lambda: self.set_color(WARM_WHITE)).grid(row=5, column=1)
Button(self, text="Cold White", command=lambda: self.set_color(COLD_WHITE)).grid(row=5, column=2)
Button(self, text="Gold", command=lambda: self.set_color(GOLD)).grid(row=6, column=0)
self.acm = color_thread.ColorThreadRunner(self.bulb, color_thread.avg_screen_color, hsbk)
Button(self, text="Avg. Screen Color", command=self.acm.start).grid(row=6, column=1)
self.threads['screen'] = color_thread.ColorThreadRunner(self.bulb, color_thread.avg_screen_color, self)
Button(self, text="Avg. Screen Color", command=self.threads['screen'].start).grid(row=6, column=1)
Button(self, text="Pick Color", command=self.get_color_hbsk).grid(row=6, column=2)
self.audio_matcher = color_thread.ColorThreadRunner(self.bulb, audio.get_music_color, hsbk)
Button(self, text="Music Color*", command=self.audio_matcher.start).grid(row=7, column=0)
self.threads['audio'] = color_thread.ColorThreadRunner(self.bulb, audio.get_music_color, self)
Button(self, text="Music Color*", command=self.threads['audio'].start).grid(row=7, column=0)
Label(self, text="*=Work in progress").grid(row=8, column=1)

self.after(HEARTBEAT_RATE, self.update_status_from_bulb)

def get_color(self):
return [v.get() for v in self.hsbk]

def stop_threads(self):
""" Stop all ColorRunner threads """
self.acm.stop()
self.audio_matcher.stop()
for thread in self.threads.values():
thread.stop()

def update_power(self):
""" Send new power state to bulb when UI is changed. """
Expand All @@ -139,7 +144,7 @@ class LightFrame(ttk.Labelframe):
def update_color(self, *args):
""" Send new color state to bulb when UI is changed. """
self.stop_threads()
self.bulb.set_color([c.get() for c in self.hsbk], rapid=True)
self.bulb.set_color(self.get_color(), rapid=True)
for key, val in enumerate(self.hsbk):
self.update_label(key)
self.update_display(key)
Expand All @@ -165,7 +170,7 @@ class LightFrame(ttk.Labelframe):
self.hsbk_labels[3].config(text=str(self.hsbk[3].get()) + " K")

def update_display(self, key):
hsbk = h, s, b, k = [v.get() for v in self.hsbk]
hsbk = h, s, b, k = self.get_color()
if key == 0:
self.hsbk_display[0].config(background='#%02x%02x%02x' % HueToRGB(360 * (h / 65535)))
elif key == 1:
Expand Down Expand Up @@ -233,7 +238,7 @@ def HSBKtoRGB(hsbk):
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1 / 3)

return (int(r * 255), int(g * 255), int(b * 255))
return int(r * 255), int(g * 255), int(b * 255)


def HueToRGB(h, s=1, v=1):
Expand Down Expand Up @@ -309,14 +314,5 @@ if __name__ == "__main__":
root = Tk()
root.title("LIFX Manager")
mainframe = LifxFrame(root)
'''
# Little test DELETE ME
color = (53, 32, 23)
hsbk = utils.RGBtoHSBK(color)
print(hsbk)
rgb = HSBKtoRGB(hsbk)
print(rgb)
print(hls_to_rgb(hsbk[0]/65535, hsbk[2]/65535, hsbk[1]/65535))
# DELETE ME
'''

root.mainloop()

0 comments on commit 62d2cc4

Please sign in to comment.