def init_standalone(self, path="./", config=None): """ Start the component isolated of system """ self.ME_PATH = path # Path of current component self.ME_STANDALONE = True if not Misc.existsFile("config.yaml", self.ME_PATH): raise ValueError(Messages.config_no_file) self.ME_CONFIG_PATH = normpath(self.ME_PATH + "/config.yaml") self.ME_CONFIG = Misc.readConfig( self.ME_CONFIG_PATH) if config == None else config self.CP = CommPool(self.ME_CONFIG, standAlone=True) self.load()
def __init__(self, vars=[]): """ Start the sub system to monitor the health of the entire system Vars: Set any config var using form VAR=VALUE """ print('\n') print('=========================='.center(50, "=")) print(' Wellcome to Home-Monitor '.center(50, "=")) print(' Version: {} '.format(__version__).center(50, " ")) print('=========================='.center(50, "=")) print(' Health Monitor System '.center(50, "=")) print('=========================='.center(50, "=")) print('') self.CONFIG_FILE = normpath(abspath('.') + "/config.yaml") self.CONFIG = Misc.readConfig(self.CONFIG_FILE) # Replacing config vars Misc.replaceConfigVars(self.CONFIG, vars) Misc.showConfig(self.CONFIG) self.commPool = CommPool(self.CONFIG) current_os = platform.system() if current_os == 'Windows': print(' Press esc or x to exit '.center(50, "=")) import msvcrt chk_time = Misc.hasKey(self.CONFIG, 'CHECKING_TIME', 30) while True: if current_os == 'Windows': if msvcrt.kbhit(): keyPressed = ord(msvcrt.getch()) if keyPressed in [27, 120]: break pool_msg = self.commPool.count() for i in range(chk_time): msg = '{} - Refreshing time: {} Seg.'.format( pool_msg, (chk_time - i)) if Misc.toBool(Misc.hasKey(self.CONFIG, 'RUN_IN_COLLAB', 'N')): sys.stdout.write('\r' + msg) else: print(msg, end='\r', flush=True) sleep(1)
def start(self): """ Start load of all device analyzers """ cp = CommPool(self.CONFIG, preferred_url=CommPool.URL_EVENTS) cp.logFromCore(Messages.system_analyzers_connect.format(cp.URL_BASE), LogTypes.INFO, self.__class__.__name__) while True: cp.logFromCore(Messages.analyzer_searching, LogTypes.INFO, self.__class__.__name__) analyzersFolders = Misc.lsFolders("./Analyzers") for cf in analyzersFolders: if Misc.hasKey(self.Analyzers, cf, None) == None: comp = Component(cf, cp) self.Analyzers[cf] = comp for c in self.Analyzers: comp = self.Analyzers[c] comp.load() sleep(self.CHECKING_TIME) cp.logFromCore(Messages.analyzer_stop, LogTypes.INFO, self.__class__.__name__)
class Component(): """ Class to represent any extensible component """ ME_NAME: str = None ME_TYPE: SourceTypes = None ME_PATH: str = None ME_CONFIG = None ME_CONFIG_PATH: str = None ME_FILE_CLASS: str = None ME_CLASS_NAME: str = None ME_ENABLED: bool = False ME_LOADED: bool = False ME_STANDALONE: bool = False CP: CommPool = None BC: Binnacle = Binnacle() Check: str = '' # Hash of config file Thread: Process = None # Thread of compoment executing Running: bool = False # Shows if component is executing Simulating: bool = False # Flag to control if data is simulated from a file SimulatingPath: str = None # Path to simulating file loggingLevel: LogTypes = LogTypes.INFO # Level of logging def __init__(self, path="./", cp: CommPool = None): """ Build a new component un memory """ self.ME_PATH = path self.CP = cp def init_standalone(self, path="./", config=None): """ Start the component isolated of system """ self.ME_PATH = path # Path of current component self.ME_STANDALONE = True if not Misc.existsFile("config.yaml", self.ME_PATH): raise ValueError(Messages.config_no_file) self.ME_CONFIG_PATH = normpath(self.ME_PATH + "/config.yaml") self.ME_CONFIG = Misc.readConfig( self.ME_CONFIG_PATH) if config == None else config self.CP = CommPool(self.ME_CONFIG, standAlone=True) self.load() def load(self, forceLoad: bool = False): """ Loads the component """ self.ME_LOADED = False try: if not Misc.existsFile("config.yaml", self.ME_PATH): raise ValueError(Messages.config_no_file) self.ME_CONFIG_PATH = normpath(self.ME_PATH + "/config.yaml") self.ME_CONFIG = Misc.readConfig(self.ME_CONFIG_PATH) new_check = hashlib.md5(str( self.ME_CONFIG).encode('utf-8')).hexdigest() if new_check == self.Check: return self.Check = new_check self.log(Messages.comp_try_start.format(self.ME_PATH), LogTypes.INFO) self.ME_NAME = Misc.hasKey(self.ME_CONFIG, 'NAME', self.ME_PATH) self.ME_TYPE = SourceTypes.parse( Misc.hasKey(self.ME_CONFIG, 'TYPE', None)) self.ME_ENABLED = Misc.toBool( Misc.hasKey(self.ME_CONFIG, 'ENABLED', 'False')) if self.Thread != None: self.Thread.terminate() self.Thread = None self.log( Messages.comp_change.format( self.ME_PATH, ('reload' if self.ME_ENABLED else 'stoped')), LogTypes.INFO) if not self.ME_ENABLED: return self.ME_FILE_CLASS = Misc.hasKey(self.ME_CONFIG, 'FILE_CLASS', None) if self.ME_FILE_CLASS == None: raise ValueError(Messages.error_file_class) self.ME_CLASS_NAME = Misc.hasKey(self.ME_CONFIG, 'CLASS_NAME', None) if self.ME_CLASS_NAME == None: raise ValueError(Messages.error_class_name) self.Simulating = Misc.toBool( Misc.hasKey(self.ME_CONFIG, 'SIMULATING', 'False')) self.SimulatingPath = Misc.hasKey(self.ME_CONFIG, 'SIMULATING_PATH', '') if self.Simulating: self.setSimulatedMode(self.Simulating, self.SimulatingPath) _cls = Misc.importModule(self.ME_PATH, self.ME_FILE_CLASS, self.ME_CLASS_NAME) obj = _cls() obj.ME_NAME = self.ME_NAME obj.ME_TYPE = self.ME_TYPE obj.ME_PATH = self.ME_PATH obj.ME_CONFIG = self.ME_CONFIG obj.ME_CONFIG_PATH = self.ME_CONFIG_PATH obj.ME_FILE_CLASS = self.ME_FILE_CLASS obj.ME_CLASS_NAME = self.ME_CLASS_NAME obj.ME_ENABLED = self.ME_ENABLED obj.ME_LOADED = True obj.ME_STANDALONE = self.ME_STANDALONE obj.CP = self.CP obj.BC = self.BC obj.Check = self.Check obj.Running = self.Running obj.Simulating = self.Simulating obj.SimulatingPath = self.SimulatingPath obj.loggingLevel = self.loggingLevel DeviceControllerThread = Process(target=obj.start, args=()) DeviceControllerThread.start() self.Thread = DeviceControllerThread del _cls, obj self.ME_LOADED = True self.log(Messages.comp_started.format(self.ME_NAME), LogTypes.INFO) print(self.ME_NAME, 'loaded.') except: self.log(Messages.comp_load_error, LogTypes.ERROR) def checkConnection(self): """ Verify connection with pool """ return self.CP.isLive() def log(self, msg: str, logType: LogTypes, item: str = ''): """ Allows send message to Binnacle """ dataLog = Data() dataLog.source_type = self.ME_TYPE dataLog.source_name = self.ME_NAME dataLog.source_item = item dataLog.data = '{}'.format(msg) dataLog.aux = self.__class__.__name__ if logType.value > LogTypes.WARNING.value: exc_type, exc_obj, exc_tb = sys.exc_info() fname = exc_tb.tb_frame.f_code.co_filename dataLog.data += ' == {} :: {} :: {} :: {}'.format( exc_obj, exc_type, fname, exc_tb.tb_lineno) self.BC.logFromComponent(dataLog, logType) if not self.ME_STANDALONE: self.CP.logFromComponent(dataLog, logType) def setLoggingSettings(self, loggingLevel: LogTypes = LogTypes.INFO, loggingFile=None, loggingFormat=None): """ set logging configurations """ self.loggingLevel = loggingLevel self.BC.loggingSettings(loggingLevel, loggingFile, loggingFormat) def setSimulatedMode(self, simulate: bool, path: str): """ Set if the capturing is simulated """ self.Simulating = simulate self.SimulatingPath = path self.log( Messages.comp_setSimulateMode.format(self.ME_NAME, str(simulate)), LogTypes.INFO) @abc.abstractmethod def start(self): """ Implement me! :: Do anything necessary for start a component. """ raise ValueError( 'Implement me! :: Do anything necessary for start a component.') def stop(self): """ Stop module and getting data """ self.Running = False self.log(Messages.comp_stop.format(self.ME_NAME), LogTypes.WARNING) def send(self, data: Data): """ Send data to pool """ self.CP.send(data) def receive(self, dataFilter: Data, limit: int = -1, lastTime: float = -1): """ Returns a list objects type Data from pool """ if self.Simulating: return self.simulateData(dataFilter, limit, lastTime) else: return self.CP.receive(dataFilter, limit=limit, lastTime=lastTime) @abc.abstractmethod def showData(self, data: Data): """ Implement me! :: To show data if this module start standalone. Call init_standalone before start. """ raise ValueError( 'Implement me! :: To show data if this module start standalone. Call init_standalone before start.' ) @abc.abstractmethod def simulateData(self, dataFilter: Data, limit: int = -1, lastTime: float = -1): """ Implement me! :: Allows to simulate data if this module start standalone. Call init_standalone before start. """ raise ValueError( 'Implement me! :: Allows to simulate data if this module start standalone. Call init_standalone before start.' )
def __init__(self, components: int, vars=[]): """ Start whole system and all sub systems. components is a number between 1 and 15. components represents a binary of 4 positions being: components[0] => DataPool : Example 1 components[1] => Controllers: Example 2 components[2] => Recognizers: Exmaple 4 components[3] => Analyzers : Exmaple 8 To load all sub system set 15 to 'components' parameter. It is possible to combine the starting of some subsystems, for example, to load DataPool and recognizer only set 5 to 'components' parameter. Vars: Set any config var using form VAR=VALUE """ print('\n') print('=========================='.center(50, "=")) print(' Wellcome to Home-Monitor '.center(50, "=")) print(' Version: {} '.format(__version__).center(50, " ")) print('=========================='.center(50, "=")) print('') # Verify components to load param if components < 1 or components > 15: Binnacle().logFromCore(Messages.nothing_to_load, LogTypes.WARNING, self.__class__.__name__) return # Loading configuration file self.CONFIG_FILE = normpath(abspath('.') + "/config.yaml") if not exists(self.CONFIG_FILE): Binnacle().loggingSettings( LogTypes.ERROR, '', '%(asctime)s - %(name)s - %(levelname)s - %(message)s') Binnacle().logFromCore(Messages.config_no_file + self.CONFIG_FILE, LogTypes.ERROR, self.__class__.__name__) return self.CONFIG = Misc.readConfig(self.CONFIG_FILE) # Replacing config vars Misc.replaceConfigVars(self.CONFIG, vars) Misc.showConfig(self.CONFIG) # Logging Configuration tm = gmtime() if Misc.toBool(Misc.hasKey(self.CONFIG, 'LOGGING_TO_FILE', 'False')): loggingFile = '{}.log'.format( str(tm.tm_year) + '%02d' % tm.tm_mon + '%02d' % tm.tm_mday) loggingFile = normpath( Misc.hasKey(self.CONFIG, 'LOGGING_PATH' + "/", "./") + loggingFile) self.CONFIG['LOGGING_FILE'] = loggingFile Binnacle().loggingConf(self.CONFIG) # Define which component should be started toStart = "%04d" % int(str(bin(components)).replace("0b", "")) #print('') Binnacle().logFromCore(Messages.system_start, LogTypes.INFO, self.__class__.__name__) Binnacle().logFromCore(Messages.system_start_components + toStart, LogTypes.INFO, self.__class__.__name__) #print('') self.must_start_pool = toStart[3] == '1' self.must_start_controllers = toStart[2] == '1' self.must_start_recognizers = toStart[1] == '1' self.must_start_analyzers = toStart[0] == '1' self.commPool = CommPool(self.CONFIG) if not self.must_start_pool and components > 1: self.check_pool_connection() if self.must_start_pool: self.start_pool() if self.must_start_controllers: self.start_controllers() if self.must_start_recognizers: self.start_recognizers() if self.must_start_analyzers: self.start_analyzers() self.heart_beat()
class main(): """ Main class to start whole system """ def __init__(self, components: int, vars=[]): """ Start whole system and all sub systems. components is a number between 1 and 15. components represents a binary of 4 positions being: components[0] => DataPool : Example 1 components[1] => Controllers: Example 2 components[2] => Recognizers: Exmaple 4 components[3] => Analyzers : Exmaple 8 To load all sub system set 15 to 'components' parameter. It is possible to combine the starting of some subsystems, for example, to load DataPool and recognizer only set 5 to 'components' parameter. Vars: Set any config var using form VAR=VALUE """ print('\n') print('=========================='.center(50, "=")) print(' Wellcome to Home-Monitor '.center(50, "=")) print(' Version: {} '.format(__version__).center(50, " ")) print('=========================='.center(50, "=")) print('') # Verify components to load param if components < 1 or components > 15: Binnacle().logFromCore(Messages.nothing_to_load, LogTypes.WARNING, self.__class__.__name__) return # Loading configuration file self.CONFIG_FILE = normpath(abspath('.') + "/config.yaml") if not exists(self.CONFIG_FILE): Binnacle().loggingSettings( LogTypes.ERROR, '', '%(asctime)s - %(name)s - %(levelname)s - %(message)s') Binnacle().logFromCore(Messages.config_no_file + self.CONFIG_FILE, LogTypes.ERROR, self.__class__.__name__) return self.CONFIG = Misc.readConfig(self.CONFIG_FILE) # Replacing config vars Misc.replaceConfigVars(self.CONFIG, vars) Misc.showConfig(self.CONFIG) # Logging Configuration tm = gmtime() if Misc.toBool(Misc.hasKey(self.CONFIG, 'LOGGING_TO_FILE', 'False')): loggingFile = '{}.log'.format( str(tm.tm_year) + '%02d' % tm.tm_mon + '%02d' % tm.tm_mday) loggingFile = normpath( Misc.hasKey(self.CONFIG, 'LOGGING_PATH' + "/", "./") + loggingFile) self.CONFIG['LOGGING_FILE'] = loggingFile Binnacle().loggingConf(self.CONFIG) # Define which component should be started toStart = "%04d" % int(str(bin(components)).replace("0b", "")) #print('') Binnacle().logFromCore(Messages.system_start, LogTypes.INFO, self.__class__.__name__) Binnacle().logFromCore(Messages.system_start_components + toStart, LogTypes.INFO, self.__class__.__name__) #print('') self.must_start_pool = toStart[3] == '1' self.must_start_controllers = toStart[2] == '1' self.must_start_recognizers = toStart[1] == '1' self.must_start_analyzers = toStart[0] == '1' self.commPool = CommPool(self.CONFIG) if not self.must_start_pool and components > 1: self.check_pool_connection() if self.must_start_pool: self.start_pool() if self.must_start_controllers: self.start_controllers() if self.must_start_recognizers: self.start_recognizers() if self.must_start_analyzers: self.start_analyzers() self.heart_beat() def heart_beat(self): """ Keep system running """ Binnacle().logFromCore(Messages.system_start_heart_beat, LogTypes.INFO, self.__class__.__name__) while True: try: """ Section to control the execution of the pool """ if self.must_start_pool and not self.poolThread.is_alive(): Binnacle().logFromCore(Messages.system_pool_restart, LogTypes.INFO, self.__class__.__name__) self.start_pool() except: message = Binnacle().errorDetail(Messages.system_pool_error) Binnacle().logFromCore(message, LogTypes.ERROR, self.__class__.__name__) try: """ Section to control the execution of the input data """ if self.must_start_controllers and not self.inputDataThread.is_alive( ): self.commPool.logFromCore( Messages.system_controllers_restart, LogTypes.INFO, self.__class__.__name__) self.start_controllers() except: message = Binnacle().errorDetail( Messages.system_controllers_error) self.commPool.logFromCore(message, LogTypes.ERROR, self.__class__.__name__) try: """ Section to control the execution of the recognizers """ if self.must_start_recognizers and not self.LoaderOfRecognizersThread.is_alive( ): self.commPool.logFromCore( Messages.system_recognizers_restart, LogTypes.INFO, self.__class__.__name__) self.start_recognizers() except: message = Binnacle().errorDetail( Messages.system_recognizers_error) self.commPool.logFromCore(message, LogTypes.ERROR, self.__class__.__name__) try: """ Section to control the execution of the lanalyzers """ if self.must_start_analyzers and not self.LoaderOfAnalyzersThread.is_alive( ): self.commPool.logFromCore( Messages.system_analyzers_restart, LogTypes.INFO, self.__class__.__name__) self.start_recognizers() except: message = Binnacle().errorDetail( Messages.system_analyzers_error) self.commPool.logFromCore(message, LogTypes.ERROR, self.__class__.__name__) if self.must_start_pool and not Misc.toBool( Misc.hasKey(self.CONFIG, 'RUN_IN_COLLAB', 'N')): self.commPool.sendCommand('pop') cont = self.commPool.count() #cont = Data().strToJSon(cont[0]) if cont[2] == 200 else '' print('\t{} - Refreshing time: {}'.format( cont[0], Misc.hasKey(self.CONFIG, 'CHECKING_TIME', 30)), end='\r', flush=True) sleep(Misc.hasKey(self.CONFIG, 'CHECKING_TIME', 30)) def start_pool(self): """ Start data pool """ Binnacle().logFromCore( Messages.system_pool_start + self.CONFIG['URL_BASE'], LogTypes.INFO, self.__class__.__name__) pool = DataPool() pool.initialize(self.CONFIG) self.poolThread = Process(target=pool.start, args=()) self.poolThread.daemon = True self.poolThread.start() del pool sleep(2) Binnacle().logFromCore( Messages.system_pool_started + self.CONFIG['URL_BASE'], LogTypes.INFO, self.__class__.__name__) def start_controllers(self): """ Start input data controller and all device controllers """ self.commPool.logFromCore( Messages.system_controllers_start + self.CONFIG['URL_BASE'], LogTypes.INFO, self.__class__.__name__) loc = LoaderOfController(self.CONFIG) self.inputDataThread = Process(target=loc.start, args=()) self.inputDataThread.start() del loc sleep(2) self.commPool.logFromCore( Messages.system_controllers_started + self.CONFIG['URL_BASE'], LogTypes.INFO, self.__class__.__name__) def start_recognizers(self): """ Start loader of Recognizers and all recognizers """ self.commPool.logFromCore( Messages.system_recognizers_start + self.CONFIG['URL_BASE'], LogTypes.INFO, self.__class__.__name__) lor = LoaderOfRecognizer(self.CONFIG) self.LoaderOfRecognizersThread = Process(target=lor.start, args=()) self.LoaderOfRecognizersThread.start() del lor sleep(2) self.commPool.logFromCore( Messages.system_recognizers_started + self.CONFIG['URL_BASE'], LogTypes.INFO, self.__class__.__name__) def start_analyzers(self): """ Start loader of Analyzers and all all analyzers """ self.commPool.logFromCore( Messages.system_analyzers_start + self.CONFIG['URL_BASE'], LogTypes.INFO, self.__class__.__name__) loa = LoaderOfAnalyzer(self.CONFIG) self.LoaderOfAnalyzersThread = Process(target=loa.start, args=()) self.LoaderOfAnalyzersThread.start() del loa sleep(2) self.commPool.logFromCore( Messages.system_analyzers_started + self.CONFIG['URL_BASE'], LogTypes.INFO, self.__class__.__name__) def check_pool_connection(self): """ Validate connection with pool - if not connect stop aplication """ err = '' for _ in range(3): if self.commPool.isLive(): err = '' break else: err = 'Failed' sleep(1) if err != '': msg: str = 'origin: {}, msg: {}' msg = msg.format( self.__class__.__name__, Messages.error_pool_connection.format(self.commPool.URL_BASE)) logging.log(LogTypes.CRITICAL.value, msg) sys.exit(1)