Mercurial > code > home > repos > homeauto
changeset 1123:2ff06e28eef0
colplay updates, then it was hacked up to do VU meter mode
Ignore-this: 122db2f66f00c0eb505e5c6413c50cc2
darcs-hash:f61d6aee513118c3ebcf6be68ae8b31ae6dc60a7
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sun, 29 Jan 2017 00:03:50 -0800 |
parents | 9cb135126a63 |
children | f088e2a02ce4 |
files | service/colplay/colplay.py service/colplay/pattern.png |
diffstat | 2 files changed, 78 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/service/colplay/colplay.py Mon Jan 16 16:54:10 2017 -0800 +++ b/service/colplay/colplay.py Sun Jan 29 00:03:50 2017 -0800 @@ -14,10 +14,27 @@ from dateutil.tz import tzlocal from cyclone.httpclient import fetch from webcolors import rgb_to_hex +from influxdb import InfluxDBClient -logging.basicConfig(level=logging.DEBUG) +influx = InfluxDBClient('bang', 9060, 'root', 'root', 'main') + +def currentAudio(location='brace'): + t = time.time() + row = list(influx.query("""SELECT mean(value) FROM audioLevel WHERE "location" = '%s' AND time > %ds""" % (location, t - 30)))[0][0] + log.debug("query took %.03fms", 1000 * (time.time() - t)) + base = {'brace': .020, + 'living': .03, + }[location] + high = { + 'brace': .1, + 'living': .3, + }[location] + return max(0.0, min(1.0, (row['mean'] - base) / high)) + + +logging.basicConfig(level=logging.INFO) log = logging.getLogger() -logging.getLogger('restkit.client').setLevel(logging.WARN) +logging.getLogger('requests.packages.urllib3.connectionpool').setLevel(logging.WARN) class Img(object): def __init__(self, filename): @@ -37,19 +54,43 @@ if os.path.getmtime(self.filename) > self.mtime: self.reread() return [v * 4 for v in self.img.getpixel((x, y))[:3]] + +theaterUrl = 'http://10.1.0.1:9059/output?p=http://projects.bigasterisk.com/room/color&s=http://bigasterisk.com/homeauto/board0/' lightResource = { - 'theater0': 'http://bang:9059/output?s=http://bigasterisk.com/homeauto/board0/rgb_right_top_2&p=http://projects.bigasterisk.com/room/color', + 'theater_left_top_0': theaterUrl + 'rgb_left_top_0', + 'theater_left_top_1': theaterUrl + 'rgb_left_top_1', + 'theater_left_top_2': theaterUrl + 'rgb_left_top_2', + 'theater_right_top_2': theaterUrl + 'rgb_right_top_2', + 'theater_right_top_1': theaterUrl + 'rgb_right_top_1', + 'theater_right_top_0': theaterUrl + 'rgb_right_top_0', + 'theater_left_bottom_0': theaterUrl + 'rgb_left_bottom_0', + 'theater_left_bottom_1': theaterUrl + 'rgb_left_bottom_1', + 'theater_left_bottom_2': theaterUrl + 'rgb_left_bottom_2', + 'theater_right_bottom_2': theaterUrl + 'rgb_right_bottom_2', + 'theater_right_bottom_1': theaterUrl + 'rgb_right_bottom_1', + 'theater_right_bottom_0': theaterUrl + 'rgb_right_bottom_0', } lightYPos = { - 'theater0' : 135, + 'theater_left_top_0': 130, + 'theater_left_top_1': 132, + 'theater_left_top_2': 134, + 'theater_right_top_2': 135, + 'theater_right_top_1': 137, + 'theater_right_top_0': 139, + 'theater_left_bottom_0': 153, + 'theater_left_bottom_1': 156, + 'theater_left_bottom_2': 159, + 'theater_right_bottom_2': 162, + 'theater_right_bottom_1': 165, + 'theater_right_bottom_0': 168, } def hexFromRgb(rgb): return rgb_to_hex(tuple([x // 4 for x in rgb])).encode('ascii') -def setColor(lightName, rgb, _req): +def setColor(lightName, rgb): """takes 10-bit r,g,b returns even if the server is down @@ -57,33 +98,27 @@ log.debug("setColor(%r,%r)", lightName, rgb) serv = lightResource[lightName] - try: - h = hexFromRgb(rgb) - log.debug("put %r to %r", h, serv) - r = _req(method='PUT', url=serv, body=h, - headers={"content-type":"text/plain"}) - return r - except Exception, e: - log.warn("Talking to: %r" % serv) - log.warn(e) - return None -def setColorAsync(lightName, rgb): - """ - uses twisted http, return deferred or sometimes None when there - was a warning - """ - def _req(method, url, body, headers): - d = fetch(url=url, method=method, postdata=body, - headers=dict((k,[v]) for k,v in headers.items())) - @d.addErrback - def err(e): - log.warn("http client error on %s: %s" % (url, e)) - raise e - return d - setColor(lightName, rgb, _req=_req) + h = hexFromRgb(rgb) + log.debug("put %r to %r", h, serv) + t1 = time.time() + d = fetch(url=serv, method='PUT', postdata=h, + headers={'content-type': ['text/plain']}) + + def err(e): + log.warn("http client error on %s: %s" % (serv, e)) + raise e + d.addErrback(err) + def done(ret): + log.debug('put took %.1fms', 1000 * (time.time() - t1)) + d.addCallback(done) + return d + + +pxPerHour = 100 + class LightState(object): def __init__(self): self.lastUpdateTime = 0 @@ -101,16 +136,26 @@ try: now = datetime.now(tzlocal()) hr = now.hour + now.minute / 60 + now.second / 3600 - x = int(((hr - 12) % 24) * 50) + x = int(((hr - 12) % 24) * pxPerHour) % 2400 log.debug("x = %s", x) - for name, ypos in lightYPos.items(): + audioLevel = currentAudio('brace') + log.debug('level = %s', audioLevel) + for i, (name, ypos) in enumerate(sorted(lightYPos.items())): + + if i / len(lightYPos) < audioLevel: + setColor(name, (500, 0, 0)) + else: + setColor(name, (0, 0, 0)) + continue + if now > self.autosetAfter[name]: c = self.img.getColor(x, ypos) - setColorAsync(name, c) + d = setColor(name, c) self.lastUpdateTime = time.time() except Exception: self.lastError = traceback.format_exc() + log.error(self.lastError) self.lastErrorTime = time.time() @@ -127,7 +172,7 @@ ), indent=4)) lightState = LightState() -task.LoopingCall(lightState.step).start(1) +task.LoopingCall(lightState.step).start(3)#3600 / pxPerHour) log.info("listening http on 9051") reactor.listenTCP(9051, cyclone.web.Application([ (r'/', IndexHandler),