Package SmootLight :: Module LightInstallation
[hide private]
[frames] | no frames]

Source Code for Module SmootLight.LightInstallation

  1  #!/usr/bin/python 
  2   
  3  from xml.etree.ElementTree import ElementTree 
  4  from pixelcore.Screen import *  
  5  from pixelcore.PixelStrip import * 
  6  import pdb, sys, time, thread 
  7  import util.TimeOps as clock 
  8  import util.Config as configGetter  
  9  import util.ComponentRegistry as compReg 
 10  import util.BehaviorQuerySystem as bqs 
 11  from logger import main_log 
 12  #Python class to instantiate and drive a Screen through different patterns, 
 13  #and effects. 
14 -class LightInstallation(object):
15 - def __init__(self, configFileName):
16 main_log.info("System Initialization began based on: " + str(configFileName)) 17 self.timer = clock.Stopwatch() 18 self.timer.start() 19 self.inputs = {} #dict of inputs and their bound behaviors, keyed by InputId 20 self.behaviors = {} 21 self.lock = thread.allocate_lock() 22 self.behaviorOutputs = {} #key: [list of output destinations] 23 self.behaviorInputs = {} 24 self.componentDict = {} 25 self.inputBehaviorRegistry = {} #inputid -> behaviors listening to that 26 self.dieNow = False 27 #input 28 self.screen = Screen() 29 compReg.initRegistry() 30 compReg.registerComponent(self.screen, 'Screen') #TODO: move to constants file 31 32 bqs.initBQS() #initialize the behavior query system 33 #read configs from xml 34 config = configGetter.loadConfigFile(configFileName) 35 36 rendererConfig = config.find('RendererConfiguration') 37 self.initializeRenderers(rendererConfig) 38 39 pixelConfig = config.find('PixelConfiguration') 40 self.initializeScreen(pixelConfig) 41 42 inputConfig = config.find('InputConfiguration') 43 self.initializeInputs(inputConfig) 44 45 behaviorConfig = config.find('BehaviorConfiguration') 46 self.initializeBehaviors(behaviorConfig) 47 48 mapperConfig = config.find('PixelMapperConfiguration') 49 self.initializeMapper(mapperConfig) 50 51 #inits 52 main_log.info('All components initialized') 53 # 54 self.registerAllComponents() 55 56 installationConfig = config.find('InstallationConfiguration') 57 self.configureInstallation(installationConfig) 58 #Done initializing. Lets start this thing! 59 self.timer.stop() 60 #main_log.info('Initialization done. Time: ', self.timer.elapsed(), 'ms') 61 self.mainLoop()
62
63 - def registerAllComponents(self):
64 #registration in dict 65 self.registerComponents(self.renderers) 66 self.registerComponents(self.inputs) 67 self.registerComponents(self.behaviors) 68 self.registerComponents(self.mappers)
69 70
71 - def configureInstallation(self, installationConfig):
72 defaults = configGetter.generateArgDict(installationConfig.find('Defaults')) 73 for defaultSelection in defaults: 74 componentToMap = compReg.getComponent(defaults[defaultSelection]) 75 compReg.registerComponent(compReg.getComponent(defaults[defaultSelection]),\ 76 'Default'+defaultSelection) 77 main_log.debug('Default Set: ' + defaultSelection + 'set to ' +\ 78 defaults[defaultSelection])
79
80 - def initializeMapper(self, mapperConfig):
81 self.mappers = self.initializeComponent(mapperConfig)
82
83 - def initializeScreen(self, layoutConfig):
84 pixelAssemblers = self.initializeComponent(layoutConfig) 85 [self.addPixelStrip(l) for l in pixelAssemblers]
86
87 - def addPixelStrip(self, layoutEngine):
88 pixelStrip = PixelStrip(layoutEngine) 89 self.screen.addStrip(pixelStrip)
90
91 - def initializeInputs(self, inputConfig):
92 inputs = self.initializeComponent(inputConfig) 93 self.inputs = inputs 94 for inputClass in inputs: 95 inputClass.start() 96 self.inputBehaviorRegistry[inputClass['Id']] = [] #Bound behaviors will be added to this
97 #list 98
99 - def initializeRenderers(self, rendererConfig):
100 self.renderers = self.initializeComponent(rendererConfig)
101
102 - def registerComponents(self, components):
103 for component in components: 104 cid = compReg.registerComponent(component) 105 main_log.info(cid + ' registered')
106 - def initializeComponent(self, config):
107 components = [] 108 if config != None: 109 for configItem in config.getchildren(): 110 try: 111 [module,className] = configItem.find('Class').text.split('.') 112 except: 113 main_log.error('Module must have Class element') 114 continue 115 try: 116 exec('from ' + module+'.'+className + ' import *') 117 main_log.debug(module +'.' +className + 'imported') 118 except Exception as inst: 119 main_log.error('Error importing ' + module+'.'+className+ '. Component not\ 120 initialized.') 121 main_log.error(str(inst)) 122 continue 123 args = configGetter.pullArgsFromItem(configItem) 124 args['parentScope'] = self 125 try: 126 new_component = eval(className+'(args)') 127 new_component.addDieListener(self) 128 components.append(new_component) 129 main_log.info(className + 'initialized with args ' + str(args)) 130 except Exception as inst: 131 main_log.error('Failure while initializing ' + className + ' with ' + str(args)) 132 main_log.error(str(inst)) 133 134 return components
135
136 - def alive(self):
137 return True
138
139 - def mainLoop(self):
140 lastLoopTime = clock.time() 141 refreshInterval = 30 142 while not self.dieNow: #dieNow is set if one of its constituents sends a die request. 143 loopStart = clock.time() 144 responses = self.evaluateBehaviors() 145 self.timer.start() 146 [self.screen.respond(response) for response in responses if 147 response != []] 148 self.screen.timeStep(loopStart) 149 [r.render(self.screen, loopStart) for r in self.renderers] 150 loopElapsed = clock.time()-loopStart 151 sleepTime = max(0,refreshInterval-loopElapsed) 152 main_log.debug('Loop complete in ' + str(loopElapsed) + 'ms. Sleeping for ' +\ 153 str(sleepTime)) 154 self.timer.stop() 155 if sleepTime > 0: 156 time.sleep(sleepTime/1000)
157
158 - def evaluateBehaviors(self):
159 """Evaluates all the behaviors (including inter-dependencies) and returns a list of responses to 160 go to the screen""" 161 responses = {} 162 responses['Screen'] = [] #responses to the screen 163 for behavior in self.behaviors: 164 if behavior['RenderToScreen'] == True: 165 responses[behavior['Id']] = behavior.timeStep() 166 responses['Screen'] += responses[behavior['Id']] 167 return responses['Screen']
168
169 - def initializeBehaviors(self, behaviorConfig):
170 self.behaviors = self.initializeComponent(behaviorConfig) 171 for behavior in self.behaviors: 172 self.addBehavior(behavior) 173 bqs.addBehavior(behavior)
174
175 - def addBehavior(self, behavior):
176 """Does work needed to add a behavior: currently -- maps behavior inputs into the input behavior 177 registry""" 178 for inputId in behavior.argDict['Inputs']: 179 if inputId in self.inputBehaviorRegistry: #it could be a behavior 180 self.inputBehaviorRegistry[inputId].append(behavior['Id'])
181
182 - def processResponse(self,inputDict, responseDict):
183 inputId = inputDict['Id'] 184 boundBehaviorIds = self.inputBehaviorRegistry[inputId] 185 try: 186 [compReg.getComponent(b).addInput(responseDict) for b in boundBehaviorIds] 187 except: 188 pass
189 #Behavior run before loading. Not a big deal. 190
191 - def handleDie(self, caller):
192 self.dieNow = True
193
194 -def main(argv):
195 if len(argv) == 1: 196 l = LightInstallation('config/6thFloor.xml') 197 else: 198 l = LightInstallation(argv[1])
199 200 if __name__ == "__main__": 201 try: 202 main(sys.argv) 203 except KeyboardInterrupt: 204 main_log.info('Terminated by keyboard.') 205