Exemplo n.º 1
0
    def prepare(self, parsed_arguments):
        logger.debug("prepare")
        logger.debug("givven arguments argv: %s", parsed_arguments)

        if not parsed_arguments.configfile and not self.config:
            raise Exception("no config exists an no new given")

        self.__event_handler = EventHandler()

        self.__config = ConfigObject.load_config(parsed_arguments.configfile)
        self.__keyboard = load_keyboard()
        logger.debug('Keyboard is now %s', self.keyboard.name)
        self.__sipphone = load_sipphone()
        self.sipphone.start()

        #register own events
        self.event_handler.register_event('OnStartup', __name__)
        self.event_handler.register_event('OnShutdown', __name__)

        # register eventbased actions from configfile
        for event_section in self.config.get_sections('EVENT_'):
            event_name = event_section[len('EVENT_'):]
            for action in sorted(self.config.get_keys(event_section)):
                self.event_handler.register_action(event_name, self.config.get(event_section, action))

        # register actions for inputpins
        section_name = 'InputPins'
        for input_pin in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action('OnKeyPressed_'+input_pin, self.config.get(section_name, input_pin))

        # register actions for DTMF
        section_name = 'DTMF'
        for DTMF in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action('OnDTMF_'+DTMF, self.config.get(section_name, DTMF))

        # register keep_alive_led
        is_alive_led = self.config.get('DoorPi', 'is_alive_led', None)
        if is_alive_led is not None:
            self.event_handler.register_action('OnTimeSecondEvenNumber', 'out:%s,HIGH,False'%is_alive_led)
            self.event_handler.register_action('OnTimeSecondUnevenNumber', 'out:%s,LOW,False'%is_alive_led)

        self.__prepared = True
        return self
