changeset 259:54fad386d6f5

add support for rgb leds on rpi Ignore-this: cf43ab04f853069450e0f9d42786ea64
author drewp@bigasterisk.com
date Mon, 21 Mar 2016 04:24:31 -0700
parents 0c4ec87d4498
children 88a9f78a7fa2
files service/piNode/devices.py service/reasoning/actions.py
diffstat 2 files changed, 56 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/service/piNode/devices.py	Mon Mar 21 04:23:59 2016 -0700
+++ b/service/piNode/devices.py	Mon Mar 21 04:24:31 2016 -0700
@@ -8,7 +8,11 @@
 except ImportError:
     pigpio = None
 import w1thermsensor
-    
+try:
+    import NeoPixel
+except ImportError:
+    NeoPixel = None
+
 import sys
 
 log = logging.getLogger()
@@ -375,10 +379,12 @@
     pollPeriod = 10
     @classmethod
     def findInstances(cls, graph, board, pi):
+        log.debug('graph has any connected devices of type OnboardTemperature on %r?', board)
         for row in graph.query('''SELECT DISTINCT ?uri WHERE {
           ?board :onboardDevice ?uri . 
           ?uri a :OnboardTemperature .
         }''', initBindings=dict(board=board)):
+            log.debug('  found %s', row.uri)
             yield cls(graph, row.uri, pi, pinNumber=None)
     
     def poll(self):
@@ -394,6 +400,53 @@
         # about eliminating it.
         return [(self.uri, ROOM['temperatureF']),
                 ]
+
+@register
+class RgbPixels(DeviceType):
+    """chain of ws2812 rgb pixels on pin GPIO18"""
+    deviceType = ROOM['RgbPixels']
+
+    def hostStateInit(self):
+        px = self.graph.value(self.uri, ROOM['pixels'])
+        self.pixelUris = list(self.graph.items(px))
+        self.values = dict((uri, Literal('#000000')) for uri in self.pixelUris)
+        self.replace = {'ledArray': 'leds_%s' % self.pinNumber,
+                        'ledCount': len(self.pixelUris),
+                        'pin': self.pinNumber,
+                        'ledType': 'WS2812',
+        }
+        self.neo = NeoPixel.NeoPixel(len(self.values))
+        self.neo.begin()
+    
+    def _rgbFromHex(self, h):
+        rrggbb = h.lstrip('#')
+        return [int(x, 16) for x in [rrggbb[0:2], rrggbb[2:4], rrggbb[4:6]]]
+    
+    def sendOutput(self, statements):
+        px, pred, color = statements[0]
+        if pred != ROOM['color']:
+            raise ValueError(pred)
+        rgb = self._rgbFromHex(color)
+        if px not in self.values:
+            raise ValueError(px)
+        self.values[px] = Literal(color)
+        self.neo.setPixelColor(self.pixelUris.index(px), rgb[0], rgb[1], rgb[2])
+        self.neo.show()
+
+    def hostStatements(self):
+        return [(uri, ROOM['color'], hexCol)
+                for uri, hexCol in self.values.items()]
+        
+    def outputPatterns(self):
+        return [(px, ROOM['color'], None) for px in self.pixelUris]
+
+    def outputWidgets(self):
+        return [{
+            'element': 'output-rgb',
+            'subj': px,
+            'pred': ROOM['color'],
+        } for px in self.pixelUris]
+
         
 def makeDevices(graph, board, pi):
     out = []
--- a/service/reasoning/actions.py	Mon Mar 21 04:23:59 2016 -0700
+++ b/service/reasoning/actions.py	Mon Mar 21 04:24:31 2016 -0700
@@ -51,6 +51,7 @@
             if len(inferredObjects) == 0:
                 self._putZero(deviceGraph, dev, pred, url)
             elif len(inferredObjects) == 1:
+                log.debug('inferredObject: %r', inferredObjects[0])
                 self._putInferred(deviceGraph, url, inferredObjects[0])
             elif len(inferredObjects) > 1:
                 log.info("conflict, ignoring: %s has %s of %s" %
@@ -116,8 +117,7 @@
                 if vol == ROOM['volumeStepUp']:
                     self.post(rootSkippingAuth + "volumeAdjust?amount=6&max=70")
                 if vol == ROOM['volumeStepDown']:
-                    self.post(rootSkippingAuth + "volumeAdjust?amount=-6&min=10")
-            
+                    self.post(rootSkippingAuth + "volumeAdjust?amount=-6&min=10")            
 
     def _frontDoorPuts(self, deviceGraph, inferred):
         # todo: shouldn't have to be a special case