changeset 243:141079644c45

piNode poll switches much faster. mirror the logic in arduinoNode though vari-rate poll is not supported yet Ignore-this: 4ef38c7a2ed35f77035209bffeffc245
author drewp@bigasterisk.com
date Tue, 02 Feb 2016 22:37:11 -0800
parents 3f936fb61e4e
children f4e762943c11
files service/arduinoNode/arduinoNode.py service/piNode/devices.py service/piNode/piNode.py
diffstat 3 files changed, 39 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/service/arduinoNode/arduinoNode.py	Tue Feb 02 01:52:29 2016 -0800
+++ b/service/arduinoNode/arduinoNode.py	Tue Feb 02 22:37:11 2016 -0800
@@ -85,6 +85,7 @@
         self._polledDevs = [d for d in self._devs if d.generatePollCode()]
         
         self._statementsFromInputs = {} # input device uri: latest statements
+        self._lastPollTime = {} # input device uri: time()
         self._carbon = CarbonClient(serverHost='bang')
         self.open()
         for d in self._devs:
@@ -122,12 +123,23 @@
             
     def _pollWork(self):
         t1 = time.time()
-        self.ser.write("\x60\x00")
+        self.ser.write("\x60\x00") # "poll everything"
         for i in self._polledDevs:
+            now = time.time()
+            new = i.readFromPoll(self.ser.read)
             prev = self._statementsFromInputs.get(i.uri, [])
-            new = self._statementsFromInputs[i.uri] = inContext(
-                i.readFromPoll(self.ser.read), i.uri)
-            self.masterGraph.patch(Patch.fromDiff(prev, new))
+            if new or prev:
+                self._statementsFromInputs[i.uri] = new
+                # it's important that quads from different devices
+                # don't clash, since that can lead to inconsistent
+                # patches (e.g.
+                #   dev1 changes value from 1 to 2;
+                #   dev2 changes value from 2 to 3;
+                #   dev1 changes from 2 to 4 but this patch will
+                #     fail since the '2' statement is gone)
+                self.masterGraph.patch(Patch.fromDiff(inContext(prev, i.uri),
+                                                      inContext(new, i.uri)))
+            self._lastPollTime[i.uri] = now
             
         #plus statements about succeeding or erroring on the last poll
         byte = self.ser.read(1)
--- a/service/piNode/devices.py	Tue Feb 02 01:52:29 2016 -0800
+++ b/service/piNode/devices.py	Tue Feb 02 22:37:11 2016 -0800
@@ -1,7 +1,7 @@
 from __future__ import division
 
 import time, logging, os
-from rdflib import Namespace, RDF, URIRef, Literal
+from rdflib import Namespace, URIRef, Literal
 
 try:
     import pigpio
@@ -329,6 +329,7 @@
 @register
 class OnboardTemperature(DeviceType):
     deviceType = ROOM['OnboardTemperature']
+    pollPeriod = 10
     @classmethod
     def findInstances(cls, graph, board, pi):
         for row in graph.query('''SELECT DISTINCT ?uri WHERE {
--- a/service/piNode/piNode.py	Tue Feb 02 01:52:29 2016 -0800
+++ b/service/piNode/piNode.py	Tue Feb 02 22:37:11 2016 -0800
@@ -57,18 +57,34 @@
         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._lastPollTime = {} # input device uri: time()
         self._carbon = CarbonClient(serverHost='bang')
         for d in self._devs:
             self.syncMasterGraphToHostStatements(d)
+            
     def startPolling(self):
-        task.LoopingCall(self._poll).start(.5)
+        task.LoopingCall(self._poll).start(.05)
 
     def _poll(self):
         for i in self._devs:
-            prev = inContext(self._statementsFromInputs.get(i.uri, []), CTX)
-            new = self._statementsFromInputs[i.uri] = i.poll()
-            new = inContext(new, CTX)
-            self.masterGraph.patch(Patch.fromDiff(prev, new))
+            now = time.time()
+            if (hasattr(i, 'pollPeriod') and
+                self._lastPollTime.get(i.uri, 0) + i.pollPeriod > now):
+                continue
+            new = i.poll()
+            prev = self._statementsFromInputs.get(i.uri, [])
+            if new or prev:
+                self._statementsFromInputs[i.uri] = new
+                # it's important that quads from different devices
+                # don't clash, since that can lead to inconsistent
+                # patches (e.g.
+                #   dev1 changes value from 1 to 2;
+                #   dev2 changes value from 2 to 3;
+                #   dev1 changes from 2 to 4 but this patch will
+                #     fail since the '2' statement is gone)
+                self.masterGraph.patch(Patch.fromDiff(inContext(prev, i.uri),
+                                                      inContext(new, i.uri)))
+            self._lastPollTime[i.uri] = now
         self._exportToGraphite()
 
     def _exportToGraphite(self):