Exemplo n.º 2
0
class DoorPi(object):
    __metaclass__ = Singleton

    __prepared = False

    __config = None

    @property
    def config(self):
        return self.__config

    __keyboard = None

    @property
    def keyboard(self):
        return self.__keyboard

    #def get_keyboard(self): return self.__keyboard

    __sipphone = None

    @property
    def sipphone(self):
        return self.__sipphone

    @property
    def additional_informations(self):
        if self.event_handler is None: return {}
        else: return self.event_handler.additional_informations

    __event_handler = None

    @property
    def event_handler(self):
        return self.__event_handler

    __webserver = None

    @property
    def webserver(self):
        return self.__webserver

    @property
    def status(self):
        return DoorPiStatus(self)

    def get_status(self, modules='', value='', name=''):
        return DoorPiStatus(self, modules, value, name)

    @property
    def epilog(self):
        return metadata.epilog

    @property
    def name(self):
        return str(metadata.package)

    @property
    def name_and_version(self):
        return str(metadata.package) + " - version: " + metadata.version

    __shutdown = False

    @property
    def shutdown(self):
        return self.__shutdown

    _base_path = metadata.doorpi_path

    @property
    def base_path(self):
        if self._base_path is None:
            try:
                self._base_path = os.path.join(os.path.expanduser('~'),
                                               metadata.package)
                assert os.access(
                    self._base_path,
                    os.W_OK), 'use fallback for base_path (see tmp path)'
            except Exception as exp:
                logger.error(exp)
                import tempfile
                self._base_path = tempfile.gettempdir()
        return self._base_path

    def __init__(self, parsed_arguments=None):
        self.__parsed_arguments = parsed_arguments
        # for start as daemon - if start as app it will not matter to load this vars
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/null'
        self.stderr_path = '/dev/null'
        self.pidfile_path = '/var/run/doorpi.pid'
        self.pidfile_timeout = 5

        self.__last_tick = time.time()

    def doorpi_shutdown(self, time_until_shutdown=10):
        time.sleep(time_until_shutdown)
        self.__shutdown = True

    def prepare(self, parsed_arguments):
        logger.debug("prepare")
        logger.debug("given arguments argv: %s", parsed_arguments)

        self.__config = ConfigObject.load_config(parsed_arguments.configfile)
        self._base_path = self.config.get('DoorPi', 'base_path',
                                          self.base_path)
        self.__event_handler = EventHandler()

        if self.config.config_file is None:
            self.event_handler.register_action('AfterStartup',
                                               self.config.save_config)
            self.config.get('EVENT_OnStartup', '10', 'sleep:1')

        if 'test' in parsed_arguments and parsed_arguments.test is True:
            logger.warning('using only test-mode and destroy after 5 seconds')
            self.event_handler.register_action(
                'AfterStartup', DoorPiShutdownAction(self.doorpi_shutdown))

        # register own events
        self.event_handler.register_event('BeforeStartup', __name__)
        self.event_handler.register_event('OnStartup', __name__)
        self.event_handler.register_event('AfterStartup', __name__)
        self.event_handler.register_event('BeforeShutdown', __name__)
        self.event_handler.register_event('OnShutdown', __name__)
        self.event_handler.register_event('AfterShutdown', __name__)
        self.event_handler.register_event('OnTimeTick', __name__)
        self.event_handler.register_event('OnTimeTickRealtime', __name__)

        # register base actions
        self.event_handler.register_action('OnTimeTick',
                                           'time_tick:!last_tick!')

        # register modules
        self.__webserver = load_webserver()
        self.__keyboard = load_keyboard()
        self.__sipphone = load_sipphone()
        self.sipphone.start()

        # register eventbased actions from configfile
        for event_section in self.config.get_sections('EVENT_'):
            logger.info("found EVENT_ section '%s' in configfile",
                        event_section)
            event_name = event_section[len('EVENT_'):]
            for action in sorted(self.config.get_keys(event_section)):
                logger.info("registering action '%s' for event '%s'", action,
                            event_name)
                self.event_handler.register_action(
                    event_name, self.config.get(event_section, action))

        # register actions for inputpins
        if 'KeyboardHandler' not in self.keyboard.name:
            section_name = 'InputPins'
            for input_pin in sorted(self.config.get_keys(section_name)):
                self.event_handler.register_action(
                    'OnKeyPressed_' + input_pin,
                    self.config.get(section_name, input_pin))
        else:
            for keyboard_name in self.keyboard.loaded_keyboards:
                section_name = keyboard_name + '_InputPins'
                for input_pin in self.config.get_keys(section_name, log=False):
                    self.event_handler.register_action(
                        'OnKeyPressed_' + keyboard_name + '.' + input_pin,
                        self.config.get(section_name, input_pin))

        # register actions for DTMF
        section_name = 'DTMF'
        for DTMF in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action(
                'OnDTMF_' + DTMF, self.config.get(section_name, DTMF))

        # register keep_alive_led
        is_alive_led = self.config.get('DoorPi', 'is_alive_led', '')
        if is_alive_led is not '':
            self.event_handler.register_action(
                'OnTimeSecondEvenNumber', 'out:%s,HIGH,False' % is_alive_led)
            self.event_handler.register_action(
                'OnTimeSecondUnevenNumber', 'out:%s,LOW,False' % is_alive_led)

        self.__prepared = True
        return self

    def __del__(self):
        return self.destroy()

    @property
    def modules_destroyed(self):
        if len(self.event_handler.sources) > 1: return False
        return self.event_handler.idle

    def destroy(self):
        logger.debug('destroy doorpi')

        if not self.event_handler or self.event_handler.threads == None:
            DoorPiEventHandlerNotExistsException(
                "don't try to stop, when not prepared")
            return False

        logger.debug("Threads before starting shutdown: %s",
                     self.event_handler.threads)

        self.event_handler.fire_event('BeforeShutdown', __name__)
        self.event_handler.fire_event_synchron('OnShutdown', __name__)
        self.event_handler.fire_event('AfterShutdown', __name__)

        timeout = 5
        waiting_between_checks = 0.5
        time.sleep(waiting_between_checks)
        while timeout > 0 and self.modules_destroyed is not True:
            # while not self.event_handler.idle and timeout > 0 and len(self.event_handler.sources) > 1:
            logger.debug('wait %s seconds for threads %s and %s event',
                         timeout, len(self.event_handler.threads[1:]),
                         len(self.event_handler.sources))
            logger.trace('still existing threads:       %s',
                         self.event_handler.threads[1:])
            logger.trace('still existing event sources: %s',
                         self.event_handler.sources)
            time.sleep(waiting_between_checks)
            timeout -= waiting_between_checks

        if timeout <= 0:
            logger.warning(
                "waiting for threads to time out - there are still threads: %s",
                self.event_handler.threads[1:])

        logger.info('======== DoorPi successfully shutdown ========')
        return True

    def restart(self):
        if self.destroy(): self.run()
        else: raise DoorPiRestartException()

    def run(self):
        logger.debug("run")
        if not self.__prepared: self.prepare(self.__parsed_arguments)

        self.event_handler.fire_event('BeforeStartup', __name__)
        self.event_handler.fire_event_synchron('OnStartup', __name__)
        self.event_handler.fire_event('AfterStartup', __name__)

        # self.event_handler.register_action('OnTimeMinuteUnevenNumber', 'doorpi_restart')

        logger.info('DoorPi started successfully')
        logger.info('BasePath is %s', self.base_path)
        if self.__webserver:
            logger.info('Weburl is %s', self.__webserver.own_url)
        else:
            logger.info('no Webserver loaded')

        time_ticks = 0

        while True and not self.__shutdown:
            time_ticks += 0.05
            self.check_time_critical_threads()
            if time_ticks > 0.5:
                self.__last_tick = time.time()
                self.__event_handler.fire_event_asynchron(
                    'OnTimeTick', __name__)
                time_ticks = 0
            time.sleep(0.05)
        return self

    def check_time_critical_threads(self):
        if self.sipphone: self.sipphone.self_check()

    def parse_string(self, input_string):
        parsed_string = datetime.datetime.now().strftime(str(input_string))

        if self.keyboard is None or self.keyboard.last_key is None:
            self.additional_informations['LastKey'] = "NotSetYet"
        else:
            self.additional_informations['LastKey'] = str(
                self.keyboard.last_key)

        infos_as_html = '<table>'
        for key in self.additional_informations.keys():
            infos_as_html += '<tr><td>'
            infos_as_html += '<b>' + key + '</b>'
            infos_as_html += '</td><td>'
            infos_as_html += '<i>' + cgi.escape(
                str(self.additional_informations.get(key)).replace(
                    "\r\n", "<br />")) + '</i>'
            infos_as_html += '</td></tr>'
        infos_as_html += '</table>'

        mapping_table = {
            'INFOS_PLAIN': str(self.additional_informations),
            'INFOS': infos_as_html,
            'BASEPATH': self.base_path,
            'last_tick': str(self.__last_tick)
        }

        if self.keyboard and 'KeyboardHandler' not in self.keyboard.name:
            for output_pin in self.config.get_keys('OutputPins', log=False):
                mapping_table[self.config.get('OutputPins',
                                              output_pin,
                                              log=False)] = output_pin
        elif self.keyboard and 'KeyboardHandler' in self.keyboard.name:
            for outputpin_section in self.config.get_sections(
                    '_OutputPins', False):
                for output_pin in self.config.get_keys(outputpin_section,
                                                       log=False):
                    mapping_table[self.config.get(outputpin_section,
                                                  output_pin,
                                                  log=False)] = output_pin

        for key in mapping_table.keys():
            parsed_string = parsed_string.replace("!" + key + "!",
                                                  mapping_table[key])

        for key in self.additional_informations.keys():
            parsed_string = parsed_string.replace(
                "!" + key + "!", str(self.additional_informations[key]))

        return parsed_string
