diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/piNode/piNode.py	Sun May 31 00:56:55 2015 -0700
@@ -0,0 +1,122 @@
+from __future__ import division
+import glob, sys, logging, subprocess, socket, os, hashlib, time, tempfile
+import shutil, json, socket
+import cyclone.web
+from rdflib import Graph, Namespace, URIRef, Literal, RDF
+from rdflib.parser import StringInputSource
+from twisted.internet import reactor, task
+from docopt import docopt
+logging.basicConfig(level=logging.DEBUG)
+sys.path.append("/my/site/magma")
+from stategraph import StateGraph
+sys.path.append('/home/pi/dim/PIGPIO')
+import pigpio
+
+import devices
+
+log = logging.getLogger()
+logging.getLogger('serial').setLevel(logging.WARN)
+ROOM = Namespace('http://projects.bigasterisk.com/room/')
+HOST = Namespace('http://bigasterisk.com/ruler/host/')
+
+hostname = socket.gethostname()
+
+class GraphPage(cyclone.web.RequestHandler):
+    def get(self):
+        g = StateGraph(ctx=ROOM['pi/%s' % hostname])
+
+        for stmt in self.settings.board.currentGraph():
+            g.add(stmt)
+
+        if self.get_argument('config', 'no') == 'yes':
+            for stmt in self.settings.config.graph:
+                g.add(stmt)
+        
+        self.set_header('Content-type', 'application/x-trig')
+        self.write(g.asTrig())
+
+class Board(object):
+    """similar to arduinoNode.Board but without the communications stuff"""
+    def __init__(self, graph, uri, onChange):
+        self.graph, self.uri = graph, uri
+        self.pi = pigpio.pi()
+        self._devs = devices.makeDevices(graph, self.uri, self.pi)
+        self._statementsFromInputs = {} # input device uri: latest statements
+
+    def startPolling(self):
+        task.LoopingCall(self._poll).start(.5)
+
+    def _poll(self):
+        for i in self._devs:
+            self._statementsFromInputs[i.uri] = i.poll()
+        
+    def outputStatements(self, stmts):
+        unused = set(stmts)
+        for dev in self._devs:
+            stmtsForDev = []
+            for pat in dev.outputPatterns():
+                if [term is None for term in pat] != [False, False, True]:
+                    raise NotImplementedError
+                for stmt in stmts:
+                    if stmt[:2] == pat[:2]:
+                        stmtsForDev.append(stmt)
+                        unused.discard(stmt)
+            if stmtsForDev:
+                log.info("output goes to action handler for %s" % dev.uri)
+                dev.sendOutput(stmtsForDev)
+                log.info("success")
+        if unused:
+            log.warn("No devices cared about these statements:")
+            for s in unused:
+                log.warn(repr(s))
+        
+class OutputPage(cyclone.web.RequestHandler):
+   
+    def put(self):
+        subj = URIRef(self.get_argument('s'))
+        pred = URIRef(self.get_argument('p'))
+
+        turtleLiteral = self.request.body
+        try:
+            obj = Literal(float(turtleLiteral))
+        except TypeError:
+            obj = Literal(turtleLiteral)
+
+        stmt = (subj, pred, obj)
+        self.settings.board.outputStatements([stmt])
+
+
+def main():
+    arg = docopt("""
+    Usage: piNode.py [options]
+
+    -v   Verbose
+    """)
+    log.setLevel(logging.WARN)
+    if arg['-v']:
+        from twisted.python import log as twlog
+        twlog.startLogging(sys.stdout)
+
+        log.setLevel(logging.DEBUG)
+    
+    config = Config()
+
+    def onChange():
+        # notify reasoning
+        pass
+
+    thisBoard = URIRef('http://bigasterisk.com/homeauto/node2')
+    
+    board = Board(config.graph, thisBoard, onChange)
+    
+    reactor.listenTCP(9059, cyclone.web.Application([
+        (r"/()", cyclone.web.StaticFileHandler, {
+            "path": "static", "default_filename": "index.html"}),
+        (r'/static/(.*)', cyclone.web.StaticFileHandler, {"path": "static"}),
+        (r"/graph", GraphPage),
+        (r'/output', OutputPage),
+        (r'/dot', Dot),
+        ], config=config, board=board))
+    reactor.run()
+
+main()