Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
 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