Exemplo n.º 3
0
    def prepare(self, parsed_arguments):
        logger.debug("prepare")
        logger.debug("given arguments argv: %s", parsed_arguments)

        self.__config = ConfigObject.load_config(parsed_arguments.configfile)
        self._base_path = self.config.get('DoorPi', 'base_path',
                                          self.base_path)
        self.__event_handler = EventHandler()

        if self.config.config_file is None:
            self.event_handler.register_action('AfterStartup',
                                               self.config.save_config)
            self.config.get('EVENT_OnStartup', '10', 'sleep:1')

        if 'test' in parsed_arguments and parsed_arguments.test is True:
            logger.warning('using only test-mode and destroy after 5 seconds')
            self.event_handler.register_action(
                'AfterStartup', DoorPiShutdownAction(self.doorpi_shutdown))

        # register own events
        self.event_handler.register_event('BeforeStartup', __name__)
        self.event_handler.register_event('OnStartup', __name__)
        self.event_handler.register_event('AfterStartup', __name__)
        self.event_handler.register_event('BeforeShutdown', __name__)
        self.event_handler.register_event('OnShutdown', __name__)
        self.event_handler.register_event('AfterShutdown', __name__)
        self.event_handler.register_event('OnTimeTick', __name__)
        self.event_handler.register_event('OnTimeTickRealtime', __name__)

        # register base actions
        self.event_handler.register_action('OnTimeTick',
                                           'time_tick:!last_tick!')

        # register modules
        self.__webserver = load_webserver()
        self.__keyboard = load_keyboard()
        self.__sipphone = load_sipphone()
        self.sipphone.start()

        # register eventbased actions from configfile
        for event_section in self.config.get_sections('EVENT_'):
            logger.info("found EVENT_ section '%s' in configfile",
                        event_section)
            event_name = event_section[len('EVENT_'):]
            for action in sorted(self.config.get_keys(event_section)):
                logger.info("registering action '%s' for event '%s'", action,
                            event_name)
                self.event_handler.register_action(
                    event_name, self.config.get(event_section, action))

        # register actions for inputpins
        if 'KeyboardHandler' not in self.keyboard.name:
            section_name = 'InputPins'
            for input_pin in sorted(self.config.get_keys(section_name)):
                self.event_handler.register_action(
                    'OnKeyPressed_' + input_pin,
                    self.config.get(section_name, input_pin))
        else:
            for keyboard_name in self.keyboard.loaded_keyboards:
                section_name = keyboard_name + '_InputPins'
                for input_pin in self.config.get_keys(section_name, log=False):
                    self.event_handler.register_action(
                        'OnKeyPressed_' + keyboard_name + '.' + input_pin,
                        self.config.get(section_name, input_pin))

        # register actions for DTMF
        section_name = 'DTMF'
        for DTMF in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action(
                'OnDTMF_' + DTMF, self.config.get(section_name, DTMF))

        # register keep_alive_led
        is_alive_led = self.config.get('DoorPi', 'is_alive_led', '')
        if is_alive_led is not '':
            self.event_handler.register_action(
                'OnTimeSecondEvenNumber', 'out:%s,HIGH,False' % is_alive_led)
            self.event_handler.register_action(
                'OnTimeSecondUnevenNumber', 'out:%s,LOW,False' % is_alive_led)

        self.__prepared = True
        return self
