コード例 #1
0
ファイル: MqttClient.py プロジェクト: johnmelodyme/brain
    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)
コード例 #2
0
 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)
コード例 #3
0
ファイル: order.py プロジェクト: johnmelodyme/brain
    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()
コード例 #4
0
    def test_start_synapse_by_list_name_single_synapse(self):
        # existing synapse in the brain
        with mock.patch("brain.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)
コード例 #5
0
    def run_synapse_by_order(self):
        """
        Give an order to Brain.ai 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
コード例 #6
0
    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
コード例 #7
0
ファイル: HookManager.py プロジェクト: johnmelodyme/brain
    def execute_synapses_in_hook_name(cls, hook_name):
        # need to import SynapseLauncher from here to avoid cross import
        from brain.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)
コード例 #8
0
    def test_start_synapse_by_list_name(self):
        # test to start a list of synapse
        with mock.patch("brain.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("brain.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("brain.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)
コード例 #9
0
    def test_run_matching_synapse_from_order(self):
        # ------------------
        # test_match_synapse1
        # ------------------
        with mock.patch("brain.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("brain.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(
                "brain.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("brain.core.Lifo.LIFOBuffer.execute"):
            with mock.patch(
                    "brain.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()
コード例 #10
0
ファイル: __init__.py プロジェクト: johnmelodyme/brain
def main():
    """Entry point of Brain.ai program."""

    Utils.print_info("")

    Utils.print_info("Brain.ai (Version 0.1.4)")
    Utils.print_info("Copyright (C) 2018 by Alexander Paul P. Quinit")
    Utils.print_info("This program comes with ABSOLUTELY NO WARRANTY")
    Utils.print_info(
        "This is free software, and you are welcome to redistribute it under certain conditions"
    )

    Utils.print_info("")

    # 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("brain 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("please 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("please 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_list_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 --deaf
            if parser.deaf:
                settings.options.deaf = True

            # start rest api
            start_rest_api(settings, brain)
            start_brain(settings, brain)