annotate service/shuttlepro/shuttleservice.py @ 936:b1eabeb7dc66

format Ignore-this: b956bc580c14c347ec202e72b4b26870 darcs-hash:20131012055217-312f9-3debd15affd6b52e56d4079291aed076b92640c1
author drewp <drewp@bigasterisk.com>
date Fri, 11 Oct 2013 22:52:17 -0700
parents 9bb3eac740f0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
935
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
1 import sys, time
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
2 import cyclone.web, cyclone.httpclient, cyclone.websocket
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
3 sys.path.append("../../lib")
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
4 from logsetup import log
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
5 from cycloneerr import PrettyErrorHandler
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
6 from twisted.internet import reactor, threads
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
7 from shuttlepro import powermate
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
8 sys.path.append("/my/site/magma")
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
9 from stategraph import StateGraph
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
10
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
11 from rdflib import Namespace, Graph, Literal
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
12 SHUTTLEPRO = Namespace("http://bigasterisk.com/room/livingRoom/shuttlepro/")
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
13 ROOM = Namespace("http://projects.bigasterisk.com/room/")
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
14
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
15 def sendOneShotGraph(g):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
16 if not g:
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
17 return
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
18
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
19 nt = g.serialize(format='nt')
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
20 cyclone.httpclient.fetch(
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
21 "http://bang:9071/oneShot",
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
22 method='POST',
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
23 postdata=nt,
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
24 timeout=1,
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
25 headers={'Content-Type': ['text/n3']},
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
26 ).addErrback(log.error)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
27
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
28 class Index(PrettyErrorHandler, cyclone.web.StaticFileHandler):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
29 def get(self, *args, **kw):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
30 self.settings.poller.assertCurrent()
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
31 return cyclone.web.StaticFileHandler.get(self, *args, **kw)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
32
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
33 class GraphResource(PrettyErrorHandler, cyclone.web.RequestHandler):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
34 def get(self):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
35 p = self.settings.poller
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
36 g = StateGraph(ROOM.environment)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
37 g.add((SHUTTLEPRO['shuttle'], ROOM['angle'],
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
38 Literal(p.currentShuttleAngle)))
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
39 g.add((SHUTTLEPRO['dial'], ROOM['totalDialMovement'],
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
40 Literal(p.totalDialMovement)))
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
41 self.set_header('Content-type', 'application/x-trig')
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
42 self.write(g.asTrig())
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
43
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
44 class Poller(object):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
45 def __init__(self, dev="/dev/input/by-id/usb-Contour_Design_ShuttlePRO-event-if00"):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
46 self.lastUpdateTime = 0
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
47 self.p = powermate(dev, self.onEvent)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
48 self.updateLoop()
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
49 self.currentShuttleAngle = 0
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
50 self.totalDialMovement = 0
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
51
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
52 def assertCurrent(self):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
53 ago = time.time() - self.lastUpdateTime
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
54 if ago > 60: # this may have to go up depending on how read_next times out
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
55 raise ValueError("last usb update was %s sec ago" % ago)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
56
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
57 def onEvent(self, what):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
58 print 'onEvent', what
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
59 g = Graph()
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
60 if 'key' in what:
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
61 g.add((SHUTTLEPRO['button%s' % what['key']['button']],
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
62 ROOM['state'],
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
63 ROOM['press'] if what['key']['press'] else ROOM['release']))
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
64 elif 'shuttle' in what:
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
65 # this will send lots of repeats. It's really not a one-shot at all.
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
66 g.add((SHUTTLEPRO['shuttle'], ROOM['position'],
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
67 Literal(what['shuttle'])))
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
68 self.currentShuttleAngle = what['shuttle']
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
69 elif 'dial' in what:
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
70 g.add((SHUTTLEPRO['dial'], ROOM['change'],
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
71 ROOM['clockwise'] if what['dial'] == 1 else
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
72 ROOM['counterclockwise']))
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
73 self.totalDialMovement += what['dial']
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
74 sendOneShotGraph(g)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
75
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
76 def updateLoop(self, *prevResults):
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
77 self.lastUpdateTime = time.time()
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
78 threads.deferToThread(
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
79 self.p.read_next
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
80 ).addCallback(self.updateLoop)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
81
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
82 if __name__ == '__main__':
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
83 from twisted.python import log as twlog
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
84 twlog.startLogging(sys.stdout)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
85 port = 9103
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
86 poller = Poller()
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
87 reactor.listenTCP(port, cyclone.web.Application(handlers=[
936
drewp <drewp@bigasterisk.com>
parents: 935
diff changeset
88 (r'/()', Index, {"path" : ".", "default_filename" : "index.html"}),
935
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
89 (r'/graph', GraphResource),
936
drewp <drewp@bigasterisk.com>
parents: 935
diff changeset
90 # serves this source code too
drewp <drewp@bigasterisk.com>
parents: 935
diff changeset
91 (r'/(.*)', cyclone.web.StaticFileHandler, {"path" : "."})
935
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
92 ], poller=poller))
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
93 log.info("serving on %s" % port)
9bb3eac740f0 new shuttlepro web service with /graph
drewp <drewp@bigasterisk.com>
parents:
diff changeset
94 reactor.run()