Exemplo n.º 4
0
class DoorPi(object):
    __metaclass__ = Singleton

    __prepared = False

    __config = None
    @property
    def config(self): return self.__config

    __keyboard = None
    @property
    def keyboard(self): return self.__keyboard
    #def get_keyboard(self): return self.__keyboard

    __sipphone = None
    @property
    def sipphone(self): return self.__sipphone

    @property
    def additional_informations(self):
        if self.event_handler is None: return {}
        else: return self.event_handler.additional_informations

    __event_handler = None
    @property
    def event_handler(self): return self.__event_handler

    __webserver = None
    @property
    def webserver(self): return self.__webserver

    @property
    def status(self): return DoorPiStatus(self)
    def get_status(self, modules = '', value= '', name = ''): return DoorPiStatus(self, modules, value, name)

    @property
    def epilog(self): return metadata.epilog

    @property
    def name(self): return str(metadata.package)
    @property
    def name_and_version(self): return str(metadata.package) + " - version: " + metadata.version

    __shutdown = False
    @property
    def shutdown(self): return self.__shutdown

    @property
    def base_path(self): return metadata.base_path

    def __init__(self, parsed_arguments = None):
        self.__parsed_arguments = parsed_arguments
        # for start as daemon - if start as app it will not matter to load this vars
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/null'
        self.stderr_path = '/dev/null'
        self.pidfile_path =  '/var/run/doorpi.pid'
        self.pidfile_timeout = 5

        self.__last_tick = time.time()

    def prepare(self, parsed_arguments):
        logger.debug("prepare")
        logger.debug("givven arguments argv: %s", parsed_arguments)

        #if not parsed_arguments.configfile and not self.config:
        #    raise Exception("no config exists and no new given")

        self.__config = ConfigObject.load_config(parsed_arguments.configfile)
        self.__event_handler = EventHandler()

        if self.config.config_file is None:
            self.event_handler.register_action('AfterStartup', self.config.save_config)
            self.config.get('EVENT_OnStartup', '10', 'sleep:1')

        #register own events
        self.event_handler.register_event('BeforeStartup', __name__)
        self.event_handler.register_event('OnStartup', __name__)
        self.event_handler.register_event('AfterStartup', __name__)
        self.event_handler.register_event('BeforeShutdown', __name__)
        self.event_handler.register_event('OnShutdown', __name__)
        self.event_handler.register_event('AfterShutdown', __name__)
        self.event_handler.register_event('OnTimeTick', __name__)
        self.event_handler.register_event('OnTimeTickRealtime', __name__)

        #register base actions
        self.event_handler.register_action('OnTimeTick', 'time_tick:!last_tick!')

        #register modules
        self.__webserver    = load_webserver().start()
        self.__keyboard     = load_keyboard()
        self.__sipphone     = load_sipphone()
        self.sipphone.start()

        # register eventbased actions from configfile
        for event_section in self.config.get_sections('EVENT_'):
            logger.info("found EVENT_ section '%s' in configfile", event_section)
            event_name = event_section[len('EVENT_'):]
            for action in sorted(self.config.get_keys(event_section)):
                logger.info("registering action '%s' for event '%s'", action, event_name)
                self.event_handler.register_action(event_name, self.config.get(event_section, action))

        # register actions for inputpins
        if 'KeyboardHandler' not in self.keyboard.name:
            section_name = 'InputPins'
            for input_pin in sorted(self.config.get_keys(section_name)):
                self.event_handler.register_action('OnKeyPressed_'+input_pin, self.config.get(section_name, input_pin))
        else:
            for keyboard_name in self.keyboard.loaded_keyboards:
                section_name = keyboard_name+'_InputPins'
                for input_pin in self.config.get_keys(section_name, log = False):
                    self.event_handler.register_action(
                        'OnKeyPressed_'+keyboard_name+'.'+input_pin,
                        self.config.get(section_name, input_pin)
                    )

        # register actions for DTMF
        section_name = 'DTMF'
        for DTMF in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action('OnDTMF_'+DTMF, self.config.get(section_name, DTMF))

        # register keep_alive_led
        is_alive_led = self.config.get('DoorPi', 'is_alive_led', '')
        if is_alive_led is not '':
            self.event_handler.register_action('OnTimeSecondEvenNumber', 'out:%s,HIGH,False'%is_alive_led)
            self.event_handler.register_action('OnTimeSecondUnevenNumber', 'out:%s,LOW,False'%is_alive_led)

        self.__prepared = True
        return self

    def __del__(self):
        return self.destroy()

    @property
    def modules_destroyed(self):
        if len(self.event_handler.sources) > 1: return False
        return self.event_handler.idle

    def destroy(self):
        logger.debug('destroy doorpi')

        if not self.event_handler: DoorPiEventHandlerNotExistsException("don't try to stop, when not prepared")
        #if self.__prepared is not True:
        #    raise DoorPiDoesntExist("don't try to stop, when not prepared")

        logger.debug("Threads before starting shutdown: %s", self.event_handler.threads)

        self.event_handler.fire_event('BeforeShutdown', __name__)
        self.event_handler.fire_event_synchron('OnShutdown', __name__)
        self.event_handler.fire_event('AfterShutdown', __name__)

        timeout = 5
        waiting_between_checks = 0.5
        time.sleep(waiting_between_checks)
        while timeout > 0 and self.modules_destroyed != True:
        #while not self.event_handler.idle and timeout > 0 and len(self.event_handler.sources) > 1:
            logger.debug('wait %s seconds for threads %s and %s event',
                         timeout, len(self.event_handler.threads[1:]), len(self.event_handler.sources))
            logger.trace('still existing threads:       %s', self.event_handler.threads[1:])
            logger.trace('still existing event sources: %s', self.event_handler.sources)
            time.sleep(waiting_between_checks)
            timeout -= waiting_between_checks

        if timeout <= 0:
            logger.warning("waiting for threads to time out - there are still threads: %s", self.event_handler.threads[1:])

        logger.info('======== DoorPi successfully shutdown ========')
        return True

    def restart(self):
        if self.destroy(): self.run()
        else: raise DoorPiRestartException()

    def run(self):
        logger.debug("run")
        if not self.__prepared: self.prepare(self.__parsed_arguments)

        self.event_handler.fire_event('BeforeStartup', __name__)
        self.event_handler.fire_event_synchron('OnStartup', __name__)
        self.event_handler.fire_event('AfterStartup', __name__)

        #self.event_handler.register_action('OnTimeMinuteUnevenNumber', 'doorpi_restart')

        logger.info('DoorPi started successfully')
        logger.info('BasePath is %s', self.base_path)

        time_ticks = 0

        while True and not self.__shutdown:
            time_ticks += 0.05
            if self.sipphone: self.sipphone.self_check()
            if time_ticks > 0.5:
                self.__last_tick = time.time()
                self.__event_handler.fire_event_asynchron('OnTimeTick', __name__)
                time_ticks = 0
            time.sleep(0.05)
        return self

    def parse_string(self, input_string):
        parsed_string = datetime.datetime.now().strftime(str(input_string))

        if self.keyboard is None or self.keyboard.last_key is None:
            self.additional_informations['LastKey'] = "NotSetYet"
        else:
            self.additional_informations['LastKey'] = str(self.keyboard.last_key)

        infos_as_html = '<table>'
        for key in self.additional_informations.keys():
            infos_as_html += '<tr><td>'
            infos_as_html += '<b>'+key+'</b>'
            infos_as_html += '</td><td>'
            infos_as_html += '<i>'+cgi.escape(
                str(self.additional_informations.get(key)).replace("\r\n", "<br />")
            )+'</i>'
            infos_as_html += '</td></tr>'
        infos_as_html += '</table>'

        mapping_table = {
            'INFOS_PLAIN':      str(self.additional_informations),
            'INFOS':            infos_as_html,
            'BASEPATH':         self.base_path,
            'last_tick':        str(self.__last_tick)
        }

        if self.keyboard and 'KeyboardHandler' not in self.keyboard.name:
            for output_pin in self.config.get_keys('OutputPins', log = False):
                mapping_table[self.config.get('OutputPins', output_pin, log = False)] = output_pin
        elif self.keyboard and 'KeyboardHandler' in self.keyboard.name:
            for outputpin_section in self.config.get_sections('_OutputPins', False):
                for output_pin in self.config.get_keys(outputpin_section, log = False):
                    mapping_table[self.config.get(outputpin_section, output_pin, log = False)] = output_pin

        for key in mapping_table.keys():
            parsed_string = parsed_string.replace(
                "!"+key+"!",
                mapping_table[key]
            )

        for key in self.additional_informations.keys():
            parsed_string = parsed_string.replace(
                "!"+key+"!",
                str(self.additional_informations[key])
            )

        return parsed_string
