Sfoglia il codice sorgente

[Hook][Refactor] add mute and unmute hooks and introduce settings editor

ThiBuff 7 anni fa
parent
commit
012b666817

+ 2 - 0
Docs/settings.md

@@ -248,6 +248,8 @@ List of available hook
 | on_processed_synapses  | When all neurons in synapses have been processed                |
 | on_deaf                | When Kalliope switches from non deaf to deaf                    |
 | on_undeaf              | When Kalliope switches from deaf to non deaf                    |
+| on_mute                | When Kalliope switches from non mute to mute                    |
+| on_unmute              | When Kalliope switches from mute to non mute                    |
 | on_start_speaking      | When Kalliope starts speaking via the text to speech engine     |
 | on_stop_speaking       | When Kalliope stops speaking                                    |
 

+ 2 - 0
Tests/settings/settings_test.yml

@@ -94,6 +94,8 @@ hooks:
   on_processed_synapses:
   on_deaf: []
   on_undeaf: []
+  on_mute: []
+  on_unmute: []
   on_start_speaking:
   on_stop_speaking:
 

+ 8 - 0
Tests/test_settings_loader.py

@@ -60,6 +60,8 @@ class TestSettingLoader(unittest.TestCase):
                       'on_undeaf': [],
                       'on_triggered': ['on-triggered-synapse'],
                       'on_deaf': [],
+                      'on_mute': [],
+                      'on_unmute': [],
                       'on_order_not_found': [
                           'order-not-found-synapse'],
                       'on_processed_synapses': None,
@@ -137,6 +139,8 @@ class TestSettingLoader(unittest.TestCase):
                                  'on_undeaf': [],
                                  'on_triggered': ['on-triggered-synapse'],
                                  'on_deaf': [],
+                                 'on_mute': [],
+                                 'on_unmute': [],
                                  'on_order_not_found': [
                                      'order-not-found-synapse'],
                                  'on_processed_synapses': None,
@@ -249,6 +253,8 @@ class TestSettingLoader(unittest.TestCase):
             "on_order_not_found": None,
             "on_deaf": None,
             "on_undeaf": None,
+            "on_mute": None,
+            "on_unmute": None,
             "on_start_speaking": None,
             "on_stop_speaking": None
         }
@@ -270,6 +276,8 @@ class TestSettingLoader(unittest.TestCase):
             "on_order_not_found": None,
             "on_deaf": None,
             "on_undeaf": None,
+            "on_mute": None,
+            "on_unmute": None,
             "on_start_speaking": None,
             "on_stop_speaking": None
         }

+ 47 - 0
kalliope/core/ConfigurationManager/SettingEditor.py

@@ -0,0 +1,47 @@
+import logging
+
+from kalliope.core.Utils import Utils
+from kalliope.core.HookManager import HookManager
+from kalliope.core.ConfigurationManager import SettingLoader
+
+logging.basicConfig()
+logger = logging.getLogger("kalliope")
+
+
+class SettingEditor(object):
+    """This class provides methods/functions to update properties from the Settings"""
+
+    @staticmethod
+    def set_mute_status(mute=False):
+        """
+        Define is the mute status
+        :param mute: Boolean. If false, Kalliope is voice is stopped
+        """
+        logger.debug("[SettingEditor] mute. Switch trigger process to mute : %s" % mute)
+        settings = SettingLoader().settings
+        if mute:
+            Utils.print_info("Kalliope now muted, voice has been stopped.")
+            HookManager.on_mute()
+        else:
+            Utils.print_info("Kalliope now speaking.")
+            HookManager.on_unmute()
+        settings.options["mute"] = mute
+
+    @staticmethod
+    def set_deaf_status(trigger_instance, deaf=False):
+        """
+        Define is the trigger is listening or not.
+        :param trigger_instance: the trigger instance coming from the order. It will be paused or unpaused.
+        :param deaf: Boolean. If true, kalliope is trigger is paused
+        """
+        logger.debug("[MainController] deaf . Switch trigger process to deaf : %s" % deaf)
+        settings = SettingLoader().settings
+        if deaf:
+            trigger_instance.pause()
+            Utils.print_info("Kalliope now deaf, trigger has been paused")
+            HookManager.on_deaf()
+        else:
+            trigger_instance.unpause()
+            Utils.print_info("Kalliope now listening for trigger detection")
+            HookManager.on_undeaf()
+        settings.options["deaf"] = deaf

+ 3 - 2
kalliope/core/ConfigurationManager/SettingLoader.py

