master
Ryan Rix 7 years ago
parent 9bd04c5563
commit d6d54b05da

@ -1,202 +1,34 @@
#!/bin/env python
from matrix_client.client import MatrixClient
import argparse
import yaml
import sys
import lightrix.matrix as mc
import lightrix.patterns as lightrix
import lightrix.strip as strip
import click
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})
import sys
import yaml
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()

Loading…
Cancel
Save