Exemplo n.º 5
0
    def prepare(self, parsed_arguments):
        logger.debug("prepare")
        logger.debug("givven arguments argv: %s", parsed_arguments)

        #if not parsed_arguments.configfile and not self.config:
        #    raise Exception("no config exists and no new given")

        self.__config = ConfigObject.load_config(parsed_arguments.configfile)
        self.__event_handler = EventHandler()

        if self.config.config_file is None:
            self.event_handler.register_action('AfterStartup', self.config.save_config)
            self.config.get('EVENT_OnStartup', '10', 'sleep:1')

        #register own events
        self.event_handler.register_event('BeforeStartup', __name__)
        self.event_handler.register_event('OnStartup', __name__)
        self.event_handler.register_event('AfterStartup', __name__)
        self.event_handler.register_event('BeforeShutdown', __name__)
        self.event_handler.register_event('OnShutdown', __name__)
        self.event_handler.register_event('AfterShutdown', __name__)
        self.event_handler.register_event('OnTimeTick', __name__)
        self.event_handler.register_event('OnTimeTickRealtime', __name__)

        #register base actions
        self.event_handler.register_action('OnTimeTick', 'time_tick:!last_tick!')

        #register modules
        self.__webserver    = load_webserver().start()
        self.__keyboard     = load_keyboard()
        self.__sipphone     = load_sipphone()
        self.sipphone.start()

        # register eventbased actions from configfile
        for event_section in self.config.get_sections('EVENT_'):
            logger.info("found EVENT_ section '%s' in configfile", event_section)
            event_name = event_section[len('EVENT_'):]
            for action in sorted(self.config.get_keys(event_section)):
                logger.info("registering action '%s' for event '%s'", action, event_name)
                self.event_handler.register_action(event_name, self.config.get(event_section, action))

        # register actions for inputpins
        if 'KeyboardHandler' not in self.keyboard.name:
            section_name = 'InputPins'
            for input_pin in sorted(self.config.get_keys(section_name)):
                self.event_handler.register_action('OnKeyPressed_'+input_pin, self.config.get(section_name, input_pin))
        else:
            for keyboard_name in self.keyboard.loaded_keyboards:
                section_name = keyboard_name+'_InputPins'
                for input_pin in self.config.get_keys(section_name, log = False):
                    self.event_handler.register_action(
                        'OnKeyPressed_'+keyboard_name+'.'+input_pin,
                        self.config.get(section_name, input_pin)
                    )

        # register actions for DTMF
        section_name = 'DTMF'
        for DTMF in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action('OnDTMF_'+DTMF, self.config.get(section_name, DTMF))

        # register keep_alive_led
        is_alive_led = self.config.get('DoorPi', 'is_alive_led', '')
        if is_alive_led is not '':
            self.event_handler.register_action('OnTimeSecondEvenNumber', 'out:%s,HIGH,False'%is_alive_led)
            self.event_handler.register_action('OnTimeSecondUnevenNumber', 'out:%s,LOW,False'%is_alive_led)

        self.__prepared = True
        return self
