master
Ryan Rix 2016-03-13 08:54:23 +00:00
parent 9bd04c5563
commit d6d54b05da
1 changed files with 27 additions and 195 deletions

View File

@ -1,202 +1,34 @@
#!/bin/env python
from matrix_client.client import MatrixClient
import argparse
import lightrix.matrix as mc
import lightrix.patterns as lightrix
import lightrix.strip as strip
import click
import os
import sys
import yaml
import sys
import os
from neopixel import *
import time
import datetime
import pytz
LED_COUNT = 48
LED_PIN = 18
LED_FREQ_HZ = 800000
LED_DMA = 10
LED_BRIGHTNESS = 255
LED_INVERT = False
class Lightrix:
def __init__(self, config, room):
self.rooms = {}
self.room_ids = []
self.strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ,
LED_DMA, LED_INVERT, LED_BRIGHTNESS)
self.strip.begin()
self.init_patterns()
self.set_pattern(self.patterns['timebase'])
self.client = MatrixClient(config['homeserver_uri'])
self.token = self.client.login_with_password(username=config['username'],
password=config['password'])
self.rooms = {}
self.room_ids = []
self.join_room(room)
self.rooms[room].send_text("Started up, set to timebase.")
return
def init_patterns(self):
def wheel(pos):
"""Generate rainbow colors across 0-255 positions."""
if pos < 85:
return Color(pos * 3, 255 - pos * 3, 0)
elif pos < 170:
pos -= 85
return Color(255 - pos * 3, 0, pos * 3)
else:
pos -= 170
return Color(0, pos * 3, 255 - pos * 3)
def rainbowCycle(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.numPixels()):
self.strip.setPixelColor(i, wheel(((i * 256 / self.strip.numPixels()) + j) & 255))
self.strip.show()
time.sleep(wait_ms/1000.0)
return
def timebased(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 Color(64, 0, 0)
if time.hour == 7: # fade to brighter yellow over the morning
return Color(64 + m, m, 0)
if time.hour == 8: # fade to brighter yellow over the morning
return Color(128 + m, 64 + m, m)
if time.hour == 9: # fade to brighter yellow over the morning
return Color(202 + m, 128 + m, 64 + m)
if time.hour > 9 and time.hour < 18: # off during the day
return Color(0, 0, 0)
if time.hour >= 18 and time.hour < 22: # medium yellow-white in the evening
return Color(255, 255, 128)
if time.hour == 22: # slowly fade to low red over the hour
return Color(255 - m*2, 255 - m*2, 128 - m)
if time.hour == 23: # slowly fade to low red over the hour
return Color(64 + 60 - m, 64 + 60 - (m * 2), 0)
return Color(64, 0, 0) # failback
def wheelStrip(idx, msg):
"""A strip of colors based on a wheel index"""
val = int(msg.split(' ')[1])
return wheel(val)
np = self.strip.numPixels()
self.patterns = {}
self.patterns[u'red'] = [Color(255, 0, 0) for i in range(0, np)]
self.patterns[u'green'] = [Color(0, 255, 0) for i in range(0, np)]
self.patterns[u'blue'] = [Color(0, 0, 255) for i in range(0, np)]
self.patterns[u'yellow'] = [Color(255, 255, 0) for i in range(0, np)]
self.patterns[u'white'] = [Color(255, 255, 255) for i in range(0, np)]
self.patterns[u'off'] = [Color(0,0,0) for i in range(0, np)]
self.patterns[u'purple'] = [Color(255,0,255) for i in range(0, np)]
self.patterns[u'cyan'] = [Color(0,255,255) for i in range(0, np)]
self.patterns[u'rainbow'] = [wheel(int(255 * i / np)) for i in range(0, np)]
self.patterns[u'cycle'] = rainbowCycle
self.patterns[u'timebase'] = timebased
self.patterns[u'wheel'] = wheelStrip
return
def join_room(self, room_id):
room = self.client.join_room(room_id)
self.rooms[room_id] = room
self.room_ids.append(room_id)
return
def set_brightness(self, brightness):
if brightness > 255:
return
if brightness < 0:
return
self.strip.setBrightness(brightness)
self.strip.show()
def listen_and_glow(self):
self.idle_since = datetime.datetime.now()
def maybe_idle():
tdel = datetime.datetime.now() - self.idle_since
if tdel.seconds > 5 * 60: # idle for five minutes
self.set_pattern(self.patterns['timebase'])
def glow_from_message_maybe(chunk):
try:
if chunk[u'type'] != u'm.room.message':
maybe_idle()
return
if not chunk[u'room_id'] in self.room_ids:
maybe_idle()
return
text = chunk[u'content'][u'body'].lower()
room = self.rooms[chunk[u'room_id']]
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(self.patterns[u'wheel'], text)
return
if text.startswith("!join"):
room = text.split(' ')[1:]
room.send_text("Joining %s" % room)
self.join_room(room)
return
if not text in self.patterns:
maybe_idle()
return
room.send_text("Setting color to %s" % text)
self.set_pattern(self.patterns[text])
except Exception as e:
print(e)
self.rooms[self.room_ids[0]].send_text("Error setting settings, try something else?")
self.rooms[self.room_ids[0]].send_text(str(e))
pass
self.client.add_listener(glow_from_message_maybe)
while(True):
self.client.listen_for_events(timeout=30000)
maybe_idle()
return
def set_pattern(self, pattern, msg=None):
# XXX: Retcon this in to a single thing.
for led_idx in range(0, self.strip.numPixels()):
if type(pattern) == list:
self.strip.setPixelColor(led_idx, pattern[led_idx])
else:
color = pattern(led_idx, msg)
self.strip.setPixelColor(led_idx, color)
self.strip.show()
self.idle_since = datetime.datetime.now()
# Announce
for room_id in self.room_ids:
self.client.api.send_message_event(room_id, "m.lightrix.pattern", {"pattern": str(pattern), "from_msg": msg})
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Pipe in to and out of a Matrix room")
parser.add_argument('--config_path', "-c", default="~/.mcatrc")
parser.add_argument('--room', "-r")
args = parser.parse_args()
if args.room is None:
@click.command()
@click.option('--config', '-c', default="~/.mcatrc", type=click.Path(exists=True))
@click.option('--room-id', '-r')
def start(config, room_id):
if room_id is None:
print("Require --room argument")
sys.exit(1)
if not os.path.exists(args.config_path):
if not os.path.exists(config):
print("Configuration file doesn't exist, please create one")
sys.exit(1)
mcat = None
with open(args.config_path) as f:
lightrix = Lightrix(yaml.safe_load(f), args.room)
lightrix.listen_and_glow()
led_count = 48
with open(config) as f:
conf = yaml.safe_load(f)
s = strip.Strip(count=led_count)
lx = lightrix.Lightrix(s)
client = mc.Client(conf['homeserver_uri'],
conf['username'], conf['password'],
room_id, strip=s)
lx.matrix = client
client.add_listener(lx.handler)
client.listen()
if __name__ == '__main__':
start()