Mercurial > code > home > repos > homeauto
comparison service/bedroomArduino/bedroomArduino.py @ 842:1f69e77411ba
add shiftbrites to bedroom arduino
Ignore-this: c0ce65f20b52679af58b9e31bcc3cf2e
darcs-hash:20120825212045-312f9-46f810a9229b60efb4db1200b17397c60c17c178
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Sat, 25 Aug 2012 14:20:45 -0700 |
parents | a87cae710556 |
children | 1fada3a61c5f |
comparison
equal
deleted
inserted
replaced
841:ddc2cdbfde50 | 842:1f69e77411ba |
---|---|
3 talks to bed.pde on an arduino | 3 talks to bed.pde on an arduino |
4 """ | 4 """ |
5 | 5 |
6 from __future__ import division | 6 from __future__ import division |
7 | 7 |
8 import cyclone.web, json, traceback, os, sys, time, logging | 8 import cyclone.web, json, traceback, os, sys, time, logging, bitstring |
9 from twisted.internet import reactor, task | 9 from twisted.internet import reactor, task |
10 from twisted.web.client import getPage | 10 from twisted.web.client import getPage |
11 sys.path.append("/my/proj/house/frontdoor") | 11 sys.path.append("/my/proj/house/frontdoor") |
12 from loggingserial import LoggingSerial | 12 from loggingserial import LoggingSerial |
13 sys.path.append("/my/proj/homeauto/lib") | 13 sys.path.append("/my/proj/homeauto/lib") |
14 from cycloneerr import PrettyErrorHandler | 14 from cycloneerr import PrettyErrorHandler |
15 from logsetup import log | 15 from logsetup import log |
16 | |
17 sys.path.append("/my/proj/pixel/shiftweb") | |
18 from shiftweb import hexFromRgb, rgbFromHex | |
16 | 19 |
17 sys.path.append("/my/site/magma") | 20 sys.path.append("/my/site/magma") |
18 from stategraph import StateGraph | 21 from stategraph import StateGraph |
19 from rdflib import Namespace | 22 from rdflib import Namespace |
20 | 23 |
32 assert msg == {"ok":True}, msg | 35 assert msg == {"ok":True}, msg |
33 | 36 |
34 def poll(self): | 37 def poll(self): |
35 self.ser.write("\x60\x01\x00") | 38 self.ser.write("\x60\x01\x00") |
36 ret = self.ser.readJson() | 39 ret = self.ser.readJson() |
40 ret['motion'] = int(ret['motion'] > 100) | |
37 return ret | 41 return ret |
38 | 42 |
39 def setSpeakerChoice(self, pillow): | 43 def setSpeakerChoice(self, pillow): |
40 self.ser.write("\x60\x02" + chr(pillow)) | 44 self.ser.write("\x60\x02" + chr(pillow)) |
41 return self.ser.readJson() | 45 return self.ser.readJson() |
46 | |
47 def setLeds(self, colors): | |
48 """ | |
49 shift out this sequence of (r,g,b) triples of 10-bit ints | |
50 The nearest led gets color[0], etc. | |
51 """ | |
52 resetCurrent = "".join(bitstring.pack("0b01, uint:10, uint:10, uint:10", | |
53 127, 127, 127).bytes | |
54 for loop in range(len(colors))) | |
55 out = "".join(bitstring.pack("0b00, uint:10, uint:10, uint:10", | |
56 b, r, g).bytes | |
57 for r,g,b in reversed(colors)) | |
58 out = resetCurrent + out | |
59 self.ser.write("\x60\x03" + chr(len(out)) + out) | |
60 msg = self.ser.readJson() | |
61 assert msg == {"ok":1}, msg | |
42 | 62 |
43 class Index(PrettyErrorHandler, cyclone.web.RequestHandler): | 63 class Index(PrettyErrorHandler, cyclone.web.RequestHandler): |
44 def get(self): | 64 def get(self): |
45 """ | 65 """ |
46 this is an acceptable status check since it makes a round-trip | 66 this is an acceptable status check since it makes a round-trip |
53 | 73 |
54 class SpeakerChoice(PrettyErrorHandler, cyclone.web.RequestHandler): | 74 class SpeakerChoice(PrettyErrorHandler, cyclone.web.RequestHandler): |
55 def put(self): | 75 def put(self): |
56 ret = self.settings.arduino.setSpeakerChoice(int(self.get_argument('pillow'))) | 76 ret = self.settings.arduino.setSpeakerChoice(int(self.get_argument('pillow'))) |
57 self.write(ret) | 77 self.write(ret) |
78 | |
79 class Brite(PrettyErrorHandler, cyclone.web.RequestHandler): | |
80 def put(self, which): | |
81 which = int(which) | |
82 brites = self.settings.brites | |
83 if which + 1 > len(brites): | |
84 brites.extend([(0,0,0)] * (which + 1 - len(brites))) | |
85 brites[which] = rgbFromHex(self.request.body) | |
86 | |
87 self.settings.arduino.setLeds(brites) | |
88 self.set_header("Content-Type", "text/plain") | |
89 self.write("ok") | |
58 | 90 |
59 class GraphPage(PrettyErrorHandler, cyclone.web.RequestHandler): | 91 class GraphPage(PrettyErrorHandler, cyclone.web.RequestHandler): |
60 def get(self): | 92 def get(self): |
61 self.set_header("Content-Type", "application/x-trig") | 93 self.set_header("Content-Type", "application/x-trig") |
62 g = StateGraph(ROOM['bedroomArduino']) | 94 g = StateGraph(ROOM['bedroomArduino']) |
73 def __init__(self, config, ard, period): | 105 def __init__(self, config, ard, period): |
74 self.config, self.ard = config, ard | 106 self.config, self.ard = config, ard |
75 self.period = period | 107 self.period = period |
76 self.lastValues = None | 108 self.lastValues = None |
77 self.lastPollTime = 0 | 109 self.lastPollTime = 0 |
78 self.lastMotion = False | 110 self.lastMotion = None |
79 | 111 |
80 def assertIsCurrent(self): | 112 def assertIsCurrent(self): |
81 """raise an error if the poll data is not fresh""" | 113 """raise an error if the poll data is not fresh""" |
82 dt = time.time() - self.lastPollTime | 114 dt = time.time() - self.lastPollTime |
83 if dt > period * 2: | 115 if dt > period * 2: |
89 try: | 121 try: |
90 newData = ard.poll() | 122 newData = ard.poll() |
91 except ValueError, e: | 123 except ValueError, e: |
92 print e | 124 print e |
93 else: | 125 else: |
94 print newData | 126 #print newData # for testing |
95 return | 127 |
96 self.lastPollTime = now | 128 self.lastPollTime = now |
97 self.lastValues = newData # for other data besides the blinks | 129 self.lastValues = newData # for other data besides the blinks |
98 self.processMotion(newData['motion']) | 130 self.processMotion(newData['motion']) |
99 | 131 |
100 except (IOError, OSError): | 132 except (IOError, OSError): |
119 print "post error", msg, args | 151 print "post error", msg, args |
120 | 152 |
121 if __name__ == '__main__': | 153 if __name__ == '__main__': |
122 | 154 |
123 config = { # to be read from a file | 155 config = { # to be read from a file |
124 'arduinoPort': '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A4001lVK-if00-port0', | 156 'arduinoPort': '/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A4001nIu-if00-port0', |
125 'servePort' : 9088, | 157 'servePort' : 9088, |
126 'pollFrequency' : 6, | 158 'pollFrequency' : 6, |
127 'boardName' : 'bedroom', # gets sent with updates | 159 'boardName' : 'bedroom', # gets sent with updates |
128 } | 160 } |
129 | 161 |
140 | 172 |
141 reactor.listenTCP(config['servePort'], cyclone.web.Application([ | 173 reactor.listenTCP(config['servePort'], cyclone.web.Application([ |
142 (r"/", Index), | 174 (r"/", Index), |
143 (r"/graph", GraphPage), | 175 (r"/graph", GraphPage), |
144 (r'/speakerChoice', SpeakerChoice), | 176 (r'/speakerChoice', SpeakerChoice), |
145 ], arduino=ard, poller=p)) | 177 (r'/brite/(\d+)', Brite), |
178 ], arduino=ard, poller=p, brites=[])) | |
146 reactor.run() | 179 reactor.run() |