@@ -642,14 +642,13 @@ class SettingLoader(with_metaclass(Singleton, object)):
         :rtype: dict
         """
 
-        options = dict()
         deaf = False
         mute = False
 
         try:
             options = settings["options"]
         except KeyError:
-            options = None
+            options = dict()
 
         if options is not None:
             if options['deaf']:
@@ -689,6 +688,8 @@ class SettingLoader(with_metaclass(Singleton, object)):
             "on_order_not_found",
             "on_deaf",
             "on_undeaf",
+            "on_mute",
+            "on_unmute",
             "on_start_speaking",
             "on_stop_speaking"
         ]

+ 1 - 0
kalliope/core/ConfigurationManager/__init__.py

@@ -1,3 +1,4 @@
 from .YAMLLoader import YAMLLoader
 from .SettingLoader import SettingLoader
 from .BrainLoader import BrainLoader
+from .SettingEditor import SettingEditor

+ 8 - 0
kalliope/core/HookManager.py

@@ -47,6 +47,14 @@ class HookManager(object):
     def on_undeaf(cls):
         return cls.execute_synapses_in_hook_name("on_undeaf")
 
+    @classmethod
+    def on_mute(cls):
+        return cls.execute_synapses_in_hook_name("on_mute")
+
+    @classmethod
+    def on_unmute(cls):
+        return cls.execute_synapses_in_hook_name("on_unmute")
+
     @classmethod
     def on_start_speaking(cls):
         return cls.execute_synapses_in_hook_name("on_start_speaking")

+ 25 - 21
kalliope/core/RestAPI/FlaskAPI.py

@@ -9,9 +9,9 @@ from flask_cors import CORS
 from flask_restful import abort
 from werkzeug.utils import secure_filename
 
-from kalliope import SignalLauncher
+from kalliope.core.SignalLauncher import SignalLauncher
 from kalliope._version import version_str
-from kalliope.core.ConfigurationManager import SettingLoader, BrainLoader
+from kalliope.core.ConfigurationManager import SettingLoader, BrainLoader, SettingEditor
 from kalliope.core.Lifo.LifoManager import LifoManager
 from kalliope.core.Models.MatchedSynapse import MatchedSynapse
 from kalliope.core.OrderListener import OrderListener
@@ -162,7 +162,7 @@ class FlaskAPI(threading.Thread):
         old_mute_value = self.settings.options["mute"]
         mute = self.get_boolean_flag_from_request(request, boolean_flag_to_find="mute")
         if mute is not None:
-            self.settings.options["mute"] = mute
+            SettingEditor.set_mute_status(mute=mute)
 
         # get parameters
         parameters = self.get_parameters_from_request(request)
@@ -171,7 +171,8 @@ class FlaskAPI(threading.Thread):
             data = {
                 "synapse name not found": "%s" % synapse_name
             }
-            self.settings.options["mute"] = old_mute_value
+            if mute is not None:
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return jsonify(error=data), 404
         else:
             # generate a MatchedSynapse from the synapse
@@ -181,7 +182,8 @@ class FlaskAPI(threading.Thread):
             lifo_buffer.add_synapse_list_to_lifo([matched_synapse])
             response = lifo_buffer.execute(is_api_call=True)
             data = jsonify(response)
-            self.settings.options["mute"] = old_mute_value
+            if mute is not None:
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return data, 201
 
     @requires_auth
@@ -213,7 +215,7 @@ class FlaskAPI(threading.Thread):
         old_mute_value = self.settings.options["mute"]
         mute = self.get_boolean_flag_from_request(request, boolean_flag_to_find="mute")
         if mute is not None:
-            self.settings.options["mute"] = mute
+            SettingEditor.set_mute_status(mute=mute)
 
         if order is not None:
             # get the order
@@ -225,13 +227,15 @@ class FlaskAPI(threading.Thread):
                                                                            is_api_call=True)
 
             data = jsonify(api_response)
-            self.settings.options["mute"] = old_mute_value
+            if mute is not None:
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return data, 201
         else:
             data = {
                 "error": "order cannot be null"
             }
-            self.settings.options["mute"] = old_mute_value
+            if mute is not None:
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return jsonify(error=data), 400
 
     @requires_auth
@@ -265,7 +269,7 @@ class FlaskAPI(threading.Thread):
         # Store the mute value, then apply depending of the request parameters
         old_mute_value = self.settings.options["mute"]
         if request.form.get("mute"):
-            self.settings.options["mute"] = self.str_to_bool(request.form.get("mute"))
+            SettingEditor.set_mute_status(mute=self.str_to_bool(request.form.get("mute")))
 
         # save the file
         filename = secure_filename(uploaded_file.filename)
@@ -288,13 +292,15 @@ class FlaskAPI(threading.Thread):
             data = jsonify(self.api_response)
             self.api_response = None
             logger.debug("[FlaskAPI] run_synapse_by_audio: data %s" % data)
-            self.settings.options["mute"] = old_mute_value
+            if request.form.get("mute"):
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return data, 201
         else:
             data = {
                 "error": "The given order doesn't match any synapses"
             }
-            self.settings.options["mute"] = old_mute_value
+            if request.form.get("mute"):
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return jsonify(error=data), 400
 
     @staticmethod
@@ -332,11 +338,10 @@ class FlaskAPI(threading.Thread):
         curl -i --user admin:secret  -X GET  http://127.0.0.1:5000/deaf
         """
 
