class KeypadApp: # pylint: disable=R0903 ## __slots__ allow us to explicitly declare data members __slots__ = ['_config_mgr', '_logger', '_log_store', '_state_object'] ## KeypadApp class constructor. # @param self The object pointer. def __init__(self): ## Instance of a configuration manager class. self._config_mgr = None self._logger = Logger() self._log_store = LogStore() self._logger.WriteToConsole = True self._logger.ExternalLogger = self self._logger.Initialise() ## Instance of the keypad state object. self._state_object = None ## Start the application, this will not exit until both the GUI and the # Twisted reactor have been destroyed. The only exception is if any # elements of the startup fail (e.g. loading the configuration). # @param self The object pointer. def start_app(self): self._config_mgr = ConfigurationManager() config = self._config_mgr.parse_config_file('configuration.json') if not config: self._logger.Log(LogType.Error, self._config_mgr.last_error_msg) return wx_app = wx.App() reactor.registerWxApp(wx_app) self._state_object = KeypadStateObject(config, self._logger) keypad_api_ctrl = KeypadApiController(config, self._state_object, self._log_store, self._logger) api_server = server.Site(keypad_api_ctrl) reactor.listenTCP(config.keypadController.networkPort, api_server) check_panel_loop = LoopingCall(self._state_object.check_panel) check_panel_loop.start(0.01, now=False) reactor.run() ## Stop the application. # @param self The object pointer. def stop_app(self): self._logger.Log(LogType.Info, 'Stopping keypad controller, cleaning up...') def add_log_event(self, current_time, log_level, msg): self._log_store.AddLogEvent(current_time, log_level, msg)
class CentralControllerApp: # pylint: disable=too-many-instance-attributes __slots__ = [ '_config_file', '_curr_devices', '__db', '_device_mgr', '_endpoint', '_event_manager', '_logger', '_log_store', '_state_mgr', '_worker_thread' ] def __init__(self, endpoint): self._config_file = os.getenv('CENCON_CONFIG') self._curr_devices = None self.__db = os.getenv('CENCON_DB') self._device_mgr = None self._endpoint = endpoint self._event_manager = None self._log_store = LogStore() self._state_mgr = None self._worker_thread = None self._logger = Logger() def start_app(self): # pylint: disable=too-many-statements self._logger.WriteToConsole = True self._logger.ExternalLogger = self self._logger.Initialise() signal.signal(signal.SIGINT, self._signal_handler) self._logger.Log(LogType.Info, 'Secure Shed Central Controller V%s', VERSION) self._logger.Log(LogType.Info, 'Copyright %s Secure Shed Project Dev Team', COPYRIGHT) self._logger.Log(LogType.Info, 'Licensed under the Apache License, Version 2.0') config_manger = ConfigurationManager() configuration = config_manger.parse_config_file(self._config_file) if not configuration: self._logger.Log(LogType.Error, 'Parse failed, last message : %s', config_manger.last_error_msg) sys.exit(1) self._logger.Log(LogType.Info, '=== Configuration Parameters ===') self._logger.Log(LogType.Info, 'Environment Variables:') self._logger.Log(LogType.Info, '|=> Configuration file : %s', self._config_file) self._logger.Log(LogType.Info, '|=> Database : %s', self.__db) self._logger.Log(LogType.Info, '===================================') self._logger.Log(LogType.Info, '=== Configuration File Settings ===') self._logger.Log(LogType.Info, 'General Settings:') self._logger.Log(LogType.Info, '|=> Devices Config File : %s', configuration.general_settings.devicesConfigFile) self._logger.Log(LogType.Info, '|=> Device Types Config File : %s', configuration.general_settings.deviceTypesConfigFile) self._logger.Log(LogType.Info, 'Keypad Controller Settings:') self._logger.Log(LogType.Info, '|=> Authentication Key : %s', configuration.keypad_controller.authKey) self._logger.Log(LogType.Info, '|=> Endpoint : %s', configuration.keypad_controller.endpoint) self._logger.Log(LogType.Info, 'Central Controller Settings:') self._logger.Log(LogType.Info, '|=> Authentication Key : %s', configuration.central_controller_api.authKey) self._logger.Log(LogType.Info, '|=> Network Port : %s', configuration.central_controller_api.networkPort) self._logger.Log(LogType.Info, '================================') self._event_manager = EventManager() controller_db = ControllerDBInterface() if not controller_db.connect(self.__db): self._logger.Log(LogType.Error, "Database '%s' is missing!", self.__db) sys.exit(1) # Build state manager which manages the state of the alarm itself and # how states are changed due to hardware device(s) being triggered. self._state_mgr = StateManager(controller_db, configuration, self._event_manager, self._logger) # Attempt to load the device types plug-ins, if a plug-in cannot be # found or is invalid then a warning is logged and it's not loaded. device_type_mgr = DeviceTypeManager(self._logger) device_types_cfg = device_type_mgr.read_device_types_config( configuration.general_settings.deviceTypesConfigFile) if not device_types_cfg: self._logger.Log(LogType.Error, device_type_mgr.last_error_msg) sys.exit(1) device_type_mgr.load_device_types() # Load the devices configuration file which contains the devices # attached to the alarm. The devices are matched to the device types # loaded above. devices_cfg = configuration.general_settings.devicesConfigFile devices_cfg_loader = DevicesConfigLoader() self._curr_devices = devices_cfg_loader.read_devices_config_file( devices_cfg) if not self._curr_devices: self._logger.Log(LogType.Error, devices_cfg_loader.last_error_msg) sys.exit(1) self._device_mgr = DeviceManager(device_type_mgr, self._event_manager, self._logger) dev_lst = self._curr_devices[devices_cfg_loader.JsonTopElement.Devices] self._device_mgr.load(dev_lst) self._device_mgr.initialise_hardware() self._register_event_callbacks() # Create the IO processing thread which handles IO requests from # hardware devices. self._worker_thread = WorkerThread(configuration, self._device_mgr, self._event_manager, self._state_mgr, self._logger) self._worker_thread.start() # pylint: disable=unused-variable api_controller = ApiController(self._event_manager, controller_db, configuration, self._endpoint, self._log_store, self._logger) send_alive_ping_evt = Event(Evts.EvtType.KeypadApiSendAlivePing) self._event_manager.QueueEvent(send_alive_ping_evt) def add_log_event(self, curr_time, log_level, msg): self._log_store.add_log_event(curr_time, log_level, msg) def _register_event_callbacks(self): # ============================= # == Register event : Keypad == # ============================= # Register event: Receive keypad event. self._event_manager.RegisterEvent(Evts.EvtType.KeypadKeyCodeEntered, self._state_mgr.rcv_keypad_event) # Register event: Receive keypad event. self._event_manager.RegisterEvent(Evts.EvtType.SensorDeviceStateChange, self._state_mgr.rcv_device_event) # =============================== # == Register event : Hardware == # =============================== # Register event: Activate alarm sirens. self._event_manager.RegisterEvent(Evts.EvtType.ActivateSiren, self._device_mgr.receive_event) # Register event: Deactivate alarm sirens. self._event_manager.RegisterEvent(Evts.EvtType.DeactivateSiren, self._device_mgr.receive_event) # ========================================= # == Register event : Alarm state change == # ========================================= # Register event: Alarm activated. self._event_manager.RegisterEvent(Evts.EvtType.AlarmActivated, self._device_mgr.receive_event) # Register event: Alarm activated. self._event_manager.RegisterEvent(Evts.EvtType.AlarmDeactivated, self._device_mgr.receive_event) # ================================= # == Register event : Keypad Api == # ================================= # Register event: Request sending of 'Alive Ping' message. self._event_manager.RegisterEvent(Evts.EvtType.KeypadApiSendAlivePing, self._state_mgr.send_alive_ping_msg) # Register event: Request sending of 'Keypad Locked' message. self._event_manager.RegisterEvent( Evts.EvtType.KeypadApiSendKeypadLock, self._state_mgr.send_keypad_locked_msg) def _signal_handler(self, signum, frame): #pylint: disable=unused-argument self._logger.Log(LogType.Info, 'Shutting down...') self._shutdown() sys.exit(1) def _shutdown(self): self._worker_thread.signal_shutdown_requested() while not self._worker_thread.shutdown_completed: time.sleep(1) self._logger.Log(LogType.Info, 'Worker thread has Shut down')