147 lines
5.4 KiB
Python
147 lines
5.4 KiB
Python
|
|
import time
|
|
import datetime
|
|
import pytz
|
|
|
|
class Lightrix:
|
|
|
|
def __init__(self, strip, matrix=None):
|
|
self.strip = strip
|
|
self.matrix = matrix
|
|
|
|
self.patterns = {}
|
|
self.patterns[u'red'] = lambda ix, msg: (255, 0, 0)
|
|
self.patterns[u'green'] = lambda ix, msg: (0, 255, 0)
|
|
self.patterns[u'blue'] = lambda ix, msg: (0, 0, 255)
|
|
self.patterns[u'yellow'] = lambda ix, msg: (255, 255, 0)
|
|
self.patterns[u'white'] = lambda ix, msg: (255, 255, 255)
|
|
self.patterns[u'off'] = lambda ix, msg: (0,0,0)
|
|
self.patterns[u'purple'] = lambda ix, msg: (255,0,255)
|
|
self.patterns[u'cyan'] = lambda ix, msg: (0,255,255)
|
|
self.patterns[u'rainbow'] = lambda ix, msg: self.wheel(int(255 * ix / self.strip.count()))
|
|
self.patterns[u'cycle'] = self.rainbowCycle
|
|
self.patterns[u'timebase'] = self.timebased
|
|
self.patterns[u'wheel'] = self.wheelStrip
|
|
|
|
|
|
def handler(self, event):
|
|
etype = event[u'type']
|
|
if etype == "m.room.message":
|
|
self.handle_message(event)
|
|
if etype == "org.lightrix.color":
|
|
self.handle_lightrix(event) # XXX
|
|
|
|
def handle_lightrix(self, event):
|
|
color = event[u'content'].get(u'color')
|
|
r = color[u'r']
|
|
g = color[u'g']
|
|
b = color[u'b']
|
|
|
|
for led_idx in range(0, self.strip.count()):
|
|
self.strip.setPixelRgb(led_idx, r,g,b)
|
|
for room_id in self.matrix.room_ids:
|
|
self.matrix.client.api.send_state_event(
|
|
room_id, "org.lightrix.pattern",
|
|
{"state": self.strip.show(), "from_msg": color}
|
|
)
|
|
|
|
self.strip.show()
|
|
|
|
def handle_message(self, event):
|
|
if not event[u'content'].get(u'body'):
|
|
return
|
|
text = event[u'content'][u'body'].lower()
|
|
room = self.matrix.rooms.get(str(event[u'room_id']))
|
|
if not room:
|
|
return
|
|
if text.startswith("!brightness"):
|
|
brightness = int(text.split(' ')[1])
|
|
room.send_text("Setting brightness to %s/255" % brightness)
|
|
self.set_brightness(int(text.split(' ')[1]))
|
|
return
|
|
if text.startswith("!wheel"):
|
|
self.set_pattern(u'wheel', text)
|
|
return
|
|
if text.startswith("!join"):
|
|
room = text.split(' ')[1:]
|
|
self.matrix.join_room(str(room))
|
|
return
|
|
if not text in self.patterns:
|
|
return
|
|
room.send_text("Setting color to %s" % text)
|
|
self.set_pattern(text, text)
|
|
|
|
|
|
def set_brightness(self, brightness):
|
|
if brightness > 255:
|
|
return
|
|
if brightness < 0:
|
|
return
|
|
self.strip.setBrightness(brightness)
|
|
self.strip.show()
|
|
for room_id in self.matrix.room_ids:
|
|
self.matrix.client.api.send_state_event(
|
|
room_id, "org.lightrix.brightness",
|
|
brightness
|
|
)
|
|
|
|
|
|
|
|
def set_pattern(self, pattern, msg=None):
|
|
patfunc = self.patterns[pattern]
|
|
for led_idx in range(0, self.strip.count()):
|
|
color = patfunc(led_idx, msg)
|
|
self.strip.setPixelRgb(led_idx, color[0], color[1], color[2])
|
|
for room_id in self.matrix.room_ids:
|
|
self.matrix.client.api.send_state_event(
|
|
room_id, "org.lightrix.pattern",
|
|
{"pattern": pattern, "state": self.strip.show(), "from_msg": msg}
|
|
)
|
|
|
|
def wheel(self, pos):
|
|
"""Generate rainbow colors across 0-255 positions."""
|
|
if pos < 85:
|
|
return (pos * 3, 255 - pos * 3, 0)
|
|
elif pos < 170:
|
|
pos -= 85
|
|
return (255 - pos * 3, 0, pos * 3)
|
|
else:
|
|
pos -= 170
|
|
return (0, pos * 3, 255 - pos * 3)
|
|
|
|
def rainbowCycle(self, idx, msg, wait_ms=20, iterations=5):
|
|
"""Draw rainbow that uniformly distributes itself across all pixels."""
|
|
for j in range(256*iterations):
|
|
for i in range(self.strip.count()):
|
|
self.strip.setPixelRgb(i, self.wheel(((i * 256 / self.strip.count()) + j) & 255))
|
|
self.strip.show()
|
|
time.sleep(wait_ms/1000.0)
|
|
return
|
|
|
|
def timebased(self, idx, msg):
|
|
"""Set different colors depending on the time of the day"""
|
|
time = datetime.datetime.now(tz=pytz.timezone('US/Pacific'))
|
|
m = time.minute
|
|
if time.hour < 7 and time.hour >= 0: # low red at night
|
|
return (64, 0, 0)
|
|
if time.hour == 7: # fade to brighter yellow over the morning
|
|
return (64 + m, m, 0)
|
|
if time.hour == 8: # fade to brighter yellow over the morning
|
|
return (128 + m, 64 + m, m)
|
|
if time.hour == 9: # fade to brighter yellow over the morning
|
|
return (202 + m, 128 + m, 64 + m)
|
|
if time.hour > 9 and time.hour < 18: # off during the day
|
|
return (0, 0, 0)
|
|
if time.hour >= 18 and time.hour < 22: # medium yellow-white in the evening
|
|
return (255, 255, 128)
|
|
if time.hour == 22: # slowly fade to low red over the hour
|
|
return (255 - m*2, 255 - m*2, 128 - m)
|
|
if time.hour == 23: # slowly fade to low red over the hour
|
|
return (64 + 60 - m, 64 + 60 - (m * 2), 0)
|
|
return (64, 0, 0) # failback
|
|
|
|
def wheelStrip(self, idx, msg):
|
|
"""A strip of colors based on a wheel index"""
|
|
val = int(msg.split(' ')[1])
|
|
return self.wheel(val)
|