Exemplo n.º 6
0
class DoorPi(object):
    __metaclass__ = Singleton

    __prepared = False

    __config = None

    @property
    def config(self):
        return self.__config

    __keyboard = None

    @property
    def keyboard(self):
        return self.__keyboard

    # def get_keyboard(self): return self.__keyboard

    __sipphone = None

    @property
    def sipphone(self):
        return self.__sipphone

    @property
    def additional_informations(self):
        if self.event_handler is None:
            return {}
        else:
            return self.event_handler.additional_informations

    __event_handler = None

    @property
    def event_handler(self):
        return self.__event_handler

    __webserver = None

    @property
    def webserver(self):
        return self.__webserver

    @property
    def status(self):
        return DoorPiStatus(self)

    def get_status(self, modules="", value="", name=""):
        return DoorPiStatus(self, modules, value, name)

    @property
    def epilog(self):
        return metadata.epilog

    @property
    def name(self):
        return str(metadata.package)

    @property
    def name_and_version(self):
        return str(metadata.package) + " - version: " + metadata.version

    __shutdown = False

    @property
    def shutdown(self):
        return self.__shutdown

    _base_path = metadata.doorpi_path

    @property
    def base_path(self):
        if self._base_path is None:
            try:
                self._base_path = os.path.join(os.path.expanduser("~"), metadata.package)
                assert os.access(self._base_path, os.W_OK), "use fallback for base_path (see tmp path)"
            except Exception as exp:
                logger.error(exp)
                import tempfile

                self._base_path = tempfile.gettempdir()
        return self._base_path

    def __init__(self, parsed_arguments=None):
        self.__parsed_arguments = parsed_arguments
        # for start as daemon - if start as app it will not matter to load this vars
        self.stdin_path = "/dev/null"
        self.stdout_path = "/dev/null"
        self.stderr_path = "/dev/null"
        self.pidfile_path = "/var/run/doorpi.pid"
        self.pidfile_timeout = 5

        self.__last_tick = time.time()

    def doorpi_shutdown(self, time_until_shutdown=10):
        time.sleep(time_until_shutdown)
        self.__shutdown = True

    def prepare(self, parsed_arguments):
        logger.debug("prepare")
        logger.debug("given arguments argv: %s", parsed_arguments)

        self.__config = ConfigObject.load_config(parsed_arguments.configfile)
        self._base_path = self.config.get("DoorPi", "base_path", self.base_path)
        self.__event_handler = EventHandler()

        if self.config.config_file is None:
            self.event_handler.register_action("AfterStartup", self.config.save_config)
            self.config.get("EVENT_OnStartup", "10", "sleep:1")

        if "test" in parsed_arguments and parsed_arguments.test is True:
            logger.warning("using only test-mode and destroy after 5 seconds")
            self.event_handler.register_action("AfterStartup", DoorPiShutdownAction(self.doorpi_shutdown))

        # register own events
        self.event_handler.register_event("BeforeStartup", __name__)
        self.event_handler.register_event("OnStartup", __name__)
        self.event_handler.register_event("AfterStartup", __name__)
        self.event_handler.register_event("BeforeShutdown", __name__)
        self.event_handler.register_event("OnShutdown", __name__)
        self.event_handler.register_event("AfterShutdown", __name__)
        self.event_handler.register_event("OnTimeTick", __name__)
        self.event_handler.register_event("OnTimeTickRealtime", __name__)

        # register base actions
        self.event_handler.register_action("OnTimeTick", "time_tick:!last_tick!")

        # register modules
        self.__webserver = load_webserver()
        self.__keyboard = load_keyboard()
        self.__sipphone = load_sipphone()
        self.sipphone.start()

        # register eventbased actions from configfile
        for event_section in self.config.get_sections("EVENT_"):
            logger.info("found EVENT_ section '%s' in configfile", event_section)
            event_name = event_section[len("EVENT_") :]
            for action in sorted(self.config.get_keys(event_section)):
                logger.info("registering action '%s' for event '%s'", action, event_name)
                self.event_handler.register_action(event_name, self.config.get(event_section, action))

        # register actions for inputpins
        if "KeyboardHandler" not in self.keyboard.name:
            section_name = "InputPins"
            for input_pin in sorted(self.config.get_keys(section_name)):
                self.event_handler.register_action(
                    "OnKeyPressed_" + input_pin, self.config.get(section_name, input_pin)
                )
        else:
            for keyboard_name in self.keyboard.loaded_keyboards:
                section_name = keyboard_name + "_InputPins"
                for input_pin in self.config.get_keys(section_name, log=False):
                    self.event_handler.register_action(
                        "OnKeyPressed_" + keyboard_name + "." + input_pin, self.config.get(section_name, input_pin)
                    )

        # register actions for DTMF
        section_name = "DTMF"
        for DTMF in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action("OnDTMF_" + DTMF, self.config.get(section_name, DTMF))

        # register keep_alive_led
        is_alive_led = self.config.get("DoorPi", "is_alive_led", "")
        if is_alive_led is not "":
            self.event_handler.register_action("OnTimeSecondEvenNumber", "out:%s,HIGH,False" % is_alive_led)
            self.event_handler.register_action("OnTimeSecondUnevenNumber", "out:%s,LOW,False" % is_alive_led)

        self.__prepared = True
        return self

    def __del__(self):
        return self.destroy()

    @property
    def modules_destroyed(self):
        if len(self.event_handler.sources) > 1:
            return False
        return self.event_handler.idle

    def destroy(self):
        logger.debug("destroy doorpi")

        if not self.event_handler or self.event_handler.threads == None:
            DoorPiEventHandlerNotExistsException("don't try to stop, when not prepared")
            return False

        logger.debug("Threads before starting shutdown: %s", self.event_handler.threads)

        self.event_handler.fire_event("BeforeShutdown", __name__)
        self.event_handler.fire_event_synchron("OnShutdown", __name__)
        self.event_handler.fire_event("AfterShutdown", __name__)

        timeout = 5
        waiting_between_checks = 0.5
        time.sleep(waiting_between_checks)
        while timeout > 0 and self.modules_destroyed is not True:
            # while not self.event_handler.idle and timeout > 0 and len(self.event_handler.sources) > 1:
            logger.debug(
                "wait %s seconds for threads %s and %s event",
                timeout,
                len(self.event_handler.threads[1:]),
                len(self.event_handler.sources),
            )
            logger.trace("still existing threads:       %s", self.event_handler.threads[1:])
            logger.trace("still existing event sources: %s", self.event_handler.sources)
            time.sleep(waiting_between_checks)
            timeout -= waiting_between_checks

        if timeout <= 0:
            logger.warning(
                "waiting for threads to time out - there are still threads: %s", self.event_handler.threads[1:]
            )

        logger.info("======== DoorPi successfully shutdown ========")
        return True

    def restart(self):
        if self.destroy():
            self.run()
        else:
            raise DoorPiRestartException()

    def run(self):
        logger.debug("run")
        if not self.__prepared:
            self.prepare(self.__parsed_arguments)

        self.event_handler.fire_event("BeforeStartup", __name__)
        self.event_handler.fire_event_synchron("OnStartup", __name__)
        self.event_handler.fire_event("AfterStartup", __name__)

        # self.event_handler.register_action('OnTimeMinuteUnevenNumber', 'doorpi_restart')

        logger.info("DoorPi started successfully")
        logger.info("BasePath is %s", self.base_path)
        if self.__webserver:
            logger.info("Weburl is %s", self.__webserver.own_url)
        else:
            logger.info("no Webserver loaded")

        time_ticks = 0

        while True and not self.__shutdown:
            time_ticks += 0.05
            self.check_time_critical_threads()
            if time_ticks > 0.5:
                self.__last_tick = time.time()
                self.__event_handler.fire_event_asynchron("OnTimeTick", __name__)
                time_ticks = 0
            time.sleep(0.05)
        return self

    def check_time_critical_threads(self):
        if self.sipphone:
            self.sipphone.self_check()

    def parse_string(self, input_string):
        parsed_string = datetime.datetime.now().strftime(str(input_string))

        if self.keyboard is None or self.keyboard.last_key is None:
            self.additional_informations["LastKey"] = "NotSetYet"
        else:
            self.additional_informations["LastKey"] = str(self.keyboard.last_key)

        infos_as_html = "<table>"
        for key in self.additional_informations.keys():
            infos_as_html += "<tr><td>"
            infos_as_html += "<b>" + key + "</b>"
            infos_as_html += "</td><td>"
            infos_as_html += (
                "<i>" + cgi.escape(str(self.additional_informations.get(key)).replace("\r\n", "<br />")) + "</i>"
            )
            infos_as_html += "</td></tr>"
        infos_as_html += "</table>"

        mapping_table = {
            "INFOS_PLAIN": str(self.additional_informations),
            "INFOS": infos_as_html,
            "BASEPATH": self.base_path,
            "last_tick": str(self.__last_tick),
        }

        if self.keyboard and "KeyboardHandler" not in self.keyboard.name:
            for output_pin in self.config.get_keys("OutputPins", log=False):
                mapping_table[self.config.get("OutputPins", output_pin, log=False)] = output_pin
        elif self.keyboard and "KeyboardHandler" in self.keyboard.name:
            for outputpin_section in self.config.get_sections("_OutputPins", False):
                for output_pin in self.config.get_keys(outputpin_section, log=False):
                    mapping_table[self.config.get(outputpin_section, output_pin, log=False)] = output_pin

        for key in mapping_table.keys():
            parsed_string = parsed_string.replace("!" + key + "!", mapping_table[key])

        for key in self.additional_informations.keys():
            parsed_string = parsed_string.replace("!" + key + "!", str(self.additional_informations[key]))

        return parsed_string
