changeset 1470:b1d8abc96f06

don't run rotations to zero when no one is requesting them. Ignore-this: 48894c486ba3ac9a229a3b34d4b81a0b
author drewp@bigasterisk.com
date Sun, 12 Jun 2016 19:05:45 +0000
parents 70959bb51ab3
children ba24eeb2853a
files light9/collector/collector.py light9/collector/device.py light9/web/live/live.coffee
diffstat 3 files changed, 39 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/light9/collector/collector.py	Sun Jun 12 12:37:24 2016 +0000
+++ b/light9/collector/collector.py	Sun Jun 12 19:05:45 2016 +0000
@@ -38,10 +38,11 @@
         self.clientTimeoutSec = clientTimeoutSec
 
         self.graph.addHandler(self.rebuildOutputMap)
-        self.lastRequest = {} # client : (session, time, {(dev,attr): latestValue})
+        self.lastRequest = {} # client : (session, time, {(dev,devattr): latestValue})
+        self.stickyAttrs = {} # (dev, devattr): value to use instead of 0
 
     def rebuildOutputMap(self):
-        self.outputMap = outputMap(self.graph, self.outputs) # (device, attr) : (output, index)
+        self.outputMap = outputMap(self.graph, self.outputs) # (device, outputattr) : (output, index)
         self.deviceType = {} # uri: type that's a subclass of Device
         self.remapOut = {} # (device, deviceAttr) : (start, end)
         for dc in self.graph.subjects(RDF.type, L9['DeviceClass']):
@@ -64,11 +65,11 @@
 
     def resolvedSettingsDict(self, settingsList):
         out = {}
-        for d, a, v in settingsList:
-            if (d, a) in out:
-                out[(d, a)] = resolve(d, a, [out[(d, a)], v])
+        for d, da, v in settingsList:
+            if (d, da) in out:
+                out[(d, da)] = resolve(d, da, [out[(d, da)], v])
             else:
-                out[(d, a)] = v
+                out[(d, da)] = v
         return out
 
     def setAttrs(self, client, clientSession, settings):
@@ -84,24 +85,10 @@
 
         self._forgetStaleClients(now)
 
-        if 0: # client updates their past requests?
-            row = self.lastRequest.get(client)
-            if row is not None:
-                sess, _, prevClientSettings = row
-                if sess != clientSession:
-                    prevClientSettings = {}
-            else:
-                prevClientSettings = {}
-        else: # client always provides all the nonzero settings it wants
-            prevClientSettings = {}
-            
-        prevClientSettings.update(self.resolvedSettingsDict(settings))
-        self.lastRequest[client] = (clientSession, now, prevClientSettings)
+        uniqueSettings = self.resolvedSettingsDict(settings)
+        self.lastRequest[client] = (clientSession, now, uniqueSettings)
 
-        # inputs that are omitted, implying a zero, should be added
-        # back here if they would remap to something nonzero.
-        
-        deviceAttrs = {} # device: {deviceAttr: value}
+        deviceAttrs = {} # device: {deviceAttr: value}       
         for _, _, lastSettings in self.lastRequest.itervalues():
             for (device, deviceAttr), value in lastSettings.iteritems():
                 if (device, deviceAttr) in self.remapOut:
@@ -112,7 +99,19 @@
                 if deviceAttr in attrs:
                     value = resolve(device, deviceAttr, [attrs[deviceAttr], value])
                 attrs[deviceAttr] = value
+                # list should come from the graph. these are attrs
+                # that should default to holding the last position,
+                # not going to 0.
+                if deviceAttr in [L9['rx'], L9['ry'], L9['zoom']]:
+                    self.stickyAttrs[(device, deviceAttr)] = value
 
+        
+        # e.g. don't let an unspecified rotation go to 0
+        for (d, da), v in self.stickyAttrs.iteritems():
+            daDict = deviceAttrs.setdefault(d, {})
+            if da not in daDict:
+                daDict[da] = v
+                    
         outputAttrs = {} # device: {outputAttr: value}
         for d in deviceAttrs:
             try:
--- a/light9/collector/device.py	Sun Jun 12 12:37:24 2016 +0000
+++ b/light9/collector/device.py	Sun Jun 12 19:05:45 2016 +0000
@@ -50,10 +50,21 @@
     if deviceAttr == L9['color']:
         rgbs = [hex_to_rgb(v) for v in values]
         return rgb_to_hex([max(*component) for component in zip(*rgbs)])
-    # angles should perhaps use average; gobo choice use the most-open one
+    # incomplete. how-to-resolve should be on the DeviceAttr defs in the graph.
+    if deviceAttr in [L9['rx'], L9['ry'], L9['zoom'], L9['focus'], L9['iris']]:
+        floatVals = []
+        for v in values:
+            if isinstance(v, Literal):
+                floatVals.append(float(v.toPython()))
+            elif isinstance(v, (int, float)):
+                floatVals.append(float(v))
+            else:
+                raise TypeError(repr(v))
+            
+        return Literal(sum(floatVals) / len(floatVals))
     
     return max(values)
-    
+
 def toOutputAttrs(deviceType, deviceAttrSettings):
     """
     Given device attr settings like {L9['color']: Literal('#ff0000')},
--- a/light9/web/live/live.coffee	Sun Jun 12 12:37:24 2016 +0000
+++ b/light9/web/live/live.coffee	Sun Jun 12 19:05:45 2016 +0000
@@ -50,6 +50,10 @@
     window.gather = (sent) =>
       [dev, devAttr, value] = sent[0]
       key = dev + " " + devAttr
+      # this is a bug for zoom=0, since collector will default it to
+      # stick at the last setting if we don't explicitly send the
+      # 0. rx/ry similar though not the exact same deal because of
+      # their remap.
       if value == 0 or value == '#000000'
         delete @currentSettings[key]
       else