def _merge(self, lastRequests): deviceAttrs = {} # device: {deviceAttr: value} for _, lastSettings in lastRequests: for (device, deviceAttr), value in lastSettings.iteritems(): if (device, deviceAttr) in self.remapOut: start, end = self.remapOut[(device, deviceAttr)] value = Literal(start + float(value) * (end - start)) attrs = deviceAttrs.setdefault(device, {}) 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'], L9['focus']]: 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 return deviceAttrs
def resolvedSettingsDict(self, settingsList): out = {} for d, da, v in settingsList: if (d, da) in out: out[(d, da)] = resolve(d, da, [out[(d, da)], v]) else: out[(d, da)] = v return out
def resolvedSettingsDict(self, settingsList): # type: (List[Tuple[URIRef, URIRef, float]]) -> Dict[Tuple[URIRef, URIRef], float] out = {} # type: Dict[Tuple[URIRef, URIRef], float] for d, da, v in settingsList: if (d, da) in out: out[(d, da)] = resolve(d, da, [out[(d, da)], v]) else: out[(d, da)] = v return out
def fromList(cls, graph, others): """note that others may have multiple values for an attr""" out = cls(graph, []) for s in others: if not isinstance(s, cls): raise TypeError(s) for row in s.asList(): # could work straight from s._compiled if row[0] is None: raise TypeError('bad row %r' % (row,)) dev, devAttr, value = row devDict = out._compiled.setdefault(dev, {}) if devAttr in devDict: value = resolve(dev, devAttr, [devDict[devAttr], value]) devDict[devAttr] = value out._delZeros() return out
def setAttrs(self, client, clientSession, settings, sendTime): """ settings is a list of (device, attr, value). These attrs are device attrs. We resolve conflicting values, process them into output attrs, and call Output.update/Output.flush to send the new outputs. Call with settings=[] to ping us that your session isn't dead. """ now = time.time() requestLag = now - sendTime if requestLag > .1: log.warn('collector.setAttrs from %s is running %.1fms after the request was made', client, requestLag * 1000) self._forgetStaleClients(now) uniqueSettings = self.resolvedSettingsDict(settings) self.lastRequest[client] = (clientSession, now, uniqueSettings) deviceAttrs = {} # device: {deviceAttr: value} for _, _, lastSettings in self.lastRequest.itervalues(): for (device, deviceAttr), value in lastSettings.iteritems(): if (device, deviceAttr) in self.remapOut: start, end = self.remapOut[(device, deviceAttr)] value = Literal(start + float(value) * (end - start)) attrs = deviceAttrs.setdefault(device, {}) 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'], L9['focus']]: 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: devType = self.deviceType[d] except KeyError: log.warn("request for output to unconfigured device %s" % d) continue outputAttrs[d] = toOutputAttrs(devType, deviceAttrs[d]) pendingOut = {} # output : values for out in self.outputs: pendingOut[out] = [0] * out.numChannels for device, attrs in outputAttrs.iteritems(): for outputAttr, value in attrs.iteritems(): self.setAttr(device, outputAttr, value, pendingOut) dt1 = 1000 * (time.time() - now) self.flush(pendingOut) dt2 = 1000 * (time.time() - now) if dt1 > 10: print "slow setAttrs: %.1fms -> flush -> %.1fms. lr %s da %s oa %s" % ( dt1, dt2, len(self.lastRequest), len(deviceAttrs), len(outputAttrs) )
def testMaxes3Colors(self): self.assertEqual('#112233', resolve(None, L9['color'], ['#110000', '#002200', '#000033']))
def testMaxes2Colors(self): self.assertEqual('#ff0400', resolve(None, L9['color'], ['#ff0300', '#000400']))
def testMaxes1Color(self): # do not delete - this one catches a bug in the rgb_to_hex(...) lines self.assertEqual('#ff0300', resolve(None, L9['color'], ['#ff0300']))