Exemplo n.º 7
0
    def prepare(self, parsed_arguments):
        logger.debug("prepare")
        logger.debug("given arguments argv: %s", parsed_arguments)

        self.__config = ConfigObject.load_config(parsed_arguments.configfile)
        self._base_path = self.config.get("DoorPi", "base_path", self.base_path)
        self.__event_handler = EventHandler()

        if self.config.config_file is None:
            self.event_handler.register_action("AfterStartup", self.config.save_config)
            self.config.get("EVENT_OnStartup", "10", "sleep:1")

        if "test" in parsed_arguments and parsed_arguments.test is True:
            logger.warning("using only test-mode and destroy after 5 seconds")
            self.event_handler.register_action("AfterStartup", DoorPiShutdownAction(self.doorpi_shutdown))

        # register own events
        self.event_handler.register_event("BeforeStartup", __name__)
        self.event_handler.register_event("OnStartup", __name__)
        self.event_handler.register_event("AfterStartup", __name__)
        self.event_handler.register_event("BeforeShutdown", __name__)
        self.event_handler.register_event("OnShutdown", __name__)
        self.event_handler.register_event("AfterShutdown", __name__)
        self.event_handler.register_event("OnTimeTick", __name__)
        self.event_handler.register_event("OnTimeTickRealtime", __name__)

        # register base actions
        self.event_handler.register_action("OnTimeTick", "time_tick:!last_tick!")

        # register modules
        self.__webserver = load_webserver()
        self.__keyboard = load_keyboard()
        self.__sipphone = load_sipphone()
        self.sipphone.start()

        # register eventbased actions from configfile
        for event_section in self.config.get_sections("EVENT_"):
            logger.info("found EVENT_ section '%s' in configfile", event_section)
            event_name = event_section[len("EVENT_") :]
            for action in sorted(self.config.get_keys(event_section)):
                logger.info("registering action '%s' for event '%s'", action, event_name)
                self.event_handler.register_action(event_name, self.config.get(event_section, action))

        # register actions for inputpins
        if "KeyboardHandler" not in self.keyboard.name:
            section_name = "InputPins"
            for input_pin in sorted(self.config.get_keys(section_name)):
                self.event_handler.register_action(
                    "OnKeyPressed_" + input_pin, self.config.get(section_name, input_pin)
                )
        else:
            for keyboard_name in self.keyboard.loaded_keyboards:
                section_name = keyboard_name + "_InputPins"
                for input_pin in self.config.get_keys(section_name, log=False):
                    self.event_handler.register_action(
                        "OnKeyPressed_" + keyboard_name + "." + input_pin, self.config.get(section_name, input_pin)
                    )

        # register actions for DTMF
        section_name = "DTMF"
        for DTMF in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action("OnDTMF_" + DTMF, self.config.get(section_name, DTMF))

        # register keep_alive_led
        is_alive_led = self.config.get("DoorPi", "is_alive_led", "")
        if is_alive_led is not "":
            self.event_handler.register_action("OnTimeSecondEvenNumber", "out:%s,HIGH,False" % is_alive_led)
            self.event_handler.register_action("OnTimeSecondUnevenNumber", "out:%s,LOW,False" % is_alive_led)

        self.__prepared = True
        return self
