lightrix/lightrix/patterns.py

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)