def call_concerned_synapses(self, topic_name, message): """ Call synapse launcher class for each synapse concerned by the subscribed topic convert the message to json if needed before. The synapse is loaded with a parameter called "mqtt_subscriber_message" that can be used in neurons :param topic_name: name of the topic that received a message from the broker :param message: string message received from the broker """ # find concerned topic by name target_topic = next(topic for topic in self.broker.topics if topic.name == topic_name) # convert payload to a dict if necessary if target_topic.is_json: message = json.loads(message) logger.debug( "[MqttClient] Payload message converted to JSON dict: %s" % message) else: logger.debug("[MqttClient] Payload message is plain text: %s" % message) # run each synapse for synapse in target_topic.synapses: logger.debug("[MqttClient] start synapse name %s" % synapse.name) overriding_parameter_dict = dict() overriding_parameter_dict["mqtt_subscriber_message"] = message SynapseLauncher.start_synapse_by_name( synapse.name, brain=self.brain, overriding_parameter_dict=overriding_parameter_dict)
def audio_analyser_callback(self, order): """ Callback of the OrderListener. Called after the processing of the audio file This method will - call the Order Analyser to analyse the order and launch corresponding synapse as usual. - get a list of launched synapse. - give the list to the main process via self.launched_synapses - notify that the processing is over via order_analyser_return :param order: string order to analyse :return: """ logger.debug("order to process %s" % order) if order is not None: # maybe we have received a null audio from STT engine order_analyser = OrderAnalyser(order, brain=self.brain) synapses_launched = order_analyser.start() self.launched_synapses = synapses_launched else: if self.settings.default_synapse is not None: SynapseLauncher.start_synapse( name=self.settings.default_synapse, brain=self.brain) self.launched_synapses = self.brain.get_synapse_by_name( synapse_name=self.settings.default_synapse) # this boolean will notify the main process that the order have been processed self.order_analyser_return = True
def call_concerned_synapses(self, topic_name, message): """ Call synapse launcher class for each synapse concerned by the subscribed topic convert the message to json if needed before. The synapse is loaded with a parameter called "mqtt_subscriber_message" that can be used in neurons :param topic_name: name of the topic that received a message from the broker :param message: string message received from the broker """ # find concerned topic by name target_topic = next(topic for topic in self.broker.topics if topic.name == topic_name) # convert payload to a dict if necessary if target_topic.is_json: message = json.loads(message) logger.debug("[MqttClient] Payload message converted to JSON dict: %s" % message) else: logger.debug("[MqttClient] Payload message is plain text: %s" % message) # run each synapse for synapse in target_topic.synapses: logger.debug("[MqttClient] start synapse name %s" % synapse.name) overriding_parameter_dict = dict() overriding_parameter_dict["mqtt_subscriber_message"] = message SynapseLauncher.start_synapse_by_list_name([synapse.name], brain=self.brain, overriding_parameter_dict=overriding_parameter_dict)
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 test_start_synapse_by_list_name_single_synapse(self): # existing synapse in the brain with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): should_be_created_matched_synapse = MatchedSynapse( matched_synapse=self.synapse1) SynapseLauncher.start_synapse_by_list_name(["Synapse1"], brain=self.brain_test) # we expect that the lifo has been loaded with the synapse to run expected_result = [[should_be_created_matched_synapse]] lifo_buffer = LifoManager.get_singleton_lifo() self.assertEqual(expected_result, lifo_buffer.lifo_list) # we expect that the lifo has been loaded with the synapse to run and overwritten parameters Singleton._instances = dict() LifoManager.clean_saved_lifo() lifo_buffer = LifoManager.get_singleton_lifo() overriding_param = {"val1": "val"} SynapseLauncher.start_synapse_by_list_name( ["Synapse1"], brain=self.brain_test, overriding_parameter_dict=overriding_param) should_be_created_matched_synapse = MatchedSynapse( matched_synapse=self.synapse1, overriding_parameter=overriding_param) # we expect that the lifo has been loaded with the synapse to run expected_result = [[should_be_created_matched_synapse]] self.assertEqual(expected_result, lifo_buffer.lifo_list) # non existing synapse in the brain with self.assertRaises(SynapseNameNotFound): SynapseLauncher.start_synapse_by_list_name(["not_existing"], brain=self.brain_test) # check that the cortex is well loaded with temp parameter from a signal with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): overriding_parameter_dict = {"parameter1": "value1"} with mock.patch( "kalliope.core.Cortex.Cortex.add_parameters_from_order" ) as cortex_mock: SynapseLauncher.start_synapse_by_list_name( ["Synapse1"], brain=self.brain_test, overriding_parameter_dict=overriding_parameter_dict) cortex_mock.assert_called_with(overriding_parameter_dict) # check disable synapse is not run self.synapse4.enabled = False LifoManager.clean_saved_lifo() with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): SynapseLauncher.start_synapse_by_list_name(["Synapse4"], brain=self.brain_test) # we expect that the lifo has NOT been loaded with the disabled synapse expected_result = [[]] lifo_buffer = LifoManager.get_singleton_lifo() self.assertEqual(expected_result, lifo_buffer.lifo_list)
def analysing_order_thread(self): """ Start the order analyser with the caught order to process """ logger.debug("[MainController] order in analysing_order_thread %s" % self.order_to_process) SynapseLauncher.run_matching_synapse_from_order(self.order_to_process, self.brain, self.settings, is_api_call=False) # return to the state "unpausing_trigger" self.start_trigger()
def test_start_synapse(self): """ Test the Synapse launcher trying to start synapse """ # Init neuron1 = Neuron(name='neurone1', parameters={'var1': 'val1'}) neuron2 = Neuron(name='neurone2', parameters={'var2': 'val2'}) neuron3 = Neuron(name='neurone3', parameters={'var3': 'val3'}) neuron4 = Neuron(name='neurone4', parameters={'var4': 'val4'}) signal1 = Order(sentence="this is the sentence") signal2 = Order(sentence="this is the second sentence") signal3 = Order(sentence="that is part of the third sentence") synapse1 = Synapse(name="Synapse1", neurons=[neuron1, neuron2], signals=[signal1]) synapse2 = Synapse(name="Synapse2", neurons=[neuron3, neuron4], signals=[signal2]) synapse3 = Synapse(name="Synapse3", neurons=[neuron2, neuron4], signals=[signal3]) all_synapse_list = [synapse1, synapse2, synapse3] br = Brain(synapses=all_synapse_list) sl = SettingLoader() r = Resources(neuron_folder="/var/tmp/test/resources") sl.settings.resources = r with mock.patch("kalliope.core.Utils.get_dynamic_class_instantiation" ) as mock_get_class_instantiation: # Success SynapseLauncher.start_synapse("Synapse1", brain=br) calls = [ mock.call(package_name="neurons", module_name=neuron1.name, parameters=neuron1.parameters, resources_dir='/var/tmp/test/resources'), mock.call(package_name="neurons", module_name=neuron2.name, parameters=neuron2.parameters, resources_dir='/var/tmp/test/resources') ] mock_get_class_instantiation.assert_has_calls(calls=calls) mock_get_class_instantiation.reset_mock() # Fail with self.assertRaises(SynapseNameNotFound): SynapseLauncher.start_synapse("Synapse4", brain=br)
def analysing_order_thread(self): """ Start the order analyser with the caught order to process """ logger.debug("order in analysing_order_thread %s" % self.order_to_process) if self.order_to_process is not None: # maybe we have received a null audio from STT engine order_analyser = OrderAnalyser(self.order_to_process, brain=self.brain) order_analyser.start() else: if self.settings.default_synapse is not None: SynapseLauncher.start_synapse(name=self.settings.default_synapse, brain=self.brain) # return to the state "unpausing_trigger" self.unpause_trigger()
def run(self): logger.debug("[NFC_Reader] Starting thread ...") self.reader = SimpleMFRC522.SimpleMFRC522() try: while True: user_id = reader.read() for synapse in self.synapse_list: SynapseLauncher.start_synapse_by_list_name([synapse], args=[user_id]) time.sleep(0.1) except KeyboardInterrupt: finally: GPIO.cleanup()
def test_start_synapse_by_name(self): # existing synapse in the brain with mock.patch("kalliope.core.LIFOBuffer.execute"): should_be_created_matched_synapse = MatchedSynapse( matched_synapse=self.synapse1) SynapseLauncher.start_synapse_by_name("Synapse1", brain=self.brain_test) # we expect that the lifo has been loaded with the synapse to run expected_result = [[should_be_created_matched_synapse]] self.assertEqual(expected_result, LIFOBuffer.lifo_list) # non existing synapse in the brain with self.assertRaises(SynapseNameNotFound): SynapseLauncher.start_synapse_by_name("not_existing", brain=self.brain_test)
def run_synapse_by_order(self): """ Give an order to Kalliope via API like it was from a spoken one Test with curl curl -i --user admin:secret -H "Content-Type: application/json" -X POST -d '{"order":"my order"}' http://localhost:5000/synapses/start/order In case of quotes in the order or accents, use a file cat post.json: {"order":"j'aime"} curl -i --user admin:secret -H "Content-Type: application/json" -X POST --data @post.json http://localhost:5000/order/ :return: """ if not request.get_json() or 'order' not in request.get_json(): abort(400) order = request.get_json('order') if order is not None: # get the order order_to_run = order["order"] api_response = SynapseLauncher.run_matching_synapse_from_order( order_to_run, self.brain, self.settings, is_api_call=True) data = jsonify(api_response) return data, 201 else: data = {"error": "order cannot be null"} return jsonify(error=data), 400
def analysing_order_thread(self): """ Start the order analyser with the caught order to process """ if self.order_to_process is None or self.order_to_process == "": logger.debug("[Order] No audio caught from analysing_order_thread") HookManager.on_stt_error() else: logger.debug("[Order] order in analysing_order_thread %s" % self.order_to_process) SynapseLauncher.run_matching_synapse_from_order(self.order_to_process, self.brain, self.settings, is_api_call=False) if self.skip_trigger: self.start_order_listener() else: self.unpause_trigger()
def analysing_order_thread(self): """ Start the order analyser with the caught order to process """ if self.order_to_process is None or self.order_to_process == "": logger.debug("[Order] No audio caught from analysing_order_thread") HookManager.on_stt_error() else: logger.debug("[Order] order in analysing_order_thread %s" % self.order_to_process) SynapseLauncher.run_matching_synapse_from_order(self.order_to_process, self.brain, self.settings, is_api_call=False) if self.skip_trigger: self.start_order_listener() else: self.start_trigger()
def run_synapse_by_name(self, synapse_name): """ Run a synapse by its name test with curl: curl -i --user admin:secret -X POST http://127.0.0.1:5000/synapses/start/id/say-hello-fr :param synapse_name: :return: """ synapse_target = self._get_synapse_by_name(synapse_name) if synapse_target is None: data = {"synapse name not found": "%s" % synapse_name} return jsonify(error=data), 404 # run the synapse SynapseLauncher.start_synapse(synapse_name, brain=self.brain) data = jsonify(synapses=synapse_target.serialize()) return data, 201
def run_synapse_by_order(self): """ Give an order to Kalliope via API like it was from a spoken one Test with curl curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ -d '{"order":"my order"}' http://localhost:5000/synapses/start/order In case of quotes in the order or accents, use a file cat post.json: {"order":"j'aime"} curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ --data @post.json http://localhost:5000/order/ Can be used with mute flag curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ -d '{"order":"my order", "mute":"true"}' http://localhost:5000/synapses/start/order :return: """ if not request.get_json() or 'order' not in request.get_json(): data = { "Error": "Wrong parameters, 'order' not set" } return jsonify(error=data), 400 order = request.get_json('order') # Store the mute value, then apply depending of the request parameters old_mute_value = self.settings.options.mute mute = utils.get_value_flag_from_request(http_request=request, flag_to_find="mute", is_boolean=True) if mute is not None: SettingEditor.set_mute_status(mute=mute) if order is not None: # get the order order_to_run = order["order"] logger.debug("[FlaskAPI] run_synapse_by_order: order to run -> %s" % order_to_run) api_response = SynapseLauncher.run_matching_synapse_from_order(order_to_run, self.brain, self.settings, is_api_call=True) Cortex.save('kalliope_last_order', order_to_run) data = jsonify(api_response) if mute is not None: SettingEditor.set_mute_status(mute=old_mute_value) return data, 201 else: data = { "error": "order cannot be null" } if mute is not None: SettingEditor.set_mute_status(mute=old_mute_value) return jsonify(error=data), 400
def run_synapse_by_order(self): """ Give an order to Kalliope via API like it was from a spoken one Test with curl curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ -d '{"order":"my order"}' http://localhost:5000/synapses/start/order In case of quotes in the order or accents, use a file cat post.json: {"order":"j'aime"} curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ --data @post.json http://localhost:5000/order/ Can be used with mute flag curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ -d '{"order":"my order", "mute":"true"}' http://localhost:5000/synapses/start/order :return: """ if not request.get_json() or 'order' not in request.get_json(): data = { "Error": "Wrong parameters, 'order' not set" } return jsonify(error=data), 400 order = request.get_json('order') # Store the mute value, then apply depending of the request parameters old_mute_value = self.settings.options.mute mute = self.get_value_flag_from_request(http_request=request, flag_to_find="mute", is_boolean=True) if mute is not None: SettingEditor.set_mute_status(mute=mute) if order is not None: # get the order order_to_run = order["order"] logger.debug("[FlaskAPI] run_synapse_by_order: order to run -> %s" % order_to_run) api_response = SynapseLauncher.run_matching_synapse_from_order(order_to_run, self.brain, self.settings, is_api_call=True) data = jsonify(api_response) if mute is not None: SettingEditor.set_mute_status(mute=old_mute_value) return data, 201 else: data = { "error": "order cannot be null" } if mute is not None: SettingEditor.set_mute_status(mute=old_mute_value) return jsonify(error=data), 400
def show_synapses_test_menu(self): """ Show a list of available synapse in the brain to run it directly """ # create a tuple for the list menu choices = list() x = 0 for el in self.brain.synapses: tup = (str(el.name), str(x)) choices.append(tup) x += 1 code, tag = self.d.menu("Select a synapse to run", choices=choices) if code == self.d.CANCEL: self.show_main_menu() if code == self.d.OK: logger.debug("Run synapse from GUI: %s" % tag) SynapseLauncher.start_synapse(tag, brain=self.brain) self.show_synapses_test_menu()
def test_start_synapse_by_name(self): # existing synapse in the brain with mock.patch("kalliope.core.LIFOBuffer.execute"): should_be_created_matched_synapse = MatchedSynapse( matched_synapse=self.synapse1) SynapseLauncher.start_synapse_by_name("Synapse1", brain=self.brain_test) # we expect that the lifo has been loaded with the synapse to run expected_result = [[should_be_created_matched_synapse]] lifo_buffer = LIFOBuffer() self.assertEqual(expected_result, lifo_buffer.lifo_list) # we expect that the lifo has been loaded with the synapse to run and overwritten parameters Singleton._instances = dict() lifo_buffer = LIFOBuffer() overriding_param = {"val1": "val"} SynapseLauncher.start_synapse_by_name( "Synapse1", brain=self.brain_test, overriding_parameter_dict=overriding_param) should_be_created_matched_synapse = MatchedSynapse( matched_synapse=self.synapse1, overriding_parameter=overriding_param) # we expect that the lifo has been loaded with the synapse to run expected_result = [[should_be_created_matched_synapse]] self.assertEqual(expected_result, lifo_buffer.lifo_list) # non existing synapse in the brain with self.assertRaises(SynapseNameNotFound): SynapseLauncher.start_synapse_by_name("not_existing", brain=self.brain_test)
def test_start_synapse_by_list_name_single_synapse(self): # existing synapse in the brain with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): should_be_created_matched_synapse = MatchedSynapse(matched_synapse=self.synapse1) SynapseLauncher.start_synapse_by_list_name(["Synapse1"], brain=self.brain_test) # we expect that the lifo has been loaded with the synapse to run expected_result = [[should_be_created_matched_synapse]] lifo_buffer = LifoManager.get_singleton_lifo() self.assertEqual(expected_result, lifo_buffer.lifo_list) # we expect that the lifo has been loaded with the synapse to run and overwritten parameters Singleton._instances = dict() LifoManager.clean_saved_lifo() lifo_buffer = LifoManager.get_singleton_lifo() overriding_param = { "val1": "val" } SynapseLauncher.start_synapse_by_list_name(["Synapse1"], brain=self.brain_test, overriding_parameter_dict=overriding_param) should_be_created_matched_synapse = MatchedSynapse(matched_synapse=self.synapse1, overriding_parameter=overriding_param) # we expect that the lifo has been loaded with the synapse to run expected_result = [[should_be_created_matched_synapse]] self.assertEqual(expected_result, lifo_buffer.lifo_list) # non existing synapse in the brain with self.assertRaises(SynapseNameNotFound): SynapseLauncher.start_synapse_by_list_name(["not_existing"], brain=self.brain_test)
def test_start_synapse_by_list_name(self): # test to start a list of synapse with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): created_matched_synapse1 = MatchedSynapse(matched_synapse=self.synapse1) created_matched_synapse2 = MatchedSynapse(matched_synapse=self.synapse2) expected_list_matched_synapse = [created_matched_synapse1, created_matched_synapse2] SynapseLauncher.start_synapse_by_list_name(["Synapse1", "Synapse2"], brain=self.brain_test) # we expect that the lifo has been loaded with the synapse to run expected_result = [expected_list_matched_synapse] lifo_buffer = LifoManager.get_singleton_lifo() self.maxDiff = None self.assertEqual(expected_result, lifo_buffer.lifo_list) # empty list should return none empty_list = list() self.assertIsNone(SynapseLauncher.start_synapse_by_list_name(empty_list)) # test to start a synapse list with a new lifo # we create a Lifo that is the current singleton Singleton._instances = dict() LifoManager.clean_saved_lifo() lifo_buffer = LifoManager.get_singleton_lifo() created_matched_synapse1 = MatchedSynapse(matched_synapse=self.synapse1) lifo_buffer.lifo_list = [created_matched_synapse1] # the current status of the singleton lifo should not move even after the call of SynapseLauncher expected_result = [created_matched_synapse1] # create a new call with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): SynapseLauncher.start_synapse_by_list_name(["Synapse2", "Synapse3"], brain=self.brain_test, new_lifo=True) # the current singleton should be the same self.assertEqual(expected_result, lifo_buffer.lifo_list) # test to start a synapse list with the singleton lifo Singleton._instances = dict() LifoManager.clean_saved_lifo() lifo_buffer = LifoManager.get_singleton_lifo() created_matched_synapse1 = MatchedSynapse(matched_synapse=self.synapse1) # place a synapse in the singleton lifo_buffer.lifo_list = [created_matched_synapse1] # the current status of the singleton lifo should contain synapse launched in the next call created_matched_synapse2 = MatchedSynapse(matched_synapse=self.synapse2) created_matched_synapse3 = MatchedSynapse(matched_synapse=self.synapse3) expected_result = [created_matched_synapse1, [created_matched_synapse2, created_matched_synapse3]] with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): SynapseLauncher.start_synapse_by_list_name(["Synapse2", "Synapse3"], brain=self.brain_test) # the singleton should now contains the synapse that was already there and the 2 other synapses self.assertEqual(expected_result, lifo_buffer.lifo_list)
def execute_synapses_in_hook_name(cls, hook_name): # need to import SynapseLauncher from here to avoid cross import from kalliope.core.SynapseLauncher import SynapseLauncher logger.debug("[HookManager] calling synapses in hook name: %s" % hook_name) settings = SettingLoader().settings # list of synapse to execute list_synapse = settings.hooks[hook_name] logger.debug("[HookManager] hook: %s , type: %s" % (hook_name, type(list_synapse))) if isinstance(list_synapse, list): return SynapseLauncher.start_synapse_by_list_name(list_synapse, new_lifo=True) if isinstance(list_synapse, str): return SynapseLauncher.start_synapse_by_name(list_synapse, new_lifo=True) return None
def test_run_synapse(self): """ Test to run a Synapse """ neuron1 = Neuron(name='neurone1', parameters={'var1': 'val1'}) neuron2 = Neuron(name='neurone2', parameters={'var2': 'val2'}) signal1 = Order(sentence="this is the sentence") synapse1 = Synapse(name="Synapse1", neurons=[neuron1, neuron2], signals=[signal1]) synapse_empty = Synapse(name="Synapse_empty", neurons=[], signals=[signal1]) sl = SettingLoader() resources = Resources(neuron_folder='/var/tmp/test/resources') sl.settings.resources = resources with mock.patch("kalliope.core.Utils.get_dynamic_class_instantiation" ) as mock_get_class_instantiation: SynapseLauncher._run_synapse(synapse=synapse1) calls = [ mock.call(package_name="neurons", module_name=neuron1.name, parameters=neuron1.parameters, resources_dir="/var/tmp/test/resources"), mock.call(package_name="neurons", module_name=neuron2.name, parameters=neuron2.parameters, resources_dir="/var/tmp/test/resources") ] mock_get_class_instantiation.assert_has_calls(calls=calls) mock_get_class_instantiation.reset_mock() # Do not any Neurons SynapseLauncher._run_synapse(synapse=synapse_empty) mock_get_class_instantiation.assert_not_called() mock_get_class_instantiation.reset_mock()
def audio_analyser_callback(self, order): """ Callback of the OrderListener. Called after the processing of the audio file This method will - call the Order Analyser to analyse the order and launch corresponding synapse as usual. - get a list of launched synapse. - give the list to the main process via self.launched_synapses - notify that the processing is over via order_analyser_return :param order: string order to analyse :return: """ logger.debug("order to process %s" % order) api_response = SynapseLauncher.run_matching_synapse_from_order( order, self.brain, self.settings, is_api_call=True) self.api_response = api_response # this boolean will notify the main process that the order have been processed self.order_analyser_return = True
def run_synapse_by_order(self): """ Give an order to Kalliope via API like it was from a spoken one Test with curl curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ -d '{"order":"my order"}' http://localhost:5000/synapses/start/order In case of quotes in the order or accents, use a file cat post.json: {"order":"j'aime"} curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ --data @post.json http://localhost:5000/order/ Can be used with no_voice flag curl -i --user admin:secret -H "Content-Type: application/json" -X POST \ -d '{"order":"my order", "no_voice":"true"}' http://localhost:5000/synapses/start/order :return: """ if not request.get_json() or 'order' not in request.get_json(): abort(400) order = request.get_json('order') # get no_voice_flag if present no_voice = self.get_boolean_flag_from_request( request, boolean_flag_to_find="no_voice") if order is not None: # get the order order_to_run = order["order"] logger.debug( "[FlaskAPI] run_synapse_by_order: order to run -> %s" % order_to_run) api_response = SynapseLauncher.run_matching_synapse_from_order( order_to_run, self.brain, self.settings, is_api_call=True, no_voice=no_voice) data = jsonify(api_response) return data, 201 else: data = {"error": "order cannot be null"} return jsonify(error=data), 400
def execute_synapses_in_hook_name(cls, hook_name): # need to import SynapseLauncher from here to avoid cross import from kalliope.core.SynapseLauncher import SynapseLauncher logger.debug("[HookManager] calling synapses in hook name: %s" % hook_name) settings = SettingLoader().settings # list of synapse to execute try: list_synapse = settings.hooks[hook_name] logger.debug("[HookManager] hook: %s , type: %s" % (hook_name, type(list_synapse))) except KeyError: # the hook haven't been set in setting. just skip the execution logger.debug("[HookManager] hook not set: %s" % hook_name) return None if isinstance(list_synapse, str): list_synapse = [list_synapse] return SynapseLauncher.start_synapse_by_list_name(list_synapse, new_lifo=True)
def audio_analyser_callback(self, order): """ Callback of the OrderListener. Called after the processing of the audio file This method will - call the Order Analyser to analyse the order and launch corresponding synapse as usual. - get a list of launched synapse. - give the list to the main process via self.launched_synapses - notify that the processing is over via order_analyser_return :param order: string order to analyse :return: """ logger.debug("[FlaskAPI] audio_analyser_callback: order to process -> %s" % order) api_response = SynapseLauncher.run_matching_synapse_from_order(order, self.brain, self.settings, is_api_call=True) self.api_response = api_response # this boolean will notify the main process that the order have been processed self.order_analyser_return = True
def test_run_matching_synapse_from_order(self): # ------------------ # test_match_synapse1 # ------------------ with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): order_to_match = "this is the sentence" should_be_created_matched_synapse = MatchedSynapse(matched_synapse=self.synapse1, user_order=order_to_match, matched_order="this is the sentence") expected_result = [[should_be_created_matched_synapse]] SynapseLauncher.run_matching_synapse_from_order(order_to_match, brain=self.brain_test, settings=self.settings_test) lifo_buffer = LifoManager.get_singleton_lifo() self.assertEqual(expected_result, lifo_buffer.lifo_list) # ------------------------- # test_match_synapse1_and_2 # ------------------------- # clean LIFO Singleton._instances = dict() LifoManager.clean_saved_lifo() with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): order_to_match = "this is the second sentence" should_be_created_matched_synapse1 = MatchedSynapse(matched_synapse=self.synapse1, user_order=order_to_match, matched_order="this is the sentence") should_be_created_matched_synapse2 = MatchedSynapse(matched_synapse=self.synapse2, user_order=order_to_match, matched_order="this is the second sentence") expected_result = [[should_be_created_matched_synapse1, should_be_created_matched_synapse2]] SynapseLauncher.run_matching_synapse_from_order(order_to_match, brain=self.brain_test, settings=self.settings_test) lifo_buffer = LifoManager.get_singleton_lifo() self.assertEqual(expected_result, lifo_buffer.lifo_list) # ------------------------- # test_call_hook_order_not_found # ------------------------- # clean LIFO Singleton._instances = dict() LifoManager.clean_saved_lifo() with mock.patch("kalliope.core.HookManager.on_order_not_found") as mock_hook: order_to_match = "not existing sentence" SynapseLauncher.run_matching_synapse_from_order(order_to_match, brain=self.brain_test, settings=self.settings_test) mock_hook.assert_called_with() mock_hook.reset_mock() # ------------------------- # test_call_hook_order_found # ------------------------- # clean LIFO Singleton._instances = dict() with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): with mock.patch("kalliope.core.HookManager.on_order_found") as mock_hook: order_to_match = "this is the second sentence" new_settings = Settings() SynapseLauncher.run_matching_synapse_from_order(order_to_match, brain=self.brain_test, settings=new_settings) mock_hook.assert_called_with() mock_hook.reset_mock()
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]") 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 test_run_matching_synapse_from_order(self): # ------------------ # test_match_synapse1 # ------------------ with mock.patch("kalliope.core.LIFOBuffer.execute"): order_to_match = "this is the sentence" should_be_created_matched_synapse = MatchedSynapse( matched_synapse=self.synapse1, user_order=order_to_match, matched_order="this is the sentence") expected_result = [[should_be_created_matched_synapse]] SynapseLauncher.run_matching_synapse_from_order( order_to_match, brain=self.brain_test, settings=self.settings_test) lifo_buffer = LIFOBuffer() self.assertEqual(expected_result, lifo_buffer.lifo_list) # ------------------------- # test_match_synapse1_and_2 # ------------------------- # clean LIFO Singleton._instances = dict() with mock.patch("kalliope.core.LIFOBuffer.execute"): order_to_match = "this is the second sentence" should_be_created_matched_synapse1 = MatchedSynapse( matched_synapse=self.synapse1, user_order=order_to_match, matched_order="this is the sentence") should_be_created_matched_synapse2 = MatchedSynapse( matched_synapse=self.synapse2, user_order=order_to_match, matched_order="this is the second sentence") expected_result = [[ should_be_created_matched_synapse1, should_be_created_matched_synapse2 ]] SynapseLauncher.run_matching_synapse_from_order( order_to_match, brain=self.brain_test, settings=self.settings_test) lifo_buffer = LIFOBuffer() self.assertEqual(expected_result, lifo_buffer.lifo_list) # ------------------------- # test_match_default_synapse # ------------------------- # clean LIFO Singleton._instances = dict() with mock.patch("kalliope.core.LIFOBuffer.execute"): order_to_match = "not existing sentence" should_be_created_matched_synapse = MatchedSynapse( matched_synapse=self.synapse3, user_order=order_to_match, matched_order=None) expected_result = [[should_be_created_matched_synapse]] SynapseLauncher.run_matching_synapse_from_order( order_to_match, brain=self.brain_test, settings=self.settings_test) lifo_buffer = LIFOBuffer() self.assertEqual(expected_result, lifo_buffer.lifo_list) # ------------------------- # test_no_match_and_no_default_synapse # ------------------------- # clean LIFO Singleton._instances = dict() with mock.patch("kalliope.core.LIFOBuffer.execute"): order_to_match = "not existing sentence" new_settings = Settings() expected_result = [[]] SynapseLauncher.run_matching_synapse_from_order( order_to_match, brain=self.brain_test, settings=new_settings) lifo_buffer = LIFOBuffer() self.assertEqual(expected_result, lifo_buffer.lifo_list)
def test_run_matching_synapse_from_order(self): # ------------------ # test_match_synapse1 # ------------------ with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): order_to_match = "this is the sentence" should_be_created_matched_synapse = MatchedSynapse( matched_synapse=self.synapse1, user_order=order_to_match, matched_order="this is the sentence") expected_result = [[should_be_created_matched_synapse]] SynapseLauncher.run_matching_synapse_from_order( order_to_match, brain=self.brain_test, settings=self.settings_test) lifo_buffer = LifoManager.get_singleton_lifo() self.assertEqual(expected_result, lifo_buffer.lifo_list) # ------------------------- # test_match_synapse1_and_2 # ------------------------- # clean LIFO Singleton._instances = dict() LifoManager.clean_saved_lifo() with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): order_to_match = "this is the second sentence" should_be_created_matched_synapse1 = MatchedSynapse( matched_synapse=self.synapse1, user_order=order_to_match, matched_order="this is the sentence") should_be_created_matched_synapse2 = MatchedSynapse( matched_synapse=self.synapse2, user_order=order_to_match, matched_order="this is the second sentence") expected_result = [[ should_be_created_matched_synapse1, should_be_created_matched_synapse2 ]] SynapseLauncher.run_matching_synapse_from_order( order_to_match, brain=self.brain_test, settings=self.settings_test) lifo_buffer = LifoManager.get_singleton_lifo() self.assertEqual(expected_result, lifo_buffer.lifo_list) # ------------------------- # test_call_hook_order_not_found # ------------------------- # clean LIFO Singleton._instances = dict() LifoManager.clean_saved_lifo() with mock.patch( "kalliope.core.HookManager.on_order_not_found") as mock_hook: order_to_match = "not existing sentence" SynapseLauncher.run_matching_synapse_from_order( order_to_match, brain=self.brain_test, settings=self.settings_test) mock_hook.assert_called_with() mock_hook.reset_mock() # ------------------------- # test_call_hook_order_found # ------------------------- # clean LIFO Singleton._instances = dict() with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): with mock.patch( "kalliope.core.HookManager.on_order_found") as mock_hook: order_to_match = "this is the second sentence" new_settings = Settings() SynapseLauncher.run_matching_synapse_from_order( order_to_match, brain=self.brain_test, settings=new_settings) mock_hook.assert_called_with() mock_hook.reset_mock()
def test_start_synapse_by_list_name(self): # test to start a list of synapse with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): created_matched_synapse1 = MatchedSynapse( matched_synapse=self.synapse1) created_matched_synapse2 = MatchedSynapse( matched_synapse=self.synapse2) expected_list_matched_synapse = [ created_matched_synapse1, created_matched_synapse2 ] SynapseLauncher.start_synapse_by_list_name( ["Synapse1", "Synapse2"], brain=self.brain_test) # we expect that the lifo has been loaded with the synapse to run expected_result = [expected_list_matched_synapse] lifo_buffer = LifoManager.get_singleton_lifo() self.maxDiff = None self.assertEqual(expected_result, lifo_buffer.lifo_list) # empty list should return none empty_list = list() self.assertIsNone( SynapseLauncher.start_synapse_by_list_name(empty_list)) # test to start a synapse list with a new lifo # we create a Lifo that is the current singleton Singleton._instances = dict() LifoManager.clean_saved_lifo() lifo_buffer = LifoManager.get_singleton_lifo() created_matched_synapse1 = MatchedSynapse( matched_synapse=self.synapse1) lifo_buffer.lifo_list = [created_matched_synapse1] # the current status of the singleton lifo should not move even after the call of SynapseLauncher expected_result = [created_matched_synapse1] # create a new call with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): SynapseLauncher.start_synapse_by_list_name( ["Synapse2", "Synapse3"], brain=self.brain_test, new_lifo=True) # the current singleton should be the same self.assertEqual(expected_result, lifo_buffer.lifo_list) # test to start a synapse list with the singleton lifo Singleton._instances = dict() LifoManager.clean_saved_lifo() lifo_buffer = LifoManager.get_singleton_lifo() created_matched_synapse1 = MatchedSynapse( matched_synapse=self.synapse1) # place a synapse in the singleton lifo_buffer.lifo_list = [created_matched_synapse1] # the current status of the singleton lifo should contain synapse launched in the next call created_matched_synapse2 = MatchedSynapse( matched_synapse=self.synapse2) created_matched_synapse3 = MatchedSynapse( matched_synapse=self.synapse3) expected_result = [ created_matched_synapse1, [created_matched_synapse2, created_matched_synapse3] ] with mock.patch("kalliope.core.Lifo.LIFOBuffer.execute"): SynapseLauncher.start_synapse_by_list_name( ["Synapse2", "Synapse3"], brain=self.brain_test) # the singleton should now contains the synapse that was already there and the 2 other synapses self.assertEqual(expected_result, lifo_buffer.lifo_list)
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 run_synapse_by_name(self, name): SynapseLauncher.start_synapse(name=name, brain=self.brain)
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)