comparison service/piNode/piNode.py @ 987:cc79d092e136

start pinode Ignore-this: bfafd9994f7f9a61919d49274417ebbb darcs-hash:20150531075655-312f9-15aefdee47756afdbde1b6c83f8797b5f0bb3a88
author drewp <drewp@bigasterisk.com>
date Sun, 31 May 2015 00:56:55 -0700
parents
children 634d6e477953
comparison
equal deleted inserted replaced
986:b279ca8d2894 987:cc79d092e136
1 from __future__ import division
2 import glob, sys, logging, subprocess, socket, os, hashlib, time, tempfile
3 import shutil, json, socket
4 import cyclone.web
5 from rdflib import Graph, Namespace, URIRef, Literal, RDF
6 from rdflib.parser import StringInputSource
7 from twisted.internet import reactor, task
8 from docopt import docopt
9 logging.basicConfig(level=logging.DEBUG)
10 sys.path.append("/my/site/magma")
11 from stategraph import StateGraph
12 sys.path.append('/home/pi/dim/PIGPIO')
13 import pigpio
14
15 import devices
16
17 log = logging.getLogger()
18 logging.getLogger('serial').setLevel(logging.WARN)
19 ROOM = Namespace('http://projects.bigasterisk.com/room/')
20 HOST = Namespace('http://bigasterisk.com/ruler/host/')
21
22 hostname = socket.gethostname()
23
24 class GraphPage(cyclone.web.RequestHandler):
25 def get(self):
26 g = StateGraph(ctx=ROOM['pi/%s' % hostname])
27
28 for stmt in self.settings.board.currentGraph():
29 g.add(stmt)
30
31 if self.get_argument('config', 'no') == 'yes':
32 for stmt in self.settings.config.graph:
33 g.add(stmt)
34
35 self.set_header('Content-type', 'application/x-trig')
36 self.write(g.asTrig())
37
38 class Board(object):
39 """similar to arduinoNode.Board but without the communications stuff"""
40 def __init__(self, graph, uri, onChange):
41 self.graph, self.uri = graph, uri
42 self.pi = pigpio.pi()
43 self._devs = devices.makeDevices(graph, self.uri, self.pi)
44 self._statementsFromInputs = {} # input device uri: latest statements
45
46 def startPolling(self):
47 task.LoopingCall(self._poll).start(.5)
48
49 def _poll(self):
50 for i in self._devs:
51 self._statementsFromInputs[i.uri] = i.poll()
52
53 def outputStatements(self, stmts):
54 unused = set(stmts)
55 for dev in self._devs:
56 stmtsForDev = []
57 for pat in dev.outputPatterns():
58 if [term is None for term in pat] != [False, False, True]:
59 raise NotImplementedError
60 for stmt in stmts:
61 if stmt[:2] == pat[:2]:
62 stmtsForDev.append(stmt)
63 unused.discard(stmt)
64 if stmtsForDev:
65 log.info("output goes to action handler for %s" % dev.uri)
66 dev.sendOutput(stmtsForDev)
67 log.info("success")
68 if unused:
69 log.warn("No devices cared about these statements:")
70 for s in unused:
71 log.warn(repr(s))
72
73 class OutputPage(cyclone.web.RequestHandler):
74
75 def put(self):
76 subj = URIRef(self.get_argument('s'))
77 pred = URIRef(self.get_argument('p'))
78
79 turtleLiteral = self.request.body
80 try:
81 obj = Literal(float(turtleLiteral))
82 except TypeError:
83 obj = Literal(turtleLiteral)
84
85 stmt = (subj, pred, obj)
86 self.settings.board.outputStatements([stmt])
87
88
89 def main():
90 arg = docopt("""
91 Usage: piNode.py [options]
92
93 -v Verbose
94 """)
95 log.setLevel(logging.WARN)
96 if arg['-v']:
97 from twisted.python import log as twlog
98 twlog.startLogging(sys.stdout)
99
100 log.setLevel(logging.DEBUG)
101
102 config = Config()
103
104 def onChange():
105 # notify reasoning
106 pass
107
108 thisBoard = URIRef('http://bigasterisk.com/homeauto/node2')
109
110 board = Board(config.graph, thisBoard, onChange)
111
112 reactor.listenTCP(9059, cyclone.web.Application([
113 (r"/()", cyclone.web.StaticFileHandler, {
114 "path": "static", "default_filename": "index.html"}),
115 (r'/static/(.*)', cyclone.web.StaticFileHandler, {"path": "static"}),
116 (r"/graph", GraphPage),
117 (r'/output', OutputPage),
118 (r'/dot', Dot),
119 ], config=config, board=board))
120 reactor.run()
121
122 main()