-        # find the order signal and call the deaf method
-        signal_order = SignalLauncher.get_order_instance()
-        if signal_order is not None:
+        # find the order signal and call the deaf settings
+        if self.settings.options["deaf"] is not None:
             data = {
-                "deaf": signal_order.get_deaf_status()
+                "deaf": self.settings.options["deaf"]
             }
             return jsonify(data), 200
 
@@ -362,12 +367,11 @@ class FlaskAPI(threading.Thread):
         # get deaf if present
         deaf = self.get_boolean_flag_from_request(request, boolean_flag_to_find="deaf")
 
-        # find the order signal and call the deaf method
         signal_order = SignalLauncher.get_order_instance()
-        if signal_order is not None and deaf is not None:
-            signal_order.set_deaf_status(deaf)
+        if signal_order is not None and deaf is not None and self.settings.options["deaf"] is not None:
+            SettingEditor.set_deaf_status(signal_order.trigger_instance, deaf)
             data = {
-                "deaf": signal_order.get_deaf_status()
+                "deaf": self.settings.options["deaf"]
             }
             return jsonify(data), 200
 
@@ -385,7 +389,7 @@ class FlaskAPI(threading.Thread):
         curl -i --user admin:secret  -X GET  http://127.0.0.1:5000/mute
         """
 
-        # find the order signal and call the deaf method
+        # find the order signal and call the mute settings
         if self.settings.options["mute"] is not None:
             data = {
                 "mute": self.settings.options["mute"]
@@ -413,8 +417,8 @@ class FlaskAPI(threading.Thread):
 
         # get mute if present
         mute = self.get_boolean_flag_from_request(request, boolean_flag_to_find="mute")
+        SettingEditor.set_mute_status(mute=mute)
 
-        self.settings.options["mute"] = mute
         data = {
             "mute": mute
         }

+ 2 - 1
kalliope/neurons/deaf/deaf.py

@@ -2,6 +2,7 @@ import logging
 
 from kalliope import SignalLauncher
 from kalliope.core.NeuronModule import NeuronModule
+from kalliope.core.ConfigurationManager.SettingEditor import SettingEditor
 
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
@@ -18,7 +19,7 @@ class Deaf(NeuronModule):
         if self._is_parameters_ok():
             signal_order = SignalLauncher.get_order_instance()
             if signal_order is not None:
-                signal_order.set_deaf_status(self.status)
+                SettingEditor.set_deaf_status(signal_order.trigger_instance, self.status)
 
     def _is_parameters_ok(self):
         """

+ 1 - 25
kalliope/signals/order/order.py

@@ -48,7 +48,6 @@ class Order(Thread):
         # save an instance of the trigger
         self.trigger_instance = None
         self.trigger_callback_called = False
-        self.is_trigger_deaf = self.settings.options['deaf']
 
         # save the current order listener
         self.order_listener = None
@@ -97,7 +96,7 @@ class Order(Thread):
         Method to print in debug that the main process is waiting for a trigger detection
         """
         logger.debug("[MainController] Entering state: %s" % self.state)
-        if self.is_trigger_deaf:  # the user asked to deaf inside the deaf neuron
+        if self.settings.options["deaf"]:  # the user asked to deaf inside the deaf neuron
             Utils.print_info("Kalliope is deaf")
             self.trigger_instance.pause()
         else:
@@ -175,26 +174,3 @@ class Order(Thread):
 
         # return to the state "unpausing_trigger"
         self.start_trigger()
-
-    def set_deaf_status(self, deaf=False):
-        """
-        Define is the trigger is listening or not
-        :param deaf: Boolean. If true, kalliope is trigger is paused
-        """
-        logger.debug("[MainController] deaf button pressed. Switch trigger process to deaf : %s" % deaf)
-        self.is_trigger_deaf = deaf
-        if deaf:
-            self.trigger_instance.pause()
-            Utils.print_info("Kalliope now deaf, trigger has been paused")
-            HookManager.on_deaf()
-        else:
-            self.trigger_instance.unpause()
-            Utils.print_info("Kalliope now listening for trigger detection")
-            HookManager.on_undeaf()
-
-    def get_deaf_status(self):
-        """
-        return the current state of the trigger (deaf or not)
-        :return: Boolean
-        """
-        return self.is_trigger_deaf