Exemplo n.º 8
0
class DoorPi(object):
    __metaclass__ = Singleton

    __prepared = False

    __config = None
    @property
    def config(self): return self.__config

    __keyboard = None
    @property
    def keyboard(self): return self.__keyboard
    #def get_keyboard(self): return self.__keyboard

    __sipphone = None
    @property
    def sipphone(self): return self.__sipphone

    @property
    def additional_informations(self):
        if self.event_handler is None: return {}
        else: return self.event_handler.additional_informations

    __event_handler = None
    @property
    def event_handler(self): return self.__event_handler

    __webserver = None
    @property
    def webserver(self): return self.__webserver

    @property
    def status(self): return DoorPiStatus(self)

    @property
    def base_path(self): return os.path.dirname(__file__)

    @property
    def epilog(self): return metadata.epilog

    __shutdown = False
    @property
    def shutdown(self): return self.__shutdown

    @property
    def base_path(self): return metadata.base_path

    def __init__(self, parsed_arguments = None):
        self.__parsed_arguments = parsed_arguments
        # for start as daemon - if start as app it will not matter to load this vars
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/null'
        self.stderr_path = '/dev/null'
        self.pidfile_path =  '/var/run/doorpi.pid'
        self.pidfile_timeout = 5

        self.__last_tick = time.time()

    def prepare(self, parsed_arguments):
        logger.debug("prepare")
        logger.debug("givven arguments argv: %s", parsed_arguments)

        if not parsed_arguments.configfile and not self.config:
            raise Exception("no config exists an no new given")

        self.__event_handler = EventHandler()

        self.__config = ConfigObject.load_config(parsed_arguments.configfile)
        self.__keyboard = load_keyboard()
        logger.debug('Keyboard is now %s', self.keyboard.name)
        self.__sipphone = load_sipphone()
        self.sipphone.start()

        #register own events
        self.event_handler.register_event('OnStartup', __name__)
        self.event_handler.register_event('OnShutdown', __name__)

        # register eventbased actions from configfile
        for event_section in self.config.get_sections('EVENT_'):
            event_name = event_section[len('EVENT_'):]
            for action in sorted(self.config.get_keys(event_section)):
                self.event_handler.register_action(event_name, self.config.get(event_section, action))

        # register actions for inputpins
        section_name = 'InputPins'
        for input_pin in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action('OnKeyPressed_'+input_pin, self.config.get(section_name, input_pin))

        # register actions for DTMF
        section_name = 'DTMF'
        for DTMF in sorted(self.config.get_keys(section_name)):
            self.event_handler.register_action('OnDTMF_'+DTMF, self.config.get(section_name, DTMF))

        # register keep_alive_led
        is_alive_led = self.config.get('DoorPi', 'is_alive_led', None)
        if is_alive_led is not None:
            self.event_handler.register_action('OnTimeSecondEvenNumber', 'out:%s,HIGH,False'%is_alive_led)
            self.event_handler.register_action('OnTimeSecondUnevenNumber', 'out:%s,LOW,False'%is_alive_led)

        self.__prepared = True
        return self

    def __del__(self):
        return self.destroy()

    def destroy(self):
        try:
            if self.__prepared is not True: return False
            logger.debug('destroy')
            self.__shutdown = True
            if self.event_handler is not None:
                self.event_handler.fire_event_synchron('OnShutdown', __name__)

            if self.keyboard is not None:
                self.keyboard.destroy()

            if self.sipphone is not None:
                self.sipphone.destroy()

            if self.event_handler is not None:
                timeout = 2
                if not self.event_handler.idle:
                    logger.warning('wait for event_handler with runnig theards %s', self.event_handler.threads[1:])
                while not self.event_handler.idle and timeout > 0:
                    logger.info('wait %s seconds for theards %s', timeout, self.event_handler.threads[1:])
                    time.sleep(0.5)
                    timeout -= 0.5

                if timeout <= 0:
                    logger.error("waiting for theards timed out - there are still theards: %s", self.event_handler.threads[1:])

            if self.event_handler is not None:
                self.event_handler.unregister_source(__name__, True)
                self.event_handler.destroy()
                self.__event_handler = None
                del self.__event_handler

            self.__keyboard = None
            del self.__keyboard

            self.__sipphone = None
            del self.__sipphone

        except Exception as ex:
            logger.exception(ex)


    def run(self):
        logger.debug("run")
        if not self.__prepared: self.prepare(self.__parsed_arguments)

        self.event_handler.register_event('OnTimeTick', __name__)
        #self.event_handler.register_action('OnTimeTick', 'sleep:0.1')
        self.event_handler.register_action('OnTimeTick', 'time_tick:!last_tick!')
        self.event_handler.fire_event_asynchron('OnTimeTick', __name__)

        self.event_handler.fire_event_synchron('OnStartup', __name__)

        logger.info('DoorPi started successfully')
        logger.info('BasePath is %s', self.base_path)

        while True:
            self.__last_tick = time.time()
            self.__event_handler.fire_event_synchron('OnTimeTick', __name__)
            time.sleep(0.4)

        return self

    def parse_string(self, input_string):
        parsed_string = datetime.datetime.now().strftime(input_string)

        if self.keyboard is None or self.keyboard.last_key is None:
            self.additional_informations['LastKey'] = "NotSetYet"
        else:
            self.additional_informations['LastKey'] = str(self.keyboard.last_key)

        infos_as_html = '<table>'
        for key in self.additional_informations.keys():
            infos_as_html += '<tr><td>'
            infos_as_html += '<b>'+key+'</b>'
            infos_as_html += '</td><td>'
            infos_as_html += '<i>'+cgi.escape(
                str(self.additional_informations.get(key)).replace("\r\n", "<br />")
            )+'</i>'
            infos_as_html += '</td></tr>'
        infos_as_html += '</table>'

        mapping_table = {
            'INFOS_PLAIN':      str(self.additional_informations),
            'INFOS':            infos_as_html,
            'BASEPATH':         self.base_path,
            'last_tick':        str(self.__last_tick)
        }

        for key in mapping_table.keys():
            parsed_string = parsed_string.replace(
                "!"+key+"!",
                mapping_table[key]
            )

        for key in self.additional_informations.keys():
            parsed_string = parsed_string.replace(
                "!"+key+"!",
                str(self.additional_informations[key])
            )

        return parsed_string