diff options
35 files changed, 282 insertions, 75 deletions
@@ -1,2 +1,4 @@ *.pyc *.swp +*.swo +*.pyo diff --git a/LightInstallation.py b/LightInstallation.py index e6e5a26..5882806 100644 --- a/LightInstallation.py +++ b/LightInstallation.py @@ -1,15 +1,18 @@ from xml.etree.ElementTree import ElementTree from pixelcore.Screen import * from pixelcore.PixelStrip import * -import pdb, sys, time, Util, thread +import pdb, sys, time, thread from pygame.locals import * import util.TimeOps as clock import util.Config as configGetter import util.ComponentRegistry as compReg +from logger import main_log #Python class to instantiate and drive a Screen through different patterns, #and effects. class LightInstallation: def __init__(self, configFileName): + main_log.critical("hi russell, i'm sending info to the log files") + main_log.critical("initializing based on file: " + str(configFileName)) self.timer = clock.Stopwatch() self.timer.start() self.inputs = {} #dict of inputs and their bound behaviors, keyed by InputId @@ -20,11 +23,8 @@ class LightInstallation: self.componentDict = {} self.inputBehaviorRegistry = {} #inputid -> behaviors listening to that #input - #give Util a pointer to our componentRegistry and screen so that everyone can use - #it - #Util.setComponentDict(self.componentDict) self.screen = Screen() - #Util.setScreen(self.screen) + compReg.initRegistry() compReg.registerComponent(self.screen, 'Screen') #TODO: move to constants file config = configGetter.loadConfigFile(configFileName) #read configs from xml @@ -33,25 +33,33 @@ class LightInstallation: inputConfig = config.find('InputConfiguration') behaviorConfig = config.find('BehaviorConfiguration') mapperConfig = config.find('PixelMapperConfiguration') + + installationConfig = config.find('InstallationConfiguration') #inits self.initializeScreen(pixelConfig) self.initializeRenderers(rendererConfig) self.initializeInputs(inputConfig) self.initializeBehaviors(behaviorConfig) self.initializeMapper(mapperConfig) - - self.screen.setMapper(self.mapper) #registration in dict self.registerComponents(self.renderers) self.registerComponents(self.inputs) self.registerComponents(self.behaviors) + self.registerComponents(self.mappers) + self.configureInstallation(installationConfig) #Done initializing. Lets start this thing! self.timer.stop() print 'Initialization done. Time: ', self.timer.elapsed(), 'ms' self.mainLoop() + def configureInstallation(self, installationConfig): + defaults = configGetter.generateArgDict(installationConfig.find('Defaults')) + for defaultSelection in defaults: + componentToMap = compReg.getComponent(defaults[defaultSelection]) + compReg.registerComponent(compReg.getComponent(defaults[defaultSelection]),\ + 'Default'+defaultSelection) + def initializeMapper(self, mapperConfig): - self.mapper = self.initializeComponent(mapperConfig)[0] #TODO: support - #multiple mappers + self.mappers = self.initializeComponent(mapperConfig) def initializeScreen(self, layoutConfig): pixelAssemblers = self.initializeComponent(layoutConfig) [self.addPixelStrip(l) for l in pixelAssemblers] @@ -72,7 +80,6 @@ class LightInstallation: cid = component['Id'] if cid == None: raise Exception('Components must have Ids!') - #self.componentDict[cid] = component compReg.registerComponent(component) def initializeComponent(self, config): components = [] @@ -125,9 +132,6 @@ class LightInstallation: self.behaviors = self.initializeComponent(behaviorConfig) for behavior in self.behaviors: self.addBehavior(behavior) - #TODO: we probably don't need this anymore :( - def topologicalBehaviorSort(self): - return Util.topologicalSort(self.behaviorDependencies) #Does work needed to add a behavior: currently -- maps behavior inputs into #the input behavior registry. def addBehavior(self, behavior): @@ -141,7 +145,8 @@ class LightInstallation: try: [compReg.getComponent(b).addInput(responseDict) for b in boundBehaviorIds] except: - print 'Behaviors not initialized yet. WAIT!' + pass + #print 'Behaviors not initialized yet. WAIT!' def main(argv): print argv if len(argv) == 1: diff --git a/behaviors/AllPixelsLeft.py b/behaviors/AllPixelsLeft.py new file mode 100644 index 0000000..7f731e9 --- /dev/null +++ b/behaviors/AllPixelsLeft.py @@ -0,0 +1,11 @@ +from operationscore.Behavior import * +import util.ComponentRegistry as compReg +import pdb +class AllPixelsLeft(Behavior): + def processResponse(self, sensorInputs, recursiveInputs): + for sensory in sensorInputs: + xLoc = sensory['Location'][0] + if type(xLoc) == type(tuple()): + pdb.set_trace() + sensory['Location'] = '[{x}<' + str(xLoc) + ']' + return (sensorInputs, recursiveInputs) diff --git a/behaviors/BehaviorChain.py b/behaviors/BehaviorChain.py index 65f5c9d..98585c9 100644 --- a/behaviors/BehaviorChain.py +++ b/behaviors/BehaviorChain.py @@ -1,6 +1,5 @@ from operationscore.Behavior import * import util.ComponentRegistry as compReg -import Util import pdb class BehaviorChain(Behavior): def behaviorInit(self): diff --git a/behaviors/DebugBehavior.py b/behaviors/DebugBehavior.py index 4c8550a..a00346b 100644 --- a/behaviors/DebugBehavior.py +++ b/behaviors/DebugBehavior.py @@ -1,5 +1,4 @@ from operationscore.Behavior import * -import Util import pdb class DebugBehavior(Behavior): def processResponse(self, sensorInputs, recursiveInputs): diff --git a/behaviors/DecayBehavior.py b/behaviors/DecayBehavior.py index 56e1686..c1f6f92 100644 --- a/behaviors/DecayBehavior.py +++ b/behaviors/DecayBehavior.py @@ -1,7 +1,6 @@ from operationscore.Behavior import * from pixelevents.DecayEvent import * import util.Strings as Strings -import Util import pdb class DecayBehavior(Behavior): def processResponse(self, sensorInputs, recursiveInputs): diff --git a/behaviors/EchoBehavior.py b/behaviors/EchoBehavior.py index 002f8fb..be0ed14 100644 --- a/behaviors/EchoBehavior.py +++ b/behaviors/EchoBehavior.py @@ -1,6 +1,5 @@ from operationscore.Behavior import * import util.Strings as Strings -import Util import pdb class EchoBehavior(Behavior): def processResponse(self, sensorInputs, recursiveInputs): diff --git a/behaviors/ModifyParam.py b/behaviors/ModifyParam.py index 38b8cd5..3701013 100644 --- a/behaviors/ModifyParam.py +++ b/behaviors/ModifyParam.py @@ -1,5 +1,4 @@ from operationscore.Behavior import * -import Util import pdb #Class to perform a given operation on some element of an argDict. Designed to be used a recursive hook, but can serve sensor-based functions as well. Specify ParamType (Sensor or Recurse), ParamName, and ParamOp, (a valid python statement with the old value represented as {val}) class ModifyParam(Behavior): diff --git a/behaviors/RunningBehavior.py b/behaviors/RunningBehavior.py index 1969162..92db69b 100644 --- a/behaviors/RunningBehavior.py +++ b/behaviors/RunningBehavior.py @@ -2,7 +2,6 @@ from operationscore.Behavior import * import util.ComponentRegistry as compReg import util.Geo as Geo import pdb -import Util class RunningBehavior(Behavior): def processResponse(self, sensorInputs, recursiveInputs): newResponses = sensorInputs diff --git a/config/Outdoor.xml b/config/Outdoor.xml index 10274b2..1cf00e4 100644 --- a/config/Outdoor.xml +++ b/config/Outdoor.xml @@ -1,5 +1,10 @@ <!---All configuration items contain a "Class" tag specifying the python class they represent, and an "Args" tag specifying the args to be passed in.--> <LightInstallation> + <InstallationConfiguration> + <Defaults> + <PixelMapper>simplemap</PixelMapper> + </Defaults> + </InstallationConfiguration> <PixelConfiguration> <PixelStrip> <Class>layouts.LineLayout</Class> @@ -62,15 +67,13 @@ </Args> </PixelStrip> </PixelConfiguration> - <!--<PixelMapperConfiguration> + <PixelMapperConfiguration> <PixelMapper> <Class>pixelmappers.SimpleMapper</Class> <Args> <Id>simplemap</Id> </Args> </PixelMapper> - </PixelMapperConfiguration>--> - <PixelMapperConfiguration> <PixelMapper> <Class>pixelmappers.GaussianMapper</Class> <Args> @@ -181,6 +184,12 @@ </Args> </Behavior> <Behavior> + <Class>behaviors.AllPixelsLeft</Class> + <Args> + <Id>pixelsleft</Id> + </Args> + </Behavior> + <Behavior> <Class>behaviors.RecursiveDecay</Class> <Args> <Id>recursivedecay</Id> @@ -201,6 +210,7 @@ </ChainedBehaviors> <RecursiveHooks>{'running':'acceleratedie'}</RecursiveHooks> <RenderToScreen>True</RenderToScreen> + <Mapper>gaussmap</Mapper> </Args> </Behavior> <Behavior> @@ -231,6 +241,7 @@ </Inputs> <ChainedBehaviors> <Id>echo</Id> + <Id>pixelsleft</Id> <Id>colorchange</Id> <Id>decay</Id> </ChainedBehaviors> diff --git a/inputs/PygameInput.py b/inputs/PygameInput.py index f69d0f5..6779a20 100644 --- a/inputs/PygameInput.py +++ b/inputs/PygameInput.py @@ -1,4 +1,4 @@ -import time, Util +import time import util.Strings as Strings from operationscore.Input import * import pygame diff --git a/inputs/TCPInput.py b/inputs/TCPInput.py index 9f62825..1517afa 100644 --- a/inputs/TCPInput.py +++ b/inputs/TCPInput.py @@ -1,4 +1,3 @@ -import Util import util.Strings as Strings from operationscore.Input import * import socket, json, time diff --git a/inputs/TCPInput_backup.py b/inputs/TCPInput_backup.py index 01b6a99..d2c4087 100644 --- a/inputs/TCPInput_backup.py +++ b/inputs/TCPInput_backup.py @@ -1,5 +1,4 @@ import SocketServer -import Util from operationscore.Input import * """ diff --git a/inputs/UDPInput.py b/inputs/UDPInput.py index 5b83792..7d5609e 100644 --- a/inputs/UDPInput.py +++ b/inputs/UDPInput.py @@ -1,4 +1,3 @@ -import Util from operationscore.Input import * import socket class UDPInput(Input): diff --git a/logger/Logger.py b/logger/Logger.py new file mode 100644 index 0000000..7115e47 --- /dev/null +++ b/logger/Logger.py @@ -0,0 +1,19 @@ +import logging +import logging.config + +logging.config.fileConfig("logger/loggingConfig.ini") + +# create logger +screen_log = logging.getLogger("root") +main_log = logging.getLogger("smoot_light") +exception_log = logging.getLogger("exception") + +#test code -- won't work unless file is imported by a file from the directory above this "logger" directory +#main_log.debug("debug mesage") +#main_log.info("info message") +#main_log.warn("warn message") +#main_log.error("error message") +#main_log.critical("critical message") +#exception_log.critical("hi") +#screen_log.error("whoa hello") + diff --git a/logger/UTF8LogFormatter.py b/logger/UTF8LogFormatter.py new file mode 100644 index 0000000..2d3fae5 --- /dev/null +++ b/logger/UTF8LogFormatter.py @@ -0,0 +1,8 @@ +from logging import Formatter + +class UTF8LogFormatter(Formatter): + def format(self, record): + try: + return Formatter.format(self, record) + except Exception, e: + return Formatter.format(self, record).encode('utf8') diff --git a/logger/__init__.py b/logger/__init__.py new file mode 100644 index 0000000..ff356f4 --- /dev/null +++ b/logger/__init__.py @@ -0,0 +1 @@ +from Logger import screen_log, main_log, exception_log diff --git a/logger/loggingConfig.ini b/logger/loggingConfig.ini new file mode 100644 index 0000000..ee35749 --- /dev/null +++ b/logger/loggingConfig.ini @@ -0,0 +1,61 @@ +# Logging configuration +# Add additional loggers, handlers, formatters here +# Uses pythons logging config file format +# http://docs.python.org/lib/logging-config-fileformat.html +[loggers] +keys = root, smoot_light, exception + +[handlers] +keys = console, file, exception + +[formatters] +keys = generic, utf8encode + +#################################################################### + +[logger_root] +level = INFO +handlers = console + +[logger_smoot_light] +level = INFO +handlers = file +qualname = smoot_light +propagate = 0 + +[logger_exception] +level = DEBUG +handlers = exception +qualname = exception +propagate = 0 + +#################################################################### + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[handler_file] +class = FileHandler +args = ('/var/log/smoot_light/main.log', 'a') +level = INFO +formatter = generic + +[handler_exception] +class = FileHandler +args = ('/var/log/smoot_light/exception.log', 'a') +level = DEBUG +formatter = utf8encode + +#################################################################### + +[formatter_generic] +format = %(asctime)s %(levelname)-8s [%(name)s] %(message)s +#datefmt = %H:%M:%S + +[formatter_utf8encode] +format = %(asctime)s %(levelname)-8s [%(name)s] %(message)s +class = logger.UTF8LogFormatter.UTF8LogFormatter +#datefmt = %H:%M:%S diff --git a/operationscore/Behavior.py b/operationscore/Behavior.py index 3bdf1ec..d48c1d5 100644 --- a/operationscore/Behavior.py +++ b/operationscore/Behavior.py @@ -33,14 +33,26 @@ class Behavior(SmootCoreObject): recursiveInputs) if type(output) != type([]): output = [output] - return (output, recursions) - except: + return self.addMapperToResponse((output, recursions)) #TODO: use a decorator for this? + except: #deal with behaviors that don't return a tuple. + responses = self.processResponse(sensorInputs, recursiveInputs) return (self.processResponse(sensorInputs, recursiveInputs),[]) def addInputs(self, sensorInputs): if type(sensorInputs) == type([]): [self.addInput(sensorInput) for sensorInput in sensorInputs] else: self.addInput(sensorInputs) + #private + def addMapperToResponse(self, responses): + if self['Mapper'] != None: + if type(responses) == type(tuple): + (out, recurs) = responses + return (self.addMapperToResponse(out), self.addMapperToResponse(recurs)) + if type(responses) == type([]): + for r in responses: + r['Mapper'] = self['Mapper'] + return responses + return responses def timeStep(self): #TODO: type checking. clean this up responses = self.processResponse(self.sensorResponseQueue, \ self.recursiveResponseQueue) @@ -54,8 +66,7 @@ class Behavior(SmootCoreObject): if type(outputs) != type([]): outputs = [outputs] try: - return outputs + return self.addMapperToResponse(outputs) #TODO: WTF is up with this? except: pass - #pdb.set_trace() - return outputs + return self.addMapperToResponse(outputs) diff --git a/operationscore/Input.py b/operationscore/Input.py index 2144678..62c4682 100644 --- a/operationscore/Input.py +++ b/operationscore/Input.py @@ -1,4 +1,4 @@ -import threading,time,Util +import threading,time from operationscore.SmootCoreObject import * #Abstract class for inputs. Inheriting classes should call "respond" to raise #their event. Inheriting classes MUST define sensingLoop. Called at the @@ -22,14 +22,10 @@ class Input(SmootCoreObject): self.daemon = True #This kills this thread when the main thread stops def respond(self, eventDict): #if eventDict != []: - #pdb.set_trace() self.parentScope.lock.acquire() self.parentScope.processResponse(self.argDict, eventDict) self.parentScope.lock.release() time.sleep(.001) - def newEvent(self, event): #Mostly just useful for grabbing events from the - #computer running the sim (key presses, clicks etc.) - self.eventQueue.append(event) def parentAlive(self): try: parentAlive = self.parentScope.alive() diff --git a/operationscore/PixelAssembler.py b/operationscore/PixelAssembler.py index c8563fb..6878f8a 100644 --- a/operationscore/PixelAssembler.py +++ b/operationscore/PixelAssembler.py @@ -1,6 +1,5 @@ from operationscore.SmootCoreObject import * import util.Geo as Geo -import Util import pdb class PixelAssembler(SmootCoreObject): def init(self): diff --git a/operationscore/PixelMapper.py b/operationscore/PixelMapper.py index bbbfcf4..e3f2515 100644 --- a/operationscore/PixelMapper.py +++ b/operationscore/PixelMapper.py @@ -1,5 +1,4 @@ from operationscore.SmootCoreObject import * -import Util import pdb class PixelMapper(SmootCoreObject): def init(self): diff --git a/operationscore/SmootCoreObject.py b/operationscore/SmootCoreObject.py index 10df299..9784aab 100644 --- a/operationscore/SmootCoreObject.py +++ b/operationscore/SmootCoreObject.py @@ -1,4 +1,3 @@ -import Util import pdb import threading import thread @@ -8,6 +7,7 @@ class SmootCoreObject(threading.Thread): self.argDict = argDict self.validateArgs(self.className()+'.params') self.lock = thread.allocate_lock() + threading.Thread.__init__(self) self.init() #call init of inheriting class # self.__setitem__ = self.argDict.__setitem__ # self.__getitem__ = self.argDict.__getitem__ diff --git a/pixelcore/PixelStrip.py b/pixelcore/PixelStrip.py index cfab948..fceff8e 100644 --- a/pixelcore/PixelStrip.py +++ b/pixelcore/PixelStrip.py @@ -4,7 +4,6 @@ import util.Geo as Geo from pixelevents.StepEvent import * import pygame import math -import Util import pdb #Python class representing a single Pixel strip (usually 50 Pixels) class PixelStrip: diff --git a/pixelcore/Screen.py b/pixelcore/Screen.py index a20cc72..da03ad2 100644 --- a/pixelcore/Screen.py +++ b/pixelcore/Screen.py @@ -1,7 +1,10 @@ from pixelcore.Pixel import * from pixelcore.PixelStrip import * from operationscore.PixelEvent import * +from operationscore.PixelMapper import * import util.Search as Search +import util.ComponentRegistry as compReg +import util.Strings as Strings import itertools #Class representing a collection of Pixels grouped into PixelStrips. Needs a #PixelMapper, currently set via setMapper by may be migrated into the argDict. @@ -29,8 +32,6 @@ class Screen: self.xPixelLocs = [p[0] for p in self.xSortedPixels] def render(self, surface): [lS.render(surface) for lS in self.pixelStrips] - def setMapper(self, mapper): - self.mapper = mapper def allOn(self): [lS.allOn(-1) for lS in self.pixelStrips] def __iter__(self): #the iterator of all our pixel strips chained togther @@ -70,8 +71,13 @@ class Screen: #[strip.respond(dict(responseInfo)) for strip in self.pixelStrips] if type(responseInfo) != type(dict()): pass - #pdb.set_trace() - pixelWeightList = self.mapper.mapEvent(responseInfo['Location'], self) + if 'Mapper' in responseInfo: + mapper = compReg.getComponent(responseInfo['Mapper']) + else: + mapper = compReg.getComponent(Strings.DEFAULT_MAPPER) + #if type(mapper) != type(PixelMapper): + # raise Exception('No default mapper specified.') + pixelWeightList = mapper.mapEvent(responseInfo['Location'], self) PixelEvent.addPixelEventIfMissing(responseInfo) for (pixel, weight) in pixelWeightList: pixel.processInput(responseInfo['PixelEvent'].scale(weight), 0) #TODO: z-index diff --git a/pixelmappers/GaussianMapper.py b/pixelmappers/GaussianMapper.py index e94235e..8755acf 100644 --- a/pixelmappers/GaussianMapper.py +++ b/pixelmappers/GaussianMapper.py @@ -1,6 +1,5 @@ from operationscore.PixelMapper import * import util.Geo as Geo -import Util class GaussianMapper(PixelMapper): def mappingFunction(self, eventLocation, screen): returnPixels = [] #TODO: consider preallocation and trimming diff --git a/pixelmappers/SimpleMapper.py b/pixelmappers/SimpleMapper.py index 4b5377d..bc51cf9 100644 --- a/pixelmappers/SimpleMapper.py +++ b/pixelmappers/SimpleMapper.py @@ -1,14 +1,29 @@ from operationscore.PixelMapper import * -import Util +import util.Geo as Geo class SimpleMapper(PixelMapper): def mappingFunction(self, eventLocation, screen): - bestDist = 10**10 #don't kill me, I'm lazy - bestPixel = None - for pixel in screen: - pixelDist = Geo.dist(pixel.location, eventLocation) - if pixelDist < bestDist: - bestPixel = pixel - bestDist = pixelDist - return [(bestPixel,1)] - + if type(eventLocation) == type(tuple()): + bestDist = 10**10 #don't kill me, I'm lazy + bestPixel = None + for pixel in screen: + pixelDist = Geo.dist(pixel.location, eventLocation) + if pixelDist < bestDist: + bestPixel = pixel + bestDist = pixelDist + return [(bestPixel,1)] + elif type(type(str)): + #[{x}>5,{y}<k] + #TODO: we should probably encapsulate this somewhere + ret = [] + eventLocation = eventLocation.replace('{x}', 'pixel.location[0]') + eventLocation = eventLocation.replace('{y}', 'pixel.location[1]') + for pixel in screen: + try: + pixelValid = sum(eval(eventLocation)) == len(eval(eventLocation)) #TODO: some + #optimizations possible. This might be slow in the long run + if pixelValid: + ret.append((pixel, 1)) + except: + raise Exception('Bad event condition') + return ret diff --git a/renderers/IndoorRenderer.py b/renderers/IndoorRenderer.py index 2eac162..c13d11f 100644 --- a/renderers/IndoorRenderer.py +++ b/renderers/IndoorRenderer.py @@ -20,12 +20,15 @@ class IndoorRenderer(Renderer): self.stripLocations[stripId] = (ip, \ stripsInPowerSupply[stripId]) def render(self, lightSystem): - for pixelStrip in lightSystem.pixelStrips: - stripId = pixelStrip.argDict['Id'] - (ip, port) = self.stripLocations[stripId] - if not ip in self.sockets: #do we have a socket to this - #strip? if not, spin off a new one - self.sockets[ip] = network.getConnectedSocket(ip,port) - packet = composer.composePixelStripPacket(pixelStrip, port) - self.sockets[ip].send(packet, 0x00) + try: + for pixelStrip in lightSystem.pixelStrips: + stripId = pixelStrip.argDict['Id'] + (ip, port) = self.stripLocations[stripId] + if not ip in self.sockets: #do we have a socket to this + #strip? if not, spin off a new one + self.sockets[ip] = network.getConnectedSocket(ip,port) + packet = composer.composePixelStripPacket(pixelStrip, port) + self.sockets[ip].send(packet, 0x00) + except: + pass #Rendering error. Log it. LOG diff --git a/tests/TestConfigLoaders.py b/tests/TestConfigLoaders.py new file mode 100644 index 0000000..6ea4f59 --- /dev/null +++ b/tests/TestConfigLoaders.py @@ -0,0 +1,10 @@ +import unittest +class TestConfigLoaders(unittest.TestCase): + def setUp(self): + pass + def tearDown(self): + pass + def test_something(self): + pass +if __name__ == '__main__': + unittest.main() diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/__init__.py diff --git a/util/ComponentRegistry.py b/util/ComponentRegistry.py index f8fe00d..119ce18 100644 --- a/util/ComponentRegistry.py +++ b/util/ComponentRegistry.py @@ -1,17 +1,43 @@ import pdb +#component registry, a singleton +import thread +#class ComponentRegistry: +# def __init__(self): +# self.regDict = {} +# @staticmethod +# def getRegistry(self): +# if self.instance == None: +# self.instance = self.__class__() +# return self.instance +# def registerComponent(component, cid=None): +# if cid != None: +# globals()['Registry'][cid] = component +# else: +# try: +# cid = component['Id'] +# globals()['Registry'][cid] = component +# except: +# raise Exception('Must specify Id, component did not store it') +#def registerDefault( +def removeComponent(cid): + globals()['Registry'].pop(cid) +def getComponent(cid): + return globals()['Registry'][cid] #Registry of all components of the light system #TODO: pick a graceful failure behavior and implement it -registry = {} +def initRegistry(): + globals()['Registry'] = {} def registerComponent(component, cid=None): if cid != None: - registry[cid] = component + globals()['Registry'][cid] = component else: try: cid = component['Id'] - registry[cid] = component + globals()['Registry'][cid] = component except: raise Exception('Must specify Id, component did not store it') +#def registerDefault( def removeComponent(cid): - registry.pop(cid) + globals()['Registry'].pop(cid) def getComponent(cid): - return registry[cid] + return globals()['Registry'][cid] diff --git a/util/Config.py b/util/Config.py index 746350d..0349e3e 100644 --- a/util/Config.py +++ b/util/Config.py @@ -1,4 +1,5 @@ from xml.etree.ElementTree import ElementTree +import util.Strings as Strings classArgsMem = {} CONFIG_PATH = 'config/' def loadParamRequirementDict(className): @@ -6,7 +7,7 @@ def loadParamRequirementDict(className): classArgsMem[className] = fileToDict(CONFIG_PATH + className) return classArgsMem[className] def loadConfigFile(fileName): #TODO: error handling etc. - try: + #try: fileName = CONFIG_PATH + fileName if '.params' in fileName: return fileToDict(fileName) @@ -14,8 +15,37 @@ def loadConfigFile(fileName): #TODO: error handling etc. config = ElementTree() #use .fromstring, and resolve xincludes config.parse(fileName) return config - except: + #except: return None +def compositeXMLTrees(parentTree, overridingTree): + #type checking -- convert ElementTrees to their root elements + parentItems = parentTree.getchildren() + overrideItems = overridingTree.getchildren() + #first, lets figure out what tags we have in the override tree: + tagCollection = [el.tag for el in overrideItems] #we can speed this up with a dict if necessary + overrideRoot = overridingTree.getroot() + for item in parentItems: + if not item.tag in tagCollection: #no override + overrideRoot.insert(-1, item) #insert the new item at the end + else: + #do we merge or replace? + intersectingElements = findElementsByTag(item.tag, overrideItems) + if len(intersectingItems) > 1: + print 'ABUSE!' + interEl = intersectingElements[0] + mode = 'Replace' + if Strings.OVERRIDE_BEHAVIOR in interEl.attrib: + mode = interEl.attrib[Strings.OVERRIDE_BEHAVIOR] + if mode != 'Replace' and mode != 'Merge': + print 'Bad Mode. Replacing' + mode = 'Replace' + if mode == 'Replace': + pass #we don't need to do anything + if mode == 'Merge': + pass #TODO: code this + +def findElementsByTag(tag, eList): + return [el for el in eList if el.tag == tag] def fileToDict(fileName): fileText = '' try: diff --git a/util/NetworkOps.py b/util/NetworkOps.py index a247090..0404975 100644 --- a/util/NetworkOps.py +++ b/util/NetworkOps.py @@ -1,6 +1,8 @@ import socket def getConnectedSocket(ip,port): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - print (ip, port) - sock.connect((ip, port)) + try: + sock.connect((ip, port)) + except: + print 'network down' return sock diff --git a/util/PacketComposition.py b/util/PacketComposition.py index 5133459..2563c61 100644 --- a/util/PacketComposition.py +++ b/util/PacketComposition.py @@ -26,7 +26,6 @@ def composePixelStripPacket(pixelStrip,port): subDict = dict(kinetDict) subDict['len'] = 38000 #I have no idea why this works. subDict['port'] = port - #pdb.set_trace() packet.extend(kinetPortOutPacket(subDict)) packet.append(0x0) packet.extend(data) @@ -50,7 +49,6 @@ def kinetPortOutPayload(argDict): #payload.append(0x00) #somepadding? lolwtf. payload.extend(struct.pack('H', argDict['len'])) payload.extend(struct.pack('H', argDict['startcode'])) - #pdb.set_trace() return payload def kinetPortOutPacket(payloadArgs): packet = bytearray() diff --git a/util/Strings.py b/util/Strings.py index d58202d..40ad86b 100644 --- a/util/Strings.py +++ b/util/Strings.py @@ -1,2 +1,7 @@ LOCATION = 'Location' +DEFAULT_MAPPER = 'DefaultPixelMapper' + + + +#XMLStuff OVERRIDE_BEHAVIOR = 'OverrideBehavior' |