def __init__(self, name, callback_function, rgbmatrix, rgbm, queue): LEDMatrixBase.__init__(self, name=name, callback_function=callback_function, rgbmatrix=rgbmatrix) self.rgbm = rgbm self.queue = queue self.bufferdict = { } #dictionary that keeps each clients buffer when the received data becomes segmented self.cmdqueue = QueueList() self.queuethread = None
class LEDMatrixSocketServiceUDP(LEDMatrixBase): def __init__(self, name, callback_function, rgbmatrix, rgbm, queue): LEDMatrixBase.__init__(self, name=name, callback_function=callback_function, rgbmatrix=rgbmatrix) self.rgbm = rgbm self.queue = queue self.bufferdict = { } #dictionary that keeps each clients buffer when the received data becomes segmented self.cmdqueue = QueueList() self.queuethread = None def run( self ): #TODO: wrap most of this in a try with logging and maybe thread shutdown on exceptions self.queuethread = SocketCommandThread(self) #self.queuethread.daemon = True self.queuethread.start() self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #for tcp set option to reuse self.sock.bind(SOCKET_UDP_LISTEN_ADDR) logging.info('SocketServiceUDP listening on ' + str(SOCKET_UDP_LISTEN_ADDR)) self.sock.setblocking(0) while not self.stop_event.is_set(): ready = select.select([self.sock], [], [], 1) if ready[0]: data, addr = self.sock.recvfrom(1024 * 16) self.bufferhandler(data, addr) if self.queuethread != None and self.queuethread.isAlive(): self.queuethread.stop_event.set() LEDMatrixBase.finalize(self) def bufferhandler(self, d, a): '''Handles your socket buffers and shit, yo''' if not a in self.bufferdict.keys(): self.bufferdict[a] = '' buff = self.bufferdict[a] + d l = buff.split(SOCKET_SPLITCHARS) if len(l) == 0: return if l[-1] == '': #complete data for x in l: if x == '': continue self.cmdqueue.append(SocketCommand(x, a)) self.bufferdict[a] = '' #clear buffer just to be sure else: for x in l[:-1]: if x == '': continue self.cmdqueue.append(SocketCommand(x, a)) self.bufferdict[a] = l[-1] #last data added back to buffer
def __init__(self, name, callback_function, rgbmatrix, rgbm, queue): LEDMatrixBase.__init__(self, name=name, callback_function=callback_function, rgbmatrix=rgbmatrix) self.rgbm = rgbm self.queue = queue self.bufferdict = {} #dictionary that keeps each clients buffer when the received data becomes segmented self.cmdqueue = QueueList() self.queuethread = None
class LEDMatrixSocketServiceUDP(LEDMatrixBase): def __init__(self, name, callback_function, rgbmatrix, rgbm, queue): LEDMatrixBase.__init__(self, name=name, callback_function=callback_function, rgbmatrix=rgbmatrix) self.rgbm = rgbm self.queue = queue self.bufferdict = {} #dictionary that keeps each clients buffer when the received data becomes segmented self.cmdqueue = QueueList() self.queuethread = None def run(self): #TODO: wrap most of this in a try with logging and maybe thread shutdown on exceptions self.queuethread = SocketCommandThread(self) #self.queuethread.daemon = True self.queuethread.start() self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #for tcp set option to reuse self.sock.bind(SOCKET_UDP_LISTEN_ADDR) logging.info('SocketServiceUDP listening on ' + str(SOCKET_UDP_LISTEN_ADDR)) self.sock.setblocking(0) while not self.stop_event.is_set(): ready = select.select([self.sock], [], [], 1) if ready[0]: data, addr = self.sock.recvfrom(1024*16) self.bufferhandler(data, addr) if self.queuethread != None and self.queuethread.isAlive(): self.queuethread.stop_event.set() LEDMatrixBase.finalize(self) def bufferhandler(self, d, a): '''Handles your socket buffers and shit, yo''' if not a in self.bufferdict.keys(): self.bufferdict[a] = '' buff = self.bufferdict[a] + d l = buff.split(SOCKET_SPLITCHARS) if len(l) == 0: return if l[-1] == '': #complete data for x in l: if x == '': continue self.cmdqueue.append(SocketCommand(x, a)) self.bufferdict[a] = '' #clear buffer just to be sure else: for x in l[:-1]: if x == '': continue self.cmdqueue.append(SocketCommand(x, a)) self.bufferdict[a] = l[-1] #last data added back to buffer
def __init__(self): logging.info('HomeAutomationCore initialized') self.threadlist = ThreadList() self.sharedqueue = QueueList() self.modules = load_modules_from_tuple(INSTALLED_APPS) self.modules_key_order = [] for key in self.modules.keys(): if self.modules[key].cls.load_priority == 1: self.modules_key_order.insert(0, key) else: self.modules_key_order.append(key) logging.info('Loading modules: ' + ', '.join(self.modules_key_order)) self.load_modules()
def HACore(): """This class puts it all together, creating a state machine and a socket thread that calls state changes for received commands""" logging.info('HomeAutomationCore initialized') threadlist = ThreadList() sharedqueue = QueueList() modules = LoadModulesFromTuple(INSTALLED_APPS) logging.debug('Loading modules:') # create threads and so on for mod in modules: logging.info(mod) mt = None if issubclass(modules[mod].cls, HAWebService): # TODO: too closely coupled mt = modules[mod].cls(name=mod, callback_function=None, queue=sharedqueue, threadlist=threadlist, modules=modules) elif issubclass(modules[mod].cls, HomeAutomationQueueThread): mt = modules[mod].cls(name=mod, callback_function=None, queue=sharedqueue, threadlist=threadlist) elif issubclass(modules[mod].cls, LEDMatrixBase): pass # leave these to be created within LEDMatrixCore else: # assume its the level below (no queue) logging.debug('Instantiating module ' + mod) mt = modules[mod].cls(name=mod, callback_function=None) if mt != None: if issubclass(modules[mod].cls, HAWebService): mt.daemon = True threadlist.append(mt) logging.debug('Starting up module threads') for ti in threadlist: ti.start() # start all threads at this point timecheck = time.time() while 1: # main loop that handles queue and threads, and through executing queue item changes the state of the statemachine try: for remote_module in REMOTE_APPS: remote_addr = remote_module['Address'] remote_apps = remote_module['INSTALLED_APPS'] if not 'socketclient' in remote_module.keys(): remote_module['socketclient'] = LEDMatrixSocketClient(remote_addr) #cache for item in [i for i in sharedqueue if i.cls in remote_apps]: logging.info('Sending queue item to remote host: ' + str(remote_module) ) remote_module['socketclient'].SendSerializedQueueItem(item.__str__()) sharedqueue.remove(item) time.sleep(0.1) if time.time() - timecheck > 10: timecheck = time.time() logging.info('10s mainloop interval, number of threads: %d (%s), queue items: %d' % ( len(threadlist), ', '.join([str(i) for i in threadlist]), len(sharedqueue) ) ) for _thread in threadlist: if not _thread.isAlive(): logging.info('Removing dead thread: ' + _thread.name) threadlist.remove(_thread) # TODO: call other module cleanup (e.g. remove instance ref in webservice globals) # webservice_state_instances # and webservice_class_instances except KeyboardInterrupt: logging.info('Detected ctrl+c, exiting main loop and stopping all threads') break except: logging.critical("Unexpected error in main loop (exiting): " + traceback.format_exc() ) break logging.debug('Stopping all threads') for _thread in threadlist: _thread.stop_event.set() # telling the threads to stop
class HACore(): """ This class puts it all together, creating a state machine and a socket thread that calls state changes for received commands """ def __init__(self): logging.info('HomeAutomationCore initialized') self.threadlist = ThreadList() self.sharedqueue = QueueList() self.modules = load_modules_from_tuple(INSTALLED_APPS) self.modules_key_order = [] for key in self.modules.keys(): if self.modules[key].cls.load_priority == 1: self.modules_key_order.insert(0, key) else: self.modules_key_order.append(key) logging.info('Loading modules: ' + ', '.join(self.modules_key_order)) self.load_modules() def load_modules(self): logging.debug('Thread cleanup before reload') for _thread in self.threadlist: if not _thread.isAlive(): self.threadlist.remove(_thread) # create threads and so on for mod in self.modules_key_order: mod_found = False for ti in self.threadlist: if mod == ti.getName(): mod_found = True break if mod_found: continue # no need to load it again logging.info('Loading module: ' + mod) mt = None if issubclass(self.modules[mod].cls, HAWebService): # TODO: too closely coupled mt = self.modules[mod].cls(name=mod, callback_function=None, queue=self.sharedqueue, threadlist=self.threadlist, modules=self.modules) elif issubclass(self.modules[mod].cls, HomeAutomationQueueThread): mt = self.modules[mod].cls(name=mod, callback_function=None, queue=self.sharedqueue, threadlist=self.threadlist) elif issubclass(self.modules[mod].cls, LEDMatrixBase): pass # leave these to be created within LEDMatrixCore else: # assume its the level below (no queue) logging.debug('Instantiating module ' + mod) mt = self.modules[mod].cls(name=mod, callback_function=None) if mt is not None: if issubclass(self.modules[mod].cls, HAWebService): mt.daemon = True self.threadlist.append(mt) logging.debug('Starting up module threads') for _thread in self.threadlist: if not _thread.isAlive(): _thread.start() # start all threads at this point - unless they are already running (reload) def mainloop(self): timecheck = time.time() while 1: # main loop that handles queue and threads, and through executing queue item changes the state # of the statemachine try: for remote_module in REMOTE_APPS: remote_addr = remote_module['Address'] remote_apps = remote_module['INSTALLED_APPS'] if 'socketclient' not in remote_module.keys(): remote_module['socketclient'] = LEDMatrixSocketClient(remote_addr) # cache for item in [i for i in self.sharedqueue if i.cls in remote_apps]: logging.info('Sending queue item to remote host: ' + str(remote_module) ) remote_module['socketclient'].SendSerializedQueueItem(item.__str__()) self.sharedqueue.remove(item) time.sleep(0.1) if time.time() - timecheck > 10: timecheck = time.time() logging.info('10s mainloop interval, number of threads: %d (%s), queue items: %d' % ( len(self.threadlist), ', '.join([str(i) for i in self.threadlist]), len(self.sharedqueue) ) ) for _thread in self.threadlist: if not _thread.isAlive(): logging.info('Removing dead thread: ' + _thread.name) self.threadlist.remove(_thread) # TODO: call other module cleanup (e.g. remove instance ref in webservice globals) # webservice_state_instances # and webservice_class_instances logging.info('Loading any missing modules..') self.load_modules() # reload modules if required (if one has stopped and been cleaned up) except KeyboardInterrupt: logging.info('Detected ctrl+c, exiting main loop and stopping all threads') break except: logging.critical("Unexpected error in main loop (exiting): " + traceback.format_exc() ) break logging.debug('Stopping all threads') for _thread in self.threadlist: _thread.stop_event.set() # telling the threads to stop
def __init__(self, name, callback_function, queue, threadlist): HomeAutomationThread.__init__(self, name, callback_function) if queue == None: queue = QueueList() self.queue = queue if threadlist == None: threadlist = ThreadList() self.threadlist = threadlist