def __init__(self, **kwargs): super(Event, self).__init__(**kwargs) Thread.__init__(self, name=Event) Utils.print_info('[Event] Starting manager') self.scheduler = BackgroundScheduler() self.list_synapses_with_event = list(super(Event, self).get_list_synapse()) self.load_events()
def __init__(self): super(Event, self).__init__() Utils.print_info('Starting event manager') self.scheduler = BackgroundScheduler() self.brain = BrainLoader().get_brain() self.synapses = self.brain.synapses self.load_events()
def start_kalliope(settings, brain): """ Start all signals declared in the brain """ # start kalliope Utils.print_success("Starting Kalliope") Utils.print_info("Press Ctrl+C for stopping") # catch signal for killing on Ctrl+C pressed signal.signal(signal.SIGINT, signal_handler) # get a list of signal class to load from declared synapse in the brain # this list will contain string of signal class type. # For example, if the brain contains multiple time the signal type "order", the list will be ["order"] # If the brain contains some synapse with "order" and "event", the list will be ["order", "event"] list_signals_class_to_load = get_list_signal_class_to_load(brain) # start each class name try: for signal_class_name in list_signals_class_to_load: signal_instance = SignalLauncher.launch_signal_class_by_name(signal_name=signal_class_name, settings=settings) if signal_instance is not None: signal_instance.daemon = True signal_instance.start() while True: # keep main thread alive time.sleep(0.1) except (KeyboardInterrupt, SystemExit): # we need to switch GPIO pin to default status if we are using a Rpi if settings.rpi_settings: Utils.print_info("GPIO cleaned") logger.debug("Clean GPIO") import RPi.GPIO as GPIO GPIO.cleanup()
def load_events(self): """ For each received synapse that have an event as signal, we add a new job scheduled to launch the synapse :return: """ for synapse in self.synapses: for signal in synapse.signals: # if the signal is an event we add it to the task list if signal.name == "event": if self.check_event_dict(signal.parameters): my_cron = CronTrigger( year=self.get_parameter_from_dict( "year", signal.parameters), month=self.get_parameter_from_dict( "month", signal.parameters), day=self.get_parameter_from_dict( "day", signal.parameters), week=self.get_parameter_from_dict( "week", signal.parameters), day_of_week=self.get_parameter_from_dict( "day_of_week", signal.parameters), hour=self.get_parameter_from_dict( "hour", signal.parameters), minute=self.get_parameter_from_dict( "minute", signal.parameters), second=self.get_parameter_from_dict( "second", signal.parameters), ) Utils.print_info( "Add synapse name \"%s\" to the scheduler: %s" % (synapse.name, my_cron)) self.scheduler.add_job(self.run_synapse_by_name, my_cron, args=[synapse.name])
def __init__(self, **kwargs): super(SignalModule, self).__init__() # get the child who called the class self.signal_name = self.__class__.__name__ Utils.print_info('Init Signal :' + self.signal_name) self.brain = BrainLoader().brain
def __init__(self, **kwargs): super(Event, self).__init__(**kwargs) Utils.print_info('[Event] Starting manager') self.scheduler = BackgroundScheduler() self.list_synapses_with_event = list( super(Event, self).get_list_synapse()) self.load_events()
def start_kalliope(settings, brain): """ Start all signals declared in the brain """ # start kalliope Utils.print_success("Starting Kalliope") Utils.print_info("Press Ctrl+C for stopping") # catch signal for killing on Ctrl+C pressed signal.signal(signal.SIGINT, signal_handler) # get a list of signal class to load from declared synapse in the brain # this list will contain string of signal class type. # For example, if the brain contains multiple time the signal type "order", the list will be ["order"] # If the brain contains some synapse with "order" and "event", the list will be ["order", "event"] list_signals_class_to_load = get_list_signal_class_to_load(brain) # start each class name for signal_class_name in list_signals_class_to_load: signal_instance = SignalLauncher.launch_signal_class_by_name( signal_name=signal_class_name, settings=settings) if signal_instance is not None: signal_instance.daemon = True signal_instance.start() while True: # keep main thread alive time.sleep(0.1)
def __init__(self, **kwargs): super(SignalModule, self).__init__(**kwargs) # get the child who called the class self.signal_name = self.__class__.__name__ Utils.print_info('Init Signal :' + self.signal_name) self.brain = BrainLoader().brain
def _add_event(self, period_string, event_id): """ Add a single event in the crontab. Will add a line like: <period_string> python /path/to/kalliope.py start --brain-file /path/to/brain.yml --run-synapse "<event_id>" E.g: 30 7 * * * python /home/me/kalliope/kalliope.py start --brain-file /home/me/brain.yml --run-synapse "Say-hello" :param period_string: crontab period :type period_string: str :param event_id: :type event_id: str :return: """ my_user_cron = CronTab(user=True) job = my_user_cron.new(command=self.base_command + " " + str("\"" + event_id + "\""), comment=CRONTAB_COMMENT) if CronSlices.is_valid(period_string): job.setall(period_string) job.enable() else: raise InvalidCrontabPeriod("The crontab period %s is not valid" % period_string) # write the file my_user_cron.write() Utils.print_info("Synapse \"%s\" added to the crontab" % event_id)
def __init__(self, **kwargs): super(Mqtt_subscriber, self).__init__(**kwargs) Thread.__init__(self, name=Mqtt_subscriber) Utils.print_info('[Mqtt_subscriber] Starting manager')# variables self.list_synapses_with_mqtt = list(super(Mqtt_subscriber, self).get_list_synapse()) self.broker_ip = None self.topic = None self.json_message = False
def __init__(self, **kwargs): super(Mqtt_subscriber, self).__init__(**kwargs) Utils.print_info('[Mqtt_subscriber] Starting manager') # variables self.list_synapses_with_mqtt = list( super(Mqtt_subscriber, self).get_list_synapse()) self.broker_ip = None self.topic = None self.json_message = False
def run_synapse_by_name(synapse_name): """ This method will run the synapse """ Utils.print_info("[Event] triggered, running synapse: %s" % synapse_name) # get a brain brain_loader = BrainLoader() brain = brain_loader.brain SynapseLauncher.start_synapse_by_list_name([synapse_name], brain=brain)
def run_synapse_by_name(synapse_name): """ This method will run the synapse """ Utils.print_info("Event triggered, running synapse: %s" % synapse_name) # get a brain brain_loader = BrainLoader() brain = brain_loader.brain SynapseLauncher.start_synapse(synapse_name, brain=brain)
def signal_handler(signal, frame): """ Used to catch a keyboard signal like Ctrl+C in order to kill the kalliope program :param signal: signal handler :param frame: execution frame """ print "\n" Utils.print_info("Ctrl+C pressed. Killing Kalliope") sys.exit(0)
def unpausing_trigger_process(self): """ If the trigger was in pause, this method will unpause it to listen again for the hotword """ logger.debug("Entering state: %s" % self.state) self.trigger_instance.unpause() self.trigger_callback_called = False Utils.print_info("Waiting for trigger detection") self.next_state()
def muted_button_pressed(self, muted=False): logger.debug( "[MainController] Mute button pressed. Switch trigger process to muted: %s" % muted) if muted: self.trigger_instance.pause() Utils.print_info("Kalliope now muted") else: self.trigger_instance.unpause() Utils.print_info("Kalliope now listening for trigger detection")
def waiting_for_trigger_callback_thread(self): """ Method to print in debug that the main process is waiting for a trigger detection """ logger.debug("[MainController] Entering state: %s" % self.state) Utils.print_info("Waiting for trigger detection") # this loop is used to keep the main thread alive while not self.trigger_callback_called: sleep(0.1) self.next_state()
def _start_rest_api(self): """ Start the Rest API if asked in the user settings """ # run the api if the user want it if self.settings.rest_api.active: Utils.print_info("Starting REST API Listening port: %s" % self.settings.rest_api.port) app = Flask(__name__) flask_api = FlaskAPI(app=app, port=self.settings.rest_api.port, brain=self.brain, allowed_cors_origin=self.settings.rest_api.allowed_cors_origin) flask_api.daemon = True flask_api.start()
def analyse_order(self, order): """ Receive an order, try to retrieve it in the brain.yml to launch to attached plugins :param order: the sentence received :type order: str """ if order is not None: # maybe we have received a null audio from STT engine order_analyser = OrderAnalyser(order, brain=self.brain) order_analyser.start() # restart the trigger when the order analyser has finish his job Utils.print_info("Waiting for trigger detection") self.trigger_instance.unpause() # create a new order listener that will wait for start self.order_listener = OrderListener(self.analyse_order)
def __init__(self, callback=None, **kwargs): """ Start recording the microphone and analyse audio with google api :param callback: The callback function to call to send the text :param kwargs: """ OrderListener.__init__(self) # callback function to call after the translation speech/tex self.callback = callback # obtain audio from the microphone r = sr.Recognizer() with sr.Microphone() as source: # listen for 1 second to calibrate the energy threshold for ambient noise levels r.adjust_for_ambient_noise(source) Utils.print_info("Say something!") audio = r.listen(source) # recognize speech using Google Speech Recognition try: # for testing purposes, we're just using the default API key # to use another API key, use `r.recognize_google(audio, key="GOOGLE_SPEECH_RECOGNITION_API_KEY")` # instead of `r.recognize_google(audio)` key = kwargs.get('key', None) language = kwargs.get('language', "en-US") show_all = kwargs.get('show_all', False) captured_audio = r.recognize_google(audio, key=key, language=language, show_all=show_all) Utils.print_success( "Google Speech Recognition thinks you said %s" % captured_audio) self._analyse_audio(captured_audio) except sr.UnknownValueError: Utils.print_warning( "Google Speech Recognition could not understand audio") # callback anyway, we need to listen again for a new order self._analyse_audio(audio=None) except sr.RequestError as e: Utils.print_danger( "Could not request results from Google Speech Recognition service; {0}" .format(e)) # callback anyway, we need to listen again for a new order self._analyse_audio(audio=None)
def __init__(self, callback=None, **kwargs): """ Start recording the microphone and analyse audio with Houndify api :param callback: The callback function to call to send the text :param kwargs: """ OrderListener.__init__(self) # callback function to call after the translation speech/tex self.callback = callback # obtain audio from the microphone r = sr.Recognizer() with sr.Microphone() as source: # listen for 1 second to calibrate the energy threshold for ambient noise levels r.adjust_for_ambient_noise(source) Utils.print_info("Say something!") audio = r.listen(source) # recognize speech using Houndify Speech Recognition try: client_id = kwargs.get('client_id', None) key = kwargs.get('key', None) language = kwargs.get('language', "en-US") show_all = kwargs.get('show_all', False) captured_audio = r.recognize_houndify(audio, client_id=client_id, client_key=key, language=language, show_all=show_all) Utils.print_success( "Houndify Speech Recognition thinks you said %s" % captured_audio) self._analyse_audio(captured_audio) except sr.UnknownValueError: Utils.print_warning( "Houndify Speech Recognition could not understand audio") # callback anyway, we need to listen again for a new order self._analyse_audio(audio=None) except sr.RequestError as e: Utils.print_danger( "Could not request results from Houndify Speech Recognition service; {0}" .format(e)) # callback anyway, we need to listen again for a new order self._analyse_audio(audio=None)
def load_events(self): """ For each received synapse that have an event as signal, we add a new job scheduled to launch the synapse :return: """ for synapse in self.synapses: for signal in synapse.signals: # if the signal is an event we add it to the task list if type(signal) == Event: my_cron = CronTrigger(year=signal.year, month=signal.month, day=signal.day, week=signal.week, day_of_week=signal.day_of_week, hour=signal.hour, minute=signal.minute, second=signal.second) Utils.print_info("Add synapse name \"%s\" to the scheduler: %s" % (synapse.name, my_cron)) self.scheduler.add_job(self.run_synapse_by_name, my_cron, args=[synapse.name])
def load_events(self): """ For each received synapse that have an event as signal, we add a new job scheduled to launch the synapse """ for synapse in self.list_synapses_with_event: for signal in synapse.signals: # We need to loop here again if the synapse has multiple event signals. # if the signal is an event we add it to the task list. if signal.name == "event": my_cron = CronTrigger(year=self.get_parameter_from_dict("year", signal.parameters), month=self.get_parameter_from_dict("month", signal.parameters), day=self.get_parameter_from_dict("day", signal.parameters), week=self.get_parameter_from_dict("week", signal.parameters), day_of_week=self.get_parameter_from_dict("day_of_week", signal.parameters), hour=self.get_parameter_from_dict("hour", signal.parameters), minute=self.get_parameter_from_dict("minute", signal.parameters), second=self.get_parameter_from_dict("second", signal.parameters), ) Utils.print_info("Add synapse name \"%s\" to the scheduler: %s" % (synapse.name, my_cron)) self.scheduler.add_job(self.run_synapse_by_name, my_cron, args=[synapse.name])
def __init__(self, brain=None): self.brain = brain # get global configuration sl = SettingLoader.Instance() self.settings = sl.settings # run the api if the user want it if self.settings.rest_api.active: Utils.print_info("Starting REST API Listening port: %s" % self.settings.rest_api.port) app = Flask(__name__) flask_api = FlaskAPI(app, port=self.settings.rest_api.port, brain=self.brain) flask_api.daemon = True flask_api.start() # create an order listener object. This last will the trigger callback before starting self.order_listener = OrderListener(self.analyse_order) # Wait that the kalliope trigger is pronounced by the user self.trigger_instance = self._get_default_trigger() self.trigger_instance.start() Utils.print_info("Waiting for trigger detection")
def __init__(self, synapses): Utils.print_info('Starting event manager') self.scheduler = BackgroundScheduler() self.synapses = synapses self.load_events() self.scheduler.start()
def main(): """ Entry point of Kalliope program """ # create arguments parser = argparse.ArgumentParser(description='Kalliope') parser.add_argument("action", help="[start|gui]") parser.add_argument("--run-synapse", help="Name of a synapse to load surrounded by quote") parser.add_argument("--brain-file", help="Full path of a brain file") parser.add_argument("--debug", action='store_true', help="Show debug output") # parse arguments from script parameters args = parser.parse_args() # require at least one parameter, the action if len(sys.argv[1:]) == 0: parser.print_usage() sys.exit(1) # check if we want debug configure_logging(debug=args.debug) logger.debug("kalliope args: %s" % args) # by default, no brain file is set. Use the default one: brain.yml in the root path brain_file = None # check if user set a brain.yml file if args.brain_file: brain_file = args.brain_file # load the brain once brain_loader = BrainLoader.Instance(file_path=brain_file) brain = brain_loader.brain # check the user provide a valid action if args.action not in ACTION_LIST: Utils.print_warning("%s is not a recognised action\n" % args.action) parser.print_help() if args.action == "start": # user set a synapse to start if args.run_synapse is not None: SynapseLauncher.start_synapse(args.run_synapse, brain=brain) if args.run_synapse is None: # first, load events in crontab crontab_manager = CrontabManager(brain=brain) crontab_manager.load_events_in_crontab() Utils.print_success("Events loaded in crontab") # then start kalliope Utils.print_success("Starting Kalliope") Utils.print_info("Press Ctrl+C for stopping") # catch signal for killing on Ctrl+C pressed signal.signal(signal.SIGINT, signal_handler) # start the main controller MainController(brain=brain) if args.action == "gui": ShellGui(brain=brain)
def main(): """Entry point of Kalliope program.""" # parse argument. the script name is removed try: parser = parse_args(sys.argv[1:]) except SystemExit: sys.exit(1) # check if we want debug configure_logging(debug=parser.debug) logger.debug("kalliope args: %s" % parser) # by default, no brain file is set. # Use the default one: brain.yml in the root path brain_file = None # check if user set a brain.yml file if parser.brain_file: brain_file = parser.brain_file # check the user provide a valid action if parser.action not in ACTION_LIST: Utils.print_warning("%s is not a recognised action\n" % parser.action) sys.exit(1) # install modules if parser.action == "install": if not parser.git_url: Utils.print_danger("You must specify the git url") sys.exit(1) else: parameters = {"git_url": parser.git_url} res_manager = ResourcesManager(**parameters) res_manager.install() return # uninstall modules if parser.action == "uninstall": if not parser.neuron_name \ and not parser.stt_name \ and not parser.tts_name \ and not parser.trigger_name\ and not parser.signal_name: Utils.print_danger("You must specify a module name with " "--neuron-name " "or --stt-name " "or --tts-name " "or --trigger-name " "or --signal-name") sys.exit(1) else: res_manager = ResourcesManager() res_manager.uninstall(neuron_name=parser.neuron_name, stt_name=parser.stt_name, tts_name=parser.tts_name, trigger_name=parser.trigger_name, signal_name=parser.signal_name) return # load the brain once brain_loader = BrainLoader(file_path=brain_file) brain = brain_loader.brain # load settings # get global configuration once settings_loader = SettingLoader() settings = settings_loader.settings if parser.action == "start": # user set a synapse to start if parser.run_synapse is not None: SynapseLauncher.start_synapse_by_name(parser.run_synapse, brain=brain) if parser.run_order is not None: SynapseLauncher.run_matching_synapse_from_order(parser.run_order, brain=brain, settings=settings, is_api_call=False) if (parser.run_synapse is None) and (parser.run_order is None): # if --muted if parser.muted: settings.start_options['muted'] = True # start rest api start_rest_api(settings, brain) start_kalliope(settings, brain) if parser.action == "gui": try: ShellGui(brain=brain) except (KeyboardInterrupt, SystemExit): Utils.print_info("Ctrl+C pressed. Killing Kalliope") sys.exit(0)
def main(): """Entry point of Kalliope program.""" # parse argument. the script name is removed try: parser = parse_args(sys.argv[1:]) except SystemExit: sys.exit(1) # check if we want debug configure_logging(debug=parser.debug) logger.debug("kalliope args: %s" % parser) # by default, no brain file is set. # Use the default one: brain.yml in the root path brain_file = None # check if user set a brain.yml file if parser.brain_file: brain_file = parser.brain_file # check the user provide a valid action if parser.action not in ACTION_LIST: Utils.print_warning("%s is not a recognised action\n" % parser.action) sys.exit(1) # install modules if parser.action == "install": if not parser.git_url: Utils.print_danger("You must specify the git url") sys.exit(1) else: parameters = {"git_url": parser.git_url} res_manager = ResourcesManager(**parameters) res_manager.install() return # uninstall modules if parser.action == "uninstall": if not parser.neuron_name and not parser.stt_name and not parser.tts_name and not parser.trigger_name: Utils.print_danger( "You must specify a module name with --neuron-name or --stt-name or --tts-name " "or --trigger-name") sys.exit(1) else: res_manager = ResourcesManager() res_manager.uninstall(neuron_name=parser.neuron_name, stt_name=parser.stt_name, tts_name=parser.tts_name, trigger_name=parser.trigger_name) return # load the brain once brain_loader = BrainLoader(file_path=brain_file) brain = brain_loader.brain # load settings # get global configuration once settings_loader = SettingLoader() settings = settings_loader.settings if parser.action == "start": if settings.rpi_settings: # init GPIO once RpiUtils(settings.rpi_settings) # user set a synapse to start if parser.run_synapse is not None: SynapseLauncher.start_synapse_by_name(parser.run_synapse, brain=brain) if parser.run_order is not None: SynapseLauncher.run_matching_synapse_from_order(parser.run_order, brain=brain, settings=settings, is_api_call=False) if (parser.run_synapse is None) and (parser.run_order is None): # first, load events in event manager EventManager(brain.synapses) Utils.print_success("Events loaded") # then start kalliope Utils.print_success("Starting Kalliope") Utils.print_info("Press Ctrl+C for stopping") # catch signal for killing on Ctrl+C pressed signal.signal(signal.SIGINT, signal_handler) # start the state machine try: MainController(brain=brain) except (KeyboardInterrupt, SystemExit): Utils.print_info("Ctrl+C pressed. Killing Kalliope") finally: # we need to switch GPIO pin to default status if we are using a Rpi if settings.rpi_settings: logger.debug("Clean GPIO") import RPi.GPIO as GPIO GPIO.cleanup() if parser.action == "gui": try: ShellGui(brain=brain) except (KeyboardInterrupt, SystemExit): Utils.print_info("Ctrl+C pressed. Killing Kalliope") sys.exit(0)
def main(): """Entry point of Kalliope program.""" # create arguments parser = argparse.ArgumentParser(description='Kalliope') parser.add_argument("action", help="[start|gui|install|uninstall]") parser.add_argument("--run-synapse", help="Name of a synapse to load surrounded by quote") parser.add_argument("--run-order", help="order surrounded by a quote") parser.add_argument("--brain-file", help="Full path of a brain file") parser.add_argument("--debug", action='store_true', help="Show debug output") parser.add_argument("--git-url", help="Git URL of the neuron to install") parser.add_argument("--neuron-name", help="Neuron name to uninstall") parser.add_argument("--stt-name", help="STT name to uninstall") parser.add_argument("--tts-name", help="TTS name to uninstall") parser.add_argument("--trigger-name", help="Trigger name to uninstall") parser.add_argument('-v', '--version', action='version', version='Kalliope ' + version_str) # parse arguments from script parameters args = parser.parse_args() # require at least one parameter, the action if len(sys.argv[1:]) == 0: parser.print_usage() sys.exit(1) # check if we want debug configure_logging(debug=args.debug) logger.debug("kalliope args: %s" % args) # by default, no brain file is set. # Use the default one: brain.yml in the root path brain_file = None # check if user set a brain.yml file if args.brain_file: brain_file = args.brain_file # check the user provide a valid action if args.action not in ACTION_LIST: Utils.print_warning("%s is not a recognised action\n" % args.action) parser.print_help() # install modules if args.action == "install": if not args.git_url: Utils.print_danger("You must specify the git url") else: parameters = {"git_url": args.git_url} res_manager = ResourcesManager(**parameters) res_manager.install() return # uninstall modules if args.action == "uninstall": if not args.neuron_name and not args.stt_name and not args.tts_name and not args.trigger_name: Utils.print_danger( "You must specify a module name with --neuron-name or --stt-name or --tts-name " "or --trigger-name") else: res_manager = ResourcesManager() res_manager.uninstall(neuron_name=args.neuron_name, stt_name=args.stt_name, tts_name=args.tts_name, trigger_name=args.trigger_name) return # load the brain once brain_loader = BrainLoader(file_path=brain_file) brain = brain_loader.brain if args.action == "start": # user set a synapse to start if args.run_synapse is not None: SynapseLauncher.start_synapse(args.run_synapse, brain=brain) if args.run_order is not None: order_analyser = OrderAnalyser(args.run_order, brain=brain) order_analyser.start() if (args.run_synapse is None) and (args.run_order is None): # first, load events in event manager EventManager(brain.synapses) Utils.print_success("Events loaded") # then start kalliope Utils.print_success("Starting Kalliope") Utils.print_info("Press Ctrl+C for stopping") # catch signal for killing on Ctrl+C pressed signal.signal(signal.SIGINT, signal_handler) # start the state machine MainController(brain=brain) if args.action == "gui": ShellGui(brain=brain)