diff service/piNode/piNode.py @ 1026:8e075449ba0a

piNode support for temp sensors. proper hostname lookup Ignore-this: a68c3319bffb16c55cbb5f329118f0a4 darcs-hash:3b4c8482b870731064ae5685d32a4206b7a2d7d6
author drewp <drewp@bigasterisk.com>
date Mon, 18 Jan 2016 22:43:22 -0800
parents f58b5536f683
children c5589f21d4a3
line wrap: on
line diff
--- a/service/piNode/piNode.py	Sun Jan 03 02:32:46 2016 -0800
+++ b/service/piNode/piNode.py	Mon Jan 18 22:43:22 2016 -0800
@@ -1,5 +1,5 @@
 from __future__ import division
-import sys, logging, socket, json
+import sys, logging, socket, json, time
 import cyclone.web
 from rdflib import Namespace, URIRef, Literal, Graph, RDF
 from rdflib.parser import StringInputSource
@@ -10,7 +10,7 @@
 sys.path.append("../../../../site/magma")
 
 from stategraph import StateGraph
-sys.path.append('/home/pi/dim/PIGPIO')
+sys.path.append('/opt/pigpio')
 try:
     import pigpio
 except ImportError:
@@ -21,6 +21,9 @@
 
 import devices
 
+# from /my/proj/room
+from carbondata import CarbonClient
+
 log = logging.getLogger()
 logging.getLogger('serial').setLevel(logging.WARN)
 ROOM = Namespace('http://projects.bigasterisk.com/room/')
@@ -33,7 +36,7 @@
         self.graph = Graph()
         log.info('read config')
         self.graph.parse('config.n3', format='n3')
-        self.graph.bind('', ROOM) # not working
+        self.graph.bind('', ROOM) # maybe working
         self.graph.bind('rdf', RDF)
 
 class GraphPage(cyclone.web.RequestHandler):
@@ -58,6 +61,7 @@
         self._devs = devices.makeDevices(graph, self.uri, self.pi)
         log.debug('found %s devices', len(self._devs))
         self._statementsFromInputs = {} # input device uri: latest statements
+        self._carbon = CarbonClient(serverHost='bang')
 
     def startPolling(self):
         task.LoopingCall(self._poll).start(.5)
@@ -65,7 +69,8 @@
     def _poll(self):
         for i in self._devs:
             self._statementsFromInputs[i.uri] = i.poll()
-        
+        self._exportToGraphite()
+
     def outputStatements(self, stmts):
         unused = set(stmts)
         for dev in self._devs:
@@ -85,6 +90,25 @@
             log.warn("No devices cared about these statements:")
             for s in unused:
                 log.warn(repr(s))
+                
+    # needs merge with arduinoNode.py
+    def _exportToGraphite(self):
+        # note this is writing way too often- graphite is storing at a lower res
+        now = time.time()
+        # 20 sec is not precise; just trying to reduce wifi traffic
+        if getattr(self, 'lastGraphiteExport', 0) + 20 > now:
+            return
+        self.lastGraphiteExport = now
+        log.debug('graphite export:')
+        # objects of these statements are suitable as graphite values.
+        graphitePredicates = {ROOM['temperatureF']}
+        # bug: one sensor can have temp and humid- this will be ambiguous
+        for s, graphiteName in self.graph.subject_objects(ROOM['graphiteName']):
+            for group in self._statementsFromInputs.values():
+                for stmt in group:
+                    if stmt[0] == s and stmt[1] in graphitePredicates:
+                        log.debug('  sending %s -> %s', stmt[0], graphiteName)
+                        self._carbon.send(graphiteName, stmt[2].toPython(), now)
         
     def currentGraph(self):
         g = Graph()
@@ -154,8 +178,16 @@
         # notify reasoning
         pass
 
-    thisBoard = URIRef('http://bigasterisk.com/homeauto/node2')
-    
+    thisHost = Literal(socket.gethostname())
+    for row in config.graph.query(
+            'SELECT ?board WHERE { ?board a :PiBoard; :hostname ?h }',
+            initBindings=dict(h=thisHost)):
+        thisBoard = row.board
+        break
+    else:
+        raise ValueError("config had no board for :hostname %r" % thisHost)
+
+    log.info("found config for board %r" % thisBoard)
     board = Board(config.graph, thisBoard, onChange)
     board.startPolling()