Browse Source

Merge pull request #436 from kalliope-project/feature/introduce_mute_settings

Feature/introduce mute settings
Nicolas Marcq 7 years ago
parent
commit
a7697d9723

+ 4 - 4
Docs/kalliope_cli.md

@@ -96,18 +96,18 @@ You can combine the options together like, for example:
 kalliope start --run-synapse "say-hello" --brain-file /home/me/my_other_brain.yml
 kalliope start --run-synapse "say-hello" --brain-file /home/me/my_other_brain.yml
 ```
 ```
 
 
-### --muted
+### --deaf
 
 
-Starts Kalliope in a muted state.
+Starts Kalliope in a deaf state, the trigger is paused.
 
 
 Example of use
 Example of use
 ```bash
 ```bash
-kalliope start --muted
+kalliope start --deaf
 ```
 ```
 
 
 You can combine the options together like, for example:
 You can combine the options together like, for example:
 ```bash
 ```bash
-kalliope start --muted --brain-file /home/me/my_other_brain.yml
+kalliope start --deaf --brain-file /home/me/my_other_brain.yml
 ```
 ```
 
 
 ### --debug
 ### --debug

+ 55 - 15
Docs/rest_api.md

@@ -12,6 +12,8 @@ Kalliope provides the REST API to manage the synapses. For configuring the API r
 | POST   | /synapses/start/id/<synapse_name> | Run a synapse by its name          |
 | POST   | /synapses/start/id/<synapse_name> | Run a synapse by its name          |
 | POST   | /synapses/start/order             | Run a synapse from a text order    |
 | POST   | /synapses/start/order             | Run a synapse from a text order    |
 | POST   | /synapses/start/audio             | Run a synapse from an audio sample |
 | POST   | /synapses/start/audio             | Run a synapse from an audio sample |
+| GET    | /deaf                             | Get the current deaf status        |
+| POST   | /deaf                             | Switch the deaf status             |
 | GET    | /mute                             | Get the current mute status        |
 | GET    | /mute                             | Get the current mute status        |
 | POST   | /mute                             | Switch the mute status             |
 | POST   | /mute                             | Switch the mute status             |
 
 
@@ -149,11 +151,11 @@ Output example:
 }
 }
 ```
 ```
 
 
-The [no_voice flag](#no-voice-flag) can be added to this call.
+The [mute flag](#mute-flag) can be added to this call.
 Curl command:
 Curl command:
 ```bash
 ```bash
 curl -i -H "Content-Type: application/json" --user admin:secret -X POST \
 curl -i -H "Content-Type: application/json" --user admin:secret -X POST \
--d '{"no_voice":"true"}' http://127.0.0.1:5000/synapses/start/id/say-hello-fr
+-d '{"mute":"true"}' http://127.0.0.1:5000/synapses/start/id/say-hello-fr
 ```
 ```
 
 
 Some neuron inside a synapse will wait for parameters that comes from the order. 
 Some neuron inside a synapse will wait for parameters that comes from the order. 
@@ -234,11 +236,11 @@ Or return an empty list of matched synapse
 }
 }
 ```
 ```
 
 
-The [no_voice flag](#no-voice-flag) can be added to this call.
+The [mute flag](#mute-flag) can be added to this call.
 Curl command:
 Curl command:
 ```bash
 ```bash
 curl -i --user admin:secret -H "Content-Type: application/json" -X POST \
 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
+-d '{"order":"my order", "mute":"true"}' http://localhost:5000/synapses/start/order
 ```
 ```
 
 
 ### Run a synapse from an audio file
 ### Run a synapse from an audio file
@@ -302,10 +304,10 @@ Or return an empty list of matched synapse
 }
 }
 ```
 ```
 
 
-The [no_voice flag](#no-voice-flag) can be added to this call with a form.
+The [mute flag](#mute-flag) can be added to this call with a form.
 Curl command:
 Curl command:
 ```bash
 ```bash
-curl -i --user admin:secret -X POST http://localhost:5000/synapses/start/audio -F "file=@path/to/file.wav" -F no_voice="true"
+curl -i --user admin:secret -X POST http://localhost:5000/synapses/start/audio -F "file=@path/to/file.wav" -F mute="true"
 ```
 ```
 
 
 #### The neurotransmitter case
 #### The neurotransmitter case
@@ -351,7 +353,7 @@ The response should be as follow:
 The ```"status": "waiting_for_answer"``` indicates that it waits for a response, so let's send it:
 The ```"status": "waiting_for_answer"``` indicates that it waits for a response, so let's send it:
 
 
 ```bash
 ```bash
- --user admin:secret -H "Content-Type: application/json" -X POST -d '{"order":"not at all"}' http://localhost:5000/synapses/start/order
+curl -i --user admin:secret -H "Content-Type: application/json" -X POST -d '{"order":"not at all"}' http://localhost:5000/synapses/start/order
 ```
 ```
 
 
 ```JSON
 ```JSON
@@ -390,42 +392,80 @@ The ```"status": "waiting_for_answer"``` indicates that it waits for a response,
 
 
 And now the status is complete. This works also when you have nested neurotransmitter neurons, you just need to keep monitoring the status from the API answer.
 And now the status is complete. This works also when you have nested neurotransmitter neurons, you just need to keep monitoring the status from the API answer.
 
 
-### Get mute status
+### Get deaf status
 
 
 Normal response codes: 200
 Normal response codes: 200
 Error response codes: unauthorized(401), Bad request(400)
 Error response codes: unauthorized(401), Bad request(400)
 
 
 Curl command:
 Curl command:
 ```bash
 ```bash
-curl -i --user admin:secret  -X GET  http://127.0.0.1:5000/mute
+curl -i --user admin:secret  -X GET  http://127.0.0.1:5000/deaf
 ```
 ```
 
 
 Output example:
 Output example:
 ```JSON
 ```JSON
 {
 {
-  "mute": true
+  "deaf": true
 }
 }
 ```
 ```
 
 
-### Switch mute status
+### Switch deaf status
+Kalliope can switch to 'deaf' mode, so she can not ear you anymore, the trigger/hotword is desactivated.
+However Kalliope continues to process synapses.
 
 
 Normal response codes: 200
 Normal response codes: 200
 Error response codes: unauthorized(401), Bad request(400)
 Error response codes: unauthorized(401), Bad request(400)
 
 
 Curl command:
 Curl command:
 ```bash
 ```bash
-curl -i -H "Content-Type: application/json" --user admin:secret  -X POST -d '{"mute": "True"}' http://127.0.0.1:5000/mute
+curl -i -H "Content-Type: application/json" --user admin:secret  -X POST -d '{"deaf": "True"}' http://127.0.0.1:5000/deaf
 ```
 ```
 
 
 Output example:
 Output example:
 ```JSON
 ```JSON
 {
 {
-  "mute": true
+  "deaf": true
 }
 }
 ```
 ```
 
 
-## No voice flag
+## Mute flag
 
 
 When you use the API, by default Kalliope will generate a text and process it into the TTS engine.
 When you use the API, by default Kalliope will generate a text and process it into the TTS engine.
 Some calls to the API can be done with a flag that will tell Kalliope to only return the generated text without processing it into the audio player.
 Some calls to the API can be done with a flag that will tell Kalliope to only return the generated text without processing it into the audio player.
-When `no_voice` is switched to true, Kalliope will not speak out loud on the server side.
+When `mute` is switched to true, Kalliope will not speak out loud on the server side.
+
+### Get mute status
+
+Normal response codes: 200
+Error response codes : unauthorized(401), Bad request(400)
+
+
+Curl command:
+```bash
+curl -i --user admin:secret  -X GET  http://127.0.0.1:5000/mute
+```
+
+Output example:
+```JSON
+{
+  "mute": true
+}
+```
+
+### Set mute status
+
+Normal response codes: 200
+Error response codes : unauthorized(401), Bad request(400)
+
+
+Curl command:
+```bash
+curl -i -H "Content-Type: application/json" --user admin:secret  -X POST -d '{"mute": "True"}' http://127.0.0.1:5000/mute
+```
+
+Output example:
+```JSON
+{
+  "mute": true
+}
+```

+ 5 - 3
Docs/settings.md

@@ -246,8 +246,10 @@ List of available hook
 | on_order_found         | When the pronounced order has been found in the brain           |
 | on_order_found         | When the pronounced order has been found in the brain           |
 | on_order_not_found     | When the pronounced order has not been found in the brain       |
 | on_order_not_found     | When the pronounced order has not been found in the brain       |
 | on_processed_synapses  | When all neurons in synapses have been processed                |
 | on_processed_synapses  | When all neurons in synapses have been processed                |
-| on_mute                | When Kalliope switches from non muted to muted                  |
-| on_unmute              | When Kalliope switches from muted to non muted                  |
+| 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_start_speaking      | When Kalliope starts speaking via the text to speech engine     |
 | on_stop_speaking       | When Kalliope stops speaking                                    |
 | on_stop_speaking       | When Kalliope stops speaking                                    |
 
 
@@ -461,7 +463,7 @@ Options that can be defined when kalliope starts.
 
 
 Example config
 Example config
 ```yaml
 ```yaml
-start_options:
+options:
   muted: True
   muted: True
 ```
 ```
 
 

+ 5 - 2
Tests/settings/settings_test.yml

@@ -92,6 +92,8 @@ hooks:
   on_order_not_found:
   on_order_not_found:
     - "order-not-found-synapse"
     - "order-not-found-synapse"
   on_processed_synapses:
   on_processed_synapses:
+  on_deaf: []
+  on_undeaf: []
   on_mute: []
   on_mute: []
   on_unmute: []
   on_unmute: []
   on_start_speaking:
   on_start_speaking:
@@ -113,5 +115,6 @@ resource_directory:
 var_files:
 var_files:
   - "../Tests/settings/variables.yml"
   - "../Tests/settings/variables.yml"
 
 
-start_options:
-  muted: True
+options:
+  deaf: True
+  mute: False

+ 2 - 2
Tests/test_hook_manager.py

@@ -77,11 +77,11 @@ class TestInit(unittest.TestCase):
     def test_on_processed_synapses(self):
     def test_on_processed_synapses(self):
         self.assertIsNone(HookManager.on_processed_synapses())
         self.assertIsNone(HookManager.on_processed_synapses())
 
 
-    def test_on_mute(self):
+    def test_on_deaf(self):
         """
         """
         test that empty list of synapse return none
         test that empty list of synapse return none
         """
         """
-        self.assertIsNone(HookManager.on_mute())
+        self.assertIsNone(HookManager.on_deaf())
 
 
 
 
 if __name__ == '__main__':
 if __name__ == '__main__':

+ 4 - 4
Tests/test_models.py

@@ -259,7 +259,7 @@ class TestModels(unittest.TestCase):
                                 resources=None,
                                 resources=None,
                                 variables={"key1": "val1"},
                                 variables={"key1": "val1"},
                                 recognition_options=recognition_options,
                                 recognition_options=recognition_options,
-                                start_options={'muted': False})
+                                options={'deaf': False, 'mute': False})
             setting1.kalliope_version = "0.4.5"
             setting1.kalliope_version = "0.4.5"
 
 
             setting2 = Settings(default_tts_name="accapela",
             setting2 = Settings(default_tts_name="accapela",
@@ -274,7 +274,7 @@ class TestModels(unittest.TestCase):
                                 resources=None,
                                 resources=None,
                                 variables={"key1": "val1"},
                                 variables={"key1": "val1"},
                                 recognition_options=recognition_options,
                                 recognition_options=recognition_options,
-                                start_options={'muted': False})
+                                options={'deaf': False, 'mute': False})
             setting2.kalliope_version = "0.4.5"
             setting2.kalliope_version = "0.4.5"
 
 
             setting3 = Settings(default_tts_name="pico2wav",
             setting3 = Settings(default_tts_name="pico2wav",
@@ -290,7 +290,7 @@ class TestModels(unittest.TestCase):
                                 resources=None,
                                 resources=None,
                                 variables={"key1": "val1"},
                                 variables={"key1": "val1"},
                                 recognition_options=recognition_options,
                                 recognition_options=recognition_options,
-                                start_options={'muted': False})
+                                options={'deaf': False, 'mute': False})
             setting3.kalliope_version = "0.4.5"
             setting3.kalliope_version = "0.4.5"
 
 
             expected_result_serialize = {
             expected_result_serialize = {
@@ -318,7 +318,7 @@ class TestModels(unittest.TestCase):
                 'triggers': ['snowboy'],
                 'triggers': ['snowboy'],
                 'players': ['mplayer'],
                 'players': ['mplayer'],
                 'recognition_options': {'energy_threshold': 4000, 'adjust_for_ambient_noise_second': 0},
                 'recognition_options': {'energy_threshold': 4000, 'adjust_for_ambient_noise_second': 0},
-                'start_options': {'muted': False}
+                'options': {'deaf': False, 'mute': False}
             }
             }
 
 
             self.maxDiff = None
             self.maxDiff = None

+ 18 - 8
Tests/test_settings_loader.py

@@ -51,15 +51,17 @@ class TestSettingLoader(unittest.TestCase):
                 {'voxygen': {'voice': 'Agnes', 'cache': True}}
                 {'voxygen': {'voice': 'Agnes', 'cache': True}}
                 ],
                 ],
             'var_files': ["../Tests/settings/variables.yml"],
             'var_files': ["../Tests/settings/variables.yml"],
-            'start_options': {'muted': True},
+            'options': {'deaf': True, 'mute': False},
             'hooks': {'on_waiting_for_trigger': 'test',
             'hooks': {'on_waiting_for_trigger': 'test',
                       'on_stop_listening': None,
                       'on_stop_listening': None,
                       'on_start_listening': None,
                       'on_start_listening': None,
                       'on_order_found': None,
                       'on_order_found': None,
                       'on_start': ['on-start-synapse', 'bring-led-on'],
                       'on_start': ['on-start-synapse', 'bring-led-on'],
-                      'on_unmute': [],
+                      'on_undeaf': [],
                       'on_triggered': ['on-triggered-synapse'],
                       'on_triggered': ['on-triggered-synapse'],
+                      'on_deaf': [],
                       'on_mute': [],
                       'on_mute': [],
+                      'on_unmute': [],
                       'on_order_not_found': [
                       'on_order_not_found': [
                           'order-not-found-synapse'],
                           'order-not-found-synapse'],
                       'on_processed_synapses': None,
                       'on_processed_synapses': None,
@@ -123,8 +125,9 @@ class TestSettingLoader(unittest.TestCase):
             "test_number": 60,
             "test_number": 60,
             "test": "kalliope"
             "test": "kalliope"
         }
         }
-        settings_object.start_options = {
-            "muted": True
+        settings_object.options = {
+            "deaf": True,
+            "mute": False
         }
         }
         settings_object.machine = platform.machine()
         settings_object.machine = platform.machine()
         settings_object.recognition_options = RecognitionOptions()
         settings_object.recognition_options = RecognitionOptions()
@@ -133,9 +136,11 @@ class TestSettingLoader(unittest.TestCase):
                                  'on_start_listening': None,
                                  'on_start_listening': None,
                                  'on_order_found': None,
                                  'on_order_found': None,
                                  'on_start': ['on-start-synapse', 'bring-led-on'],
                                  'on_start': ['on-start-synapse', 'bring-led-on'],
-                                 'on_unmute': [],
+                                 'on_undeaf': [],
                                  'on_triggered': ['on-triggered-synapse'],
                                  'on_triggered': ['on-triggered-synapse'],
+                                 'on_deaf': [],
                                  'on_mute': [],
                                  'on_mute': [],
+                                 'on_unmute': [],
                                  'on_order_not_found': [
                                  'on_order_not_found': [
                                      'order-not-found-synapse'],
                                      'order-not-found-synapse'],
                                  'on_processed_synapses': None,
                                  'on_processed_synapses': None,
@@ -221,13 +226,14 @@ class TestSettingLoader(unittest.TestCase):
         self.assertEqual(expected_result,
         self.assertEqual(expected_result,
                          sl._get_variables(self.settings_dict))
                          sl._get_variables(self.settings_dict))
 
 
-    def test_get_start_options(self):
+    def test_get_options(self):
         expected_result = {
         expected_result = {
-            "muted": True
+            "deaf": True,
+            "mute": False
         }
         }
         sl = SettingLoader(file_path=self.settings_file_to_test)
         sl = SettingLoader(file_path=self.settings_file_to_test)
         self.assertEqual(expected_result,
         self.assertEqual(expected_result,
-                         sl._get_start_options(self.settings_dict))
+                         sl._get_options(self.settings_dict))
 
 
     def test_get_hooks(self):
     def test_get_hooks(self):
 
 
@@ -245,6 +251,8 @@ class TestSettingLoader(unittest.TestCase):
             "on_stop_listening": None,
             "on_stop_listening": None,
             "on_order_found": None,
             "on_order_found": None,
             "on_order_not_found": None,
             "on_order_not_found": None,
+            "on_deaf": None,
+            "on_undeaf": None,
             "on_mute": None,
             "on_mute": None,
             "on_unmute": None,
             "on_unmute": None,
             "on_start_speaking": None,
             "on_start_speaking": None,
@@ -266,6 +274,8 @@ class TestSettingLoader(unittest.TestCase):
             "on_stop_listening": None,
             "on_stop_listening": None,
             "on_order_found": None,
             "on_order_found": None,
             "on_order_not_found": None,
             "on_order_not_found": None,
+            "on_deaf": None,
+            "on_undeaf": None,
             "on_mute": None,
             "on_mute": None,
             "on_unmute": None,
             "on_unmute": None,
             "on_start_speaking": None,
             "on_start_speaking": None,

+ 2 - 2
brain_examples/mute.yml

@@ -1,10 +1,10 @@
 
 
-- name: "mute-synapse"
+- name: "deaf-synapse"
   signals:
   signals:
     - order: "stop listening"
     - order: "stop listening"
   neurons:
   neurons:
     - say:
     - say:
         message:
         message:
           - "I stop hearing you, sir"
           - "I stop hearing you, sir"
-    - mute:
+    - deaf:
         status: True
         status: True

+ 4 - 4
kalliope/__init__.py

@@ -63,7 +63,7 @@ def parse_args(args):
     parser.add_argument("--tts-name", help="TTS 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("--trigger-name", help="Trigger name to uninstall")
     parser.add_argument("--signal-name", help="Signal name to uninstall")
     parser.add_argument("--signal-name", help="Signal name to uninstall")
-    parser.add_argument("--muted", action='store_true', help="Starts Kalliope muted")
+    parser.add_argument("--deaf", action='store_true', help="Starts Kalliope deaf")
     parser.add_argument('-v', '--version', action='version',
     parser.add_argument('-v', '--version', action='version',
                         version='Kalliope ' + version_str)
                         version='Kalliope ' + version_str)
 
 
@@ -155,9 +155,9 @@ def main():
                                                             is_api_call=False)
                                                             is_api_call=False)
 
 
         if (parser.run_synapse is None) and (parser.run_order is None):
         if (parser.run_synapse is None) and (parser.run_order is None):
-            # if --muted
-            if parser.muted:
-                settings.start_options['muted'] = True
+            # if --deaf
+            if parser.deaf:
+                settings.options['deaf'] = True
 
 
             # start rest api
             # start rest api
             start_rest_api(settings, brain)
             start_rest_api(settings, brain)

+ 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

+ 17 - 13
kalliope/core/ConfigurationManager/SettingLoader.py

@@ -112,7 +112,7 @@ class SettingLoader(with_metaclass(Singleton, object)):
         resources = self._get_resources(settings)
         resources = self._get_resources(settings)
         variables = self._get_variables(settings)
         variables = self._get_variables(settings)
         recognition_options = self._get_recognition_options(settings)
         recognition_options = self._get_recognition_options(settings)
-        start_options = self._get_start_options(settings)
+        options = self._get_options(settings)
         hooks = self._get_hooks(settings)
         hooks = self._get_hooks(settings)
 
 
         # Load the setting singleton with the parameters
         # Load the setting singleton with the parameters
@@ -129,7 +129,7 @@ class SettingLoader(with_metaclass(Singleton, object)):
         setting_object.resources = resources
         setting_object.resources = resources
         setting_object.variables = variables
         setting_object.variables = variables
         setting_object.recognition_options = recognition_options
         setting_object.recognition_options = recognition_options
-        setting_object.start_options = start_options
+        setting_object.options = options
         setting_object.hooks = hooks
         setting_object.hooks = hooks
 
 
         return setting_object
         return setting_object
@@ -632,7 +632,7 @@ class SettingLoader(with_metaclass(Singleton, object)):
         return recognition_options
         return recognition_options
 
 
     @staticmethod
     @staticmethod
-    def _get_start_options(settings):
+    def _get_options(settings):
         """
         """
         Return the start options settings
         Return the start options settings
 
 
@@ -641,21 +641,23 @@ class SettingLoader(with_metaclass(Singleton, object)):
         :return: A dict containing the start options
         :return: A dict containing the start options
         :rtype: dict
         :rtype: dict
         """
         """
-        options = dict()
-        muted = False
+
+        deaf = False
+        mute = False
 
 
         try:
         try:
-            start_options = settings["start_options"]
+            options = settings["options"]
         except KeyError:
         except KeyError:
-            start_options = None
+            options = dict()
 
 
-        if start_options is not None:
-            try:
-                muted = start_options['muted']
-            except KeyError:
-                muted = False
+        if options is not None:
+            if options['deaf']:
+                deaf = options['deaf']
+            if options['mute']:
+                mute = options['mute']
 
 
-        options['muted'] = muted
+        options['deaf'] = deaf
+        options['mute'] = mute
 
 
         logger.debug("Start options: %s" % options)
         logger.debug("Start options: %s" % options)
         return options
         return options
@@ -684,6 +686,8 @@ class SettingLoader(with_metaclass(Singleton, object)):
             "on_stop_listening",
             "on_stop_listening",
             "on_order_found",
             "on_order_found",
             "on_order_not_found",
             "on_order_not_found",
+            "on_deaf",
+            "on_undeaf",
             "on_mute",
             "on_mute",
             "on_unmute",
             "on_unmute",
             "on_start_speaking",
             "on_start_speaking",

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

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

+ 8 - 0
kalliope/core/HookManager.py

@@ -39,6 +39,14 @@ class HookManager(object):
     def on_processed_synapses(cls):
     def on_processed_synapses(cls):
         return cls.execute_synapses_in_hook_name("on_processed_synapses")
         return cls.execute_synapses_in_hook_name("on_processed_synapses")
 
 
+    @classmethod
+    def on_deaf(cls):
+        return cls.execute_synapses_in_hook_name("on_deaf")
+
+    @classmethod
+    def on_undeaf(cls):
+        return cls.execute_synapses_in_hook_name("on_undeaf")
+
     @classmethod
     @classmethod
     def on_mute(cls):
     def on_mute(cls):
         return cls.execute_synapses_in_hook_name("on_mute")
         return cls.execute_synapses_in_hook_name("on_mute")

+ 2 - 7
kalliope/core/Lifo/LIFOBuffer.py

@@ -39,7 +39,6 @@ class LIFOBuffer(object):
         self.lifo_list = list()
         self.lifo_list = list()
         self.answer = None
         self.answer = None
         self.is_api_call = False
         self.is_api_call = False
-        self.no_voice = False
         self.is_running = False
         self.is_running = False
         self.reset_lifo = False
         self.reset_lifo = False
 
 
@@ -79,7 +78,7 @@ class LIFOBuffer(object):
         self.api_response = APIResponse()
         self.api_response = APIResponse()
         return returned_api_response
         return returned_api_response
 
 
-    def execute(self, answer=None, is_api_call=False, no_voice=False):
+    def execute(self, answer=None, is_api_call=False):
         """
         """
         Process the LIFO list.
         Process the LIFO list.
 
 
@@ -91,13 +90,11 @@ class LIFOBuffer(object):
 
 
         :param answer: String answer to give the the last neuron which was waiting for an answer
         :param answer: String answer to give the the last neuron which was waiting for an answer
         :param is_api_call: Boolean passed to all neuron in order to let them know if the current call comes from API
         :param is_api_call: Boolean passed to all neuron in order to let them know if the current call comes from API
-        :param no_voice: If true, the generated text will not be processed by the TTS engine
         :return: serialized APIResponse object
         :return: serialized APIResponse object
         """
         """
         # store the answer if present
         # store the answer if present
         self.answer = answer
         self.answer = answer
         self.is_api_call = is_api_call
         self.is_api_call = is_api_call
-        self.no_voice = no_voice
 
 
         try:
         try:
             if not self.is_running:
             if not self.is_running:
@@ -170,9 +167,7 @@ class LIFOBuffer(object):
                 self.answer = None
                 self.answer = None
             # todo fix this when we have a full client/server call. The client would be the voice or api call
             # todo fix this when we have a full client/server call. The client would be the voice or api call
             neuron.parameters["is_api_call"] = self.is_api_call
             neuron.parameters["is_api_call"] = self.is_api_call
-            neuron.parameters["no_voice"] = self.no_voice
-            logger.debug("[LIFOBuffer] process_neuron_list: is_api_call: %s, no_voice: %s" % (self.is_api_call,
-                                                                                              self.no_voice))
+            logger.debug("[LIFOBuffer] process_neuron_list: is_api_call: %s" % (self.is_api_call))
             # execute the neuron
             # execute the neuron
             instantiated_neuron = NeuronLauncher.start_neuron(neuron=neuron,
             instantiated_neuron = NeuronLauncher.start_neuron(neuron=neuron,
                                                               parameters_dict=matched_synapse.parameters)
                                                               parameters_dict=matched_synapse.parameters)

+ 3 - 3
kalliope/core/Models/Settings.py

@@ -22,7 +22,7 @@ class Settings(object):
                  resources=None,
                  resources=None,
                  variables=None,
                  variables=None,
                  recognition_options=None,
                  recognition_options=None,
-                 start_options=None,
+                 options=None,
                  hooks=None):
                  hooks=None):
 
 
         self.default_tts_name = default_tts_name
         self.default_tts_name = default_tts_name
@@ -40,7 +40,7 @@ class Settings(object):
         self.machine = platform.machine()   # can be x86_64 or armv7l
         self.machine = platform.machine()   # can be x86_64 or armv7l
         self.kalliope_version = current_kalliope_version
         self.kalliope_version = current_kalliope_version
         self.recognition_options = recognition_options
         self.recognition_options = recognition_options
-        self.start_options = start_options
+        self.options = options
         self.hooks = hooks
         self.hooks = hooks
 
 
     def serialize(self):
     def serialize(self):
@@ -67,7 +67,7 @@ class Settings(object):
             'machine': self.machine,
             'machine': self.machine,
             'kalliope_version': self.kalliope_version,
             'kalliope_version': self.kalliope_version,
             'recognition_options': self.recognition_options.serialize() if self.recognition_options is not None else None,
             'recognition_options': self.recognition_options.serialize() if self.recognition_options is not None else None,
-            'start_options': self.start_options,
+            'options': self.options,
             'hooks': self.hooks
             'hooks': self.hooks
         }
         }
 
 

+ 6 - 8
kalliope/core/NeuronModule.py

@@ -105,8 +105,6 @@ class NeuronModule(object):
         self.tts_message = None
         self.tts_message = None
         # if the current call is api one
         # if the current call is api one
         self.is_api_call = kwargs.get('is_api_call', False)
         self.is_api_call = kwargs.get('is_api_call', False)
-        # if the current call want to mute kalliope
-        self.no_voice = kwargs.get('no_voice', False)
         # boolean to know id the synapse is waiting for an answer
         # boolean to know id the synapse is waiting for an answer
         self.is_waiting_for_answer = False
         self.is_waiting_for_answer = False
         # the synapse name to add the the buffer
         # the synapse name to add the the buffer
@@ -171,11 +169,11 @@ class NeuronModule(object):
             # save in kalliope memory the last tts message
             # save in kalliope memory the last tts message
             Cortex.save("kalliope_last_tts_message", tts_message)
             Cortex.save("kalliope_last_tts_message", tts_message)
 
 
-            # process the audio only if the no_voice flag is false
-            if self.no_voice:
-                logger.debug("[NeuronModule] no_voice is True, Kalliope is muted")
+            # process the audio only if the mute flag is false
+            if self.settings.options["mute"]:
+                logger.debug("[NeuronModule] mute is True, Kalliope is muted")
             else:
             else:
-                logger.debug("[NeuronModule] no_voice is False, make Kalliope speaking")
+                logger.debug("[NeuronModule] mute is False, make Kalliope speaking")
                 HookManager.on_start_speaking()
                 HookManager.on_start_speaking()
                 # get the instance of the TTS module
                 # get the instance of the TTS module
                 tts_folder = None
                 tts_folder = None
@@ -237,7 +235,7 @@ class NeuronModule(object):
 
 
     @staticmethod
     @staticmethod
     def run_synapse_by_name(synapse_name, user_order=None, synapse_order=None, high_priority=False,
     def run_synapse_by_name(synapse_name, user_order=None, synapse_order=None, high_priority=False,
-                            is_api_call=False, overriding_parameter_dict=None, no_voice=False):
+                            is_api_call=False, overriding_parameter_dict=None):
         """
         """
         call the lifo for adding a synapse to execute in the list of synapse list to process
         call the lifo for adding a synapse to execute in the list of synapse list to process
         :param synapse_name: The name of the synapse to run
         :param synapse_name: The name of the synapse to run
@@ -258,7 +256,7 @@ class NeuronModule(object):
         # get the singleton
         # get the singleton
         lifo_buffer = LifoManager.get_singleton_lifo()
         lifo_buffer = LifoManager.get_singleton_lifo()
         lifo_buffer.add_synapse_list_to_lifo(list_synapse_to_process, high_priority=high_priority)
         lifo_buffer.add_synapse_list_to_lifo(list_synapse_to_process, high_priority=high_priority)
-        lifo_buffer.execute(is_api_call=is_api_call, no_voice=no_voice)
+        lifo_buffer.execute(is_api_call=is_api_call)
 
 
     @staticmethod
     @staticmethod
     def is_order_matching(order_said, order_match):
     def is_order_matching(order_said, order_match):

+ 105 - 43
kalliope/core/RestAPI/FlaskAPI.py

@@ -9,9 +9,9 @@ from flask_cors import CORS
 from flask_restful import abort
 from flask_restful import abort
 from werkzeug.utils import secure_filename
 from werkzeug.utils import secure_filename
 
 
-from kalliope import SignalLauncher
+from kalliope.core.SignalLauncher import SignalLauncher
 from kalliope._version import version_str
 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.Lifo.LifoManager import LifoManager
 from kalliope.core.Models.MatchedSynapse import MatchedSynapse
 from kalliope.core.Models.MatchedSynapse import MatchedSynapse
 from kalliope.core.OrderListener import OrderListener
 from kalliope.core.OrderListener import OrderListener
@@ -62,9 +62,6 @@ class FlaskAPI(threading.Thread):
         if self.allowed_cors_origin is not False:
         if self.allowed_cors_origin is not False:
             CORS(app, resources={r"/*": {"origins": allowed_cors_origin}}, supports_credentials=True)
             CORS(app, resources={r"/*": {"origins": allowed_cors_origin}}, supports_credentials=True)
 
 
-        # no voice flag
-        self.no_voice = False
-
         # Add routing rules
         # Add routing rules
         self.app.add_url_rule('/', view_func=self.get_main_page, methods=['GET'])
         self.app.add_url_rule('/', view_func=self.get_main_page, methods=['GET'])
         self.app.add_url_rule('/synapses', view_func=self.get_synapses, methods=['GET'])
         self.app.add_url_rule('/synapses', view_func=self.get_synapses, methods=['GET'])
@@ -73,6 +70,8 @@ class FlaskAPI(threading.Thread):
         self.app.add_url_rule('/synapses/start/order', view_func=self.run_synapse_by_order, methods=['POST'])
         self.app.add_url_rule('/synapses/start/order', view_func=self.run_synapse_by_order, methods=['POST'])
         self.app.add_url_rule('/synapses/start/audio', view_func=self.run_synapse_by_audio, methods=['POST'])
         self.app.add_url_rule('/synapses/start/audio', view_func=self.run_synapse_by_audio, methods=['POST'])
         self.app.add_url_rule('/shutdown/', view_func=self.shutdown_server, methods=['POST'])
         self.app.add_url_rule('/shutdown/', view_func=self.shutdown_server, methods=['POST'])
+        self.app.add_url_rule('/deaf/', view_func=self.get_deaf, methods=['GET'])
+        self.app.add_url_rule('/deaf/', view_func=self.set_deaf, methods=['POST'])
         self.app.add_url_rule('/mute/', view_func=self.get_mute, methods=['GET'])
         self.app.add_url_rule('/mute/', view_func=self.get_mute, methods=['GET'])
         self.app.add_url_rule('/mute/', view_func=self.set_mute, methods=['POST'])
         self.app.add_url_rule('/mute/', view_func=self.set_mute, methods=['POST'])
 
 
@@ -145,11 +144,11 @@ class FlaskAPI(threading.Thread):
 
 
         run a synapse without making kalliope speaking
         run a synapse without making kalliope speaking
         curl -i -H "Content-Type: application/json" --user admin:secret -X POST  \
         curl -i -H "Content-Type: application/json" --user admin:secret -X POST  \
-        -d '{"no_voice":"true"}' http://127.0.0.1:5000/synapses/start/id/say-hello-fr
+        -d '{"mute":"true"}' http://127.0.0.1:5000/synapses/start/id/say-hello-fr
 
 
         Run a synapse by its name and pass order's parameters
         Run a synapse by its name and pass order's parameters
         curl -i -H "Content-Type: application/json" --user admin:secret -X POST  \
         curl -i -H "Content-Type: application/json" --user admin:secret -X POST  \
-        -d '{"no_voice":"true", "parameters": {"parameter1": "value1" }}' \
+        -d '{"mute":"true", "parameters": {"parameter1": "value1" }}' \
         http://127.0.0.1:5000/synapses/start/id/say-hello-fr
         http://127.0.0.1:5000/synapses/start/id/say-hello-fr
 
 
         :param synapse_name: name(id) of the synapse to execute
         :param synapse_name: name(id) of the synapse to execute
@@ -159,8 +158,11 @@ class FlaskAPI(threading.Thread):
         logger.debug("[FlaskAPI] run_synapse_by_name: synapse name -> %s" % synapse_name)
         logger.debug("[FlaskAPI] run_synapse_by_name: synapse name -> %s" % synapse_name)
         synapse_target = BrainLoader().brain.get_synapse_by_name(synapse_name=synapse_name)
         synapse_target = BrainLoader().brain.get_synapse_by_name(synapse_name=synapse_name)
 
 
-        # get no_voice_flag if present
-        no_voice = self.get_boolean_flag_from_request(request, boolean_flag_to_find="no_voice")
+        # Store the mute value, then apply depending of the request parameters
+        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:
+            SettingEditor.set_mute_status(mute=mute)
 
 
         # get parameters
         # get parameters
         parameters = self.get_parameters_from_request(request)
         parameters = self.get_parameters_from_request(request)
@@ -169,6 +171,8 @@ class FlaskAPI(threading.Thread):
             data = {
             data = {
                 "synapse name not found": "%s" % synapse_name
                 "synapse name not found": "%s" % synapse_name
             }
             }
+            if mute is not None:
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return jsonify(error=data), 404
             return jsonify(error=data), 404
         else:
         else:
             # generate a MatchedSynapse from the synapse
             # generate a MatchedSynapse from the synapse
@@ -176,8 +180,10 @@ class FlaskAPI(threading.Thread):
             # get the current LIFO buffer from the singleton
             # get the current LIFO buffer from the singleton
             lifo_buffer = LifoManager.get_singleton_lifo()
             lifo_buffer = LifoManager.get_singleton_lifo()
             lifo_buffer.add_synapse_list_to_lifo([matched_synapse])
             lifo_buffer.add_synapse_list_to_lifo([matched_synapse])
-            response = lifo_buffer.execute(is_api_call=True, no_voice=no_voice)
+            response = lifo_buffer.execute(is_api_call=True)
             data = jsonify(response)
             data = jsonify(response)
+            if mute is not None:
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return data, 201
             return data, 201
 
 
     @requires_auth
     @requires_auth
@@ -194,9 +200,9 @@ class FlaskAPI(threading.Thread):
         curl -i --user admin:secret -H "Content-Type: application/json" -X POST \
         curl -i --user admin:secret -H "Content-Type: application/json" -X POST \
         --data @post.json http://localhost:5000/order/
         --data @post.json http://localhost:5000/order/
 
 
-        Can be used with no_voice flag
+        Can be used with mute flag
         curl -i --user admin:secret -H "Content-Type: application/json" -X POST \
         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
+        -d '{"order":"my order", "mute":"true"}' http://localhost:5000/synapses/start/order
 
 
         :return:
         :return:
         """
         """
@@ -204,8 +210,13 @@ class FlaskAPI(threading.Thread):
             abort(400)
             abort(400)
 
 
         order = request.get_json('order')
         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")
+
+        # Store the mute value, then apply depending of the request parameters
+        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:
+            SettingEditor.set_mute_status(mute=mute)
+
         if order is not None:
         if order is not None:
             # get the order
             # get the order
             order_to_run = order["order"]
             order_to_run = order["order"]
@@ -213,15 +224,18 @@ class FlaskAPI(threading.Thread):
             api_response = SynapseLauncher.run_matching_synapse_from_order(order_to_run,
             api_response = SynapseLauncher.run_matching_synapse_from_order(order_to_run,
                                                                            self.brain,
                                                                            self.brain,
                                                                            self.settings,
                                                                            self.settings,
-                                                                           is_api_call=True,
-                                                                           no_voice=no_voice)
+                                                                           is_api_call=True)
 
 
             data = jsonify(api_response)
             data = jsonify(api_response)
+            if mute is not None:
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return data, 201
             return data, 201
         else:
         else:
             data = {
             data = {
                 "error": "order cannot be null"
                 "error": "order cannot be null"
             }
             }
+            if mute is not None:
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return jsonify(error=data), 400
             return jsonify(error=data), 400
 
 
     @requires_auth
     @requires_auth
@@ -231,13 +245,10 @@ class FlaskAPI(threading.Thread):
         Test with curl
         Test with curl
         curl -i --user admin:secret -X POST  http://localhost:5000/synapses/start/audio -F "file=@/path/to/input.wav"
         curl -i --user admin:secret -X POST  http://localhost:5000/synapses/start/audio -F "file=@/path/to/input.wav"
 
 
-        With no_voice flag
-        curl -i -H "Content-Type: application/json" --user admin:secret -X POST \
-        http://localhost:5000/synapses/start/audio -F "file=@path/to/file.wav" -F no_voice="true"
+        With mute flag
+        curl -i --user admin:secret -X POST http://localhost:5000/synapses/start/audio -F "file=@path/to/file.wav" -F mute="true"
         :return:
         :return:
         """
         """
-        # get no_voice_flag if present
-        self.no_voice = self.str_to_bool(request.form.get("no_voice"))
 
 
         # check if the post request has the file part
         # check if the post request has the file part
         if 'file' not in request.files:
         if 'file' not in request.files:
@@ -254,6 +265,12 @@ class FlaskAPI(threading.Thread):
                 "error": "No file provided"
                 "error": "No file provided"
             }
             }
             return jsonify(error=data), 400
             return jsonify(error=data), 400
+
+        # Store the mute value, then apply depending of the request parameters
+        old_mute_value = self.settings.options["mute"]
+        if request.form.get("mute"):
+            SettingEditor.set_mute_status(mute=self.str_to_bool(request.form.get("mute")))
+
         # save the file
         # save the file
         filename = secure_filename(uploaded_file.filename)
         filename = secure_filename(uploaded_file.filename)
         base_path = os.path.join(self.app.config['UPLOAD_FOLDER'])
         base_path = os.path.join(self.app.config['UPLOAD_FOLDER'])
@@ -275,11 +292,15 @@ class FlaskAPI(threading.Thread):
             data = jsonify(self.api_response)
             data = jsonify(self.api_response)
             self.api_response = None
             self.api_response = None
             logger.debug("[FlaskAPI] run_synapse_by_audio: data %s" % data)
             logger.debug("[FlaskAPI] run_synapse_by_audio: data %s" % data)
+            if request.form.get("mute"):
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return data, 201
             return data, 201
         else:
         else:
             data = {
             data = {
                 "error": "The given order doesn't match any synapses"
                 "error": "The given order doesn't match any synapses"
             }
             }
+            if request.form.get("mute"):
+                SettingEditor.set_mute_status(mute=old_mute_value)
             return jsonify(error=data), 400
             return jsonify(error=data), 400
 
 
     @staticmethod
     @staticmethod
@@ -309,58 +330,100 @@ class FlaskAPI(threading.Thread):
         return "Shutting down..."
         return "Shutting down..."
 
 
     @requires_auth
     @requires_auth
-    def get_mute(self):
+    def get_deaf(self):
         """
         """
         Return the current trigger status
         Return the current trigger status
 
 
         Curl test
         Curl test
-        curl -i --user admin:secret  -X GET  http://127.0.0.1:5000/mute
+        curl -i --user admin:secret  -X GET  http://127.0.0.1:5000/deaf
         """
         """
 
 
-        # find the order signal and call the mute 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 = {
             data = {
-                "mute": signal_order.get_mute_status()
+                "deaf": self.settings.options["deaf"]
             }
             }
             return jsonify(data), 200
             return jsonify(data), 200
 
 
         # if no Order instance
         # if no Order instance
         data = {
         data = {
-            "error": "Mute status unknow"
+            "error": "deaf status unknow"
         }
         }
         return jsonify(error=data), 400
         return jsonify(error=data), 400
 
 
     @requires_auth
     @requires_auth
-    def set_mute(self):
+    def set_deaf(self):
         """
         """
-        Set the trigger status (muted or not)
+        Set the trigger status (deaf or not)
 
 
         Curl test:
         Curl test:
         curl -i -H "Content-Type: application/json" --user admin:secret  -X POST \
         curl -i -H "Content-Type: application/json" --user admin:secret  -X POST \
-        -d '{"mute": "True"}' http://127.0.0.1:5000/mute
+        -d '{"deaf": "True"}' http://127.0.0.1:5000/deaf
         """
         """
 
 
-        if not request.get_json() or 'mute' not in request.get_json():
+        if not request.get_json() or 'deaf' not in request.get_json():
             abort(400)
             abort(400)
 
 
-        # get mute if present
-        mute = self.get_boolean_flag_from_request(request, boolean_flag_to_find="mute")
+        # get deaf if present
+        deaf = self.get_boolean_flag_from_request(request, boolean_flag_to_find="deaf")
 
 
-        # find the order signal and call the mute method
         signal_order = SignalLauncher.get_order_instance()
         signal_order = SignalLauncher.get_order_instance()
-        if signal_order is not None:
-            signal_order.set_mute_status(mute)
+        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 = {
             data = {
-                "mute": signal_order.get_mute_status()
+                "deaf": self.settings.options["deaf"]
             }
             }
             return jsonify(data), 200
             return jsonify(data), 200
 
 
         data = {
         data = {
-            "error": "Cannot switch mute status"
+            "error": "Cannot switch deaf status"
         }
         }
         return jsonify(error=data), 400
         return jsonify(error=data), 400
 
 
+    @requires_auth
+    def get_mute(self):
+        """
+        Return the current mute status
+
+        Curl test
+        curl -i --user admin:secret  -X GET  http://127.0.0.1:5000/mute
+        """
+
+        # find the order signal and call the mute settings
+        if self.settings.options["mute"] is not None:
+            data = {
+                "mute": self.settings.options["mute"]
+            }
+            return jsonify(data), 200
+
+        # if no Order instance
+        data = {
+            "error": "mute status unknow"
+        }
+        return jsonify(error=data), 400
+
+    @requires_auth
+    def set_mute(self):
+        """
+        Set the Kalliope Core mute status (mute or not)
+
+        Curl test:
+        curl -i -H "Content-Type: application/json" --user admin:secret  -X POST \
+        -d '{"mute": "True"}' http://127.0.0.1:5000/mute
+        """
+
+        if not request.get_json() or 'mute' not in request.get_json():
+            abort(400)
+
+        # get mute if present
+        mute = self.get_boolean_flag_from_request(request, boolean_flag_to_find="mute")
+        SettingEditor.set_mute_status(mute=mute)
+
+        data = {
+            "mute": mute
+        }
+        return jsonify(data), 200
+
     def audio_analyser_callback(self, order):
     def audio_analyser_callback(self, order):
         """
         """
         Callback of the OrderListener. Called after the processing of the audio file
         Callback of the OrderListener. Called after the processing of the audio file
@@ -376,8 +439,7 @@ class FlaskAPI(threading.Thread):
         api_response = SynapseLauncher.run_matching_synapse_from_order(order,
         api_response = SynapseLauncher.run_matching_synapse_from_order(order,
                                                                        self.brain,
                                                                        self.brain,
                                                                        self.settings,
                                                                        self.settings,
-                                                                       is_api_call=True,
-                                                                       no_voice=self.no_voice)
+                                                                       is_api_call=True)
         self.api_response = api_response
         self.api_response = api_response
 
 
         # this boolean will notify the main process that the order have been processed
         # this boolean will notify the main process that the order have been processed
@@ -385,12 +447,12 @@ class FlaskAPI(threading.Thread):
 
 
     def get_boolean_flag_from_request(self, http_request, boolean_flag_to_find):
     def get_boolean_flag_from_request(self, http_request, boolean_flag_to_find):
         """
         """
-        Get the boolean flag from the request if exist
+        Get the boolean flag from the request if exist, None otherwise !
         :param http_request:
         :param http_request:
         :param boolean_flag_to_find: json flag to find in the http_request
         :param boolean_flag_to_find: json flag to find in the http_request
         :return: True or False if the boolean flag has been found in the request
         :return: True or False if the boolean flag has been found in the request
         """
         """
-        boolean_flag = False
+        boolean_flag = None
         try:
         try:
             received_json = http_request.get_json(force=True, silent=True, cache=True)
             received_json = http_request.get_json(force=True, silent=True, cache=True)
             if boolean_flag_to_find in received_json:
             if boolean_flag_to_find in received_json:

+ 3 - 4
kalliope/core/SynapseLauncher.py

@@ -64,14 +64,13 @@ class SynapseLauncher(object):
         return None
         return None
 
 
     @classmethod
     @classmethod
-    def run_matching_synapse_from_order(cls, order_to_process, brain, settings, is_api_call=False, no_voice=False):
+    def run_matching_synapse_from_order(cls, order_to_process, brain, settings, is_api_call=False):
         """
         """
         
         
         :param order_to_process: the spoken order sent by the user
         :param order_to_process: the spoken order sent by the user
         :param brain: Brain object
         :param brain: Brain object
         :param settings: Settings object
         :param settings: Settings object
         :param is_api_call: if True, the current call come from the API. This info must be known by launched Neuron
         :param is_api_call: if True, the current call come from the API. This info must be known by launched Neuron
-        :param no_voice: If true, the generated text will not be processed by the TTS engine
         :return: list of matched synapse
         :return: list of matched synapse
         """
         """
 
 
@@ -81,7 +80,7 @@ class SynapseLauncher(object):
         # if the LIFO is not empty, so, the current order is passed to the current processing synapse as an answer
         # if the LIFO is not empty, so, the current order is passed to the current processing synapse as an answer
         if len(lifo_buffer.lifo_list) > 0:
         if len(lifo_buffer.lifo_list) > 0:
             # the LIFO is not empty, this is an answer to a previous call
             # the LIFO is not empty, this is an answer to a previous call
-            return lifo_buffer.execute(answer=order_to_process, is_api_call=is_api_call, no_voice=no_voice)
+            return lifo_buffer.execute(answer=order_to_process, is_api_call=is_api_call)
 
 
         else:  # the LIFO is empty, this is a new call
         else:  # the LIFO is empty, this is a new call
             # get a list of matched synapse from the order
             # get a list of matched synapse from the order
@@ -95,6 +94,6 @@ class SynapseLauncher(object):
             lifo_buffer.add_synapse_list_to_lifo(list_synapse_to_process)
             lifo_buffer.add_synapse_list_to_lifo(list_synapse_to_process)
             lifo_buffer.api_response.user_order = order_to_process
             lifo_buffer.api_response.user_order = order_to_process
 
 
-            execdata = lifo_buffer.execute(is_api_call=is_api_call, no_voice=no_voice)
+            execdata = lifo_buffer.execute(is_api_call=is_api_call)
             HookManager.on_processed_synapses()
             HookManager.on_processed_synapses()
             return execdata
             return execdata

+ 11 - 11
kalliope/neurons/mute/README.md → kalliope/neurons/deaf/README.md

@@ -1,12 +1,12 @@
-# Mute
+# Deaf
 
 
 ## Synopsis
 ## Synopsis
 
 
-Mute control of kalliope. If set to True the trigger process will be stopped.
+Deaf control of kalliope. If set to True the trigger process will be stopped.
 
 
-Once this neuron is used, and Kalliope muted, the hotword is deactivated. Only ways to unmute are:
-- by calling the API (see [mute section](../../../Docs/rest_api.md#switch-mute-status))
-- If running on Raspberry, by using the unmute button. (See the section [Raspberry LED and mute button](../../../Docs/settings.md#raspberry-led-and-mute-button))
+Once this neuron is used, and Kalliope deaf, the hotword is deactivated. Only ways to undeaf are:
+- by calling the API (see [deaf section](../../../Docs/rest_api.md#switch-deaf-status))
+- If running on Raspberry, by using the undeaf button. (See the section [Raspberry LED and deaf button](../../../Docs/settings.md#raspberry-led-and-deaf-button))
 - by using another signals than a "vocal order" that call back this neuron with a status set to "False"
 - by using another signals than a "vocal order" that call back this neuron with a status set to "False"
 - Restarting Kalliope
 - Restarting Kalliope
 
 
@@ -23,28 +23,28 @@ Not returned values
 
 
 ## Synapses example
 ## Synapses example
 
 
-Mute Kalliope from a vocal order
+Deaf Kalliope from a vocal order
 ```yml
 ```yml
-- name: "mute-synapse"
+- name: "deaf-synapse"
   signals:
   signals:
     - order: "stop listening"
     - order: "stop listening"
   neurons:
   neurons:
     - say:
     - say:
         message:
         message:
           - "I stop hearing you, sir"
           - "I stop hearing you, sir"
-    - mute:
+    - deaf:
         status: True
         status: True
 ```
 ```
 
 
-Unmute Kalliope from another signals. In the following example, a MQTT message is received
+Undeaf Kalliope from another signals. In the following example, a MQTT message is received
 ```yml
 ```yml
-- name: "unmute-synapse"
+- name: "undeaf-synapse"
   signals:
   signals:
     - mqtt_subscriber:
     - mqtt_subscriber:
         broker_ip: "127.0.0.1"
         broker_ip: "127.0.0.1"
         topic: "/my/sensor"
         topic: "/my/sensor"
   neurons:
   neurons:
-    - mute:
+    - deaf:
         status: False
         status: False
     - say:
     - say:
         message:
         message:

+ 0 - 0
kalliope/neurons/mute/__init__.py → kalliope/neurons/deaf/__init__.py


+ 5 - 4
kalliope/neurons/mute/mute.py → kalliope/neurons/deaf/deaf.py

@@ -2,15 +2,16 @@ import logging
 
 
 from kalliope import SignalLauncher
 from kalliope import SignalLauncher
 from kalliope.core.NeuronModule import NeuronModule
 from kalliope.core.NeuronModule import NeuronModule
+from kalliope.core.ConfigurationManager.SettingEditor import SettingEditor
 
 
 logging.basicConfig()
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
 logger = logging.getLogger("kalliope")
 
 
 
 
-class Mute(NeuronModule):
+class Deaf(NeuronModule):
 
 
     def __init__(self, **kwargs):
     def __init__(self, **kwargs):
-        super(Mute, self).__init__(**kwargs)
+        super(Deaf, self).__init__(**kwargs)
 
 
         self.status = kwargs.get('status', None)
         self.status = kwargs.get('status', None)
 
 
@@ -18,7 +19,7 @@ class Mute(NeuronModule):
         if self._is_parameters_ok():
         if self._is_parameters_ok():
             signal_order = SignalLauncher.get_order_instance()
             signal_order = SignalLauncher.get_order_instance()
             if signal_order is not None:
             if signal_order is not None:
-                signal_order.set_mute_status(self.status)
+                SettingEditor.set_deaf_status(signal_order.trigger_instance, self.status)
 
 
     def _is_parameters_ok(self):
     def _is_parameters_ok(self):
         """
         """
@@ -28,6 +29,6 @@ class Mute(NeuronModule):
         .. raises:: MissingParameterException
         .. raises:: MissingParameterException
         """
         """
         if self.status is None:
         if self.status is None:
-            logger.debug("[Mute] You must specify a status with a boolean")
+            logger.debug("[Deaf] You must specify a status with a boolean")
             return False
             return False
         return True
         return True

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

@@ -53,8 +53,7 @@ class Neurotransmitter(NeuronModule):
                                                  user_order=audio,
                                                  user_order=audio,
                                                  synapse_order=answer,
                                                  synapse_order=answer,
                                                  high_priority=True,
                                                  high_priority=True,
-                                                 is_api_call=self.is_api_call,
-                                                 no_voice=self.no_voice)
+                                                 is_api_call=self.is_api_call)
                         found = True
                         found = True
                         break
                         break
             if not found:  # the answer do not correspond to any answer. We run the default synapse
             if not found:  # the answer do not correspond to any answer. We run the default synapse

+ 1 - 2
kalliope/neurons/neurotransmitter/tests/test_neurotransmitter.py

@@ -124,8 +124,7 @@ class TestNeurotransmitter(unittest.TestCase):
                                                                  user_order=audio_text,
                                                                  user_order=audio_text,
                                                                  synapse_order="answer one",
                                                                  synapse_order="answer one",
                                                                  high_priority=True,
                                                                  high_priority=True,
-                                                                 is_api_call=False,
-                                                                 no_voice=False)
+                                                                 is_api_call=False)
 
 
     def testInit(self):
     def testInit(self):
         """
         """

+ 6 - 5
kalliope/settings.yml

@@ -119,8 +119,8 @@ hooks:
   on_order_found:
   on_order_found:
   on_order_not_found: "order-not-found-synapse"
   on_order_not_found: "order-not-found-synapse"
   on_processed_synapses:
   on_processed_synapses:
-  on_mute:
-  on_unmute:
+  on_deaf:
+  on_undeaf:
   on_start_speaking:
   on_start_speaking:
   on_stop_speaking:
   on_stop_speaking:
 
 
@@ -162,7 +162,8 @@ rest_api:
 #  - variables2.yml
 #  - variables2.yml
 
 
 # -------------
 # -------------
-# Start options
+# Options
 # -------------
 # -------------
-#start_options:
-#  muted: False
+options:
+  deaf: False
+  mute: False

+ 2 - 31
kalliope/signals/order/order.py

@@ -48,11 +48,6 @@ class Order(Thread):
         # save an instance of the trigger
         # save an instance of the trigger
         self.trigger_instance = None
         self.trigger_instance = None
         self.trigger_callback_called = False
         self.trigger_callback_called = False
-        self.is_trigger_muted = False
-
-        # If kalliope is asked to start muted
-        if self.settings.start_options['muted'] is True:
-            self.is_trigger_muted = True
 
 
         # save the current order listener
         # save the current order listener
         self.order_listener = None
         self.order_listener = None
@@ -101,8 +96,8 @@ class Order(Thread):
         Method to print in debug that the main process is waiting for a trigger detection
         Method to print in debug that the main process is waiting for a trigger detection
         """
         """
         logger.debug("[MainController] Entering state: %s" % self.state)
         logger.debug("[MainController] Entering state: %s" % self.state)
-        if self.is_trigger_muted:  # the user asked to mute inside the mute neuron
-            Utils.print_info("Kalliope is muted")
+        if self.settings.options["deaf"]:  # the user asked to deaf inside the deaf neuron
+            Utils.print_info("Kalliope is deaf")
             self.trigger_instance.pause()
             self.trigger_instance.pause()
         else:
         else:
             Utils.print_info("Waiting for trigger detection")
             Utils.print_info("Waiting for trigger detection")
@@ -179,27 +174,3 @@ class Order(Thread):
 
 
         # return to the state "unpausing_trigger"
         # return to the state "unpausing_trigger"
         self.start_trigger()
         self.start_trigger()
-
-    def set_mute_status(self, muted=False):
-        """
-        Define is the trigger is listening or not
-        :param muted: Boolean. If true, kalliope is muted
-        """
-        logger.debug("[MainController] Mute button pressed. Switch trigger process to muted: %s" % muted)
-        if muted:
-            self.trigger_instance.pause()
-            self.is_trigger_muted = True
-            Utils.print_info("Kalliope now muted")
-            HookManager.on_mute()
-        else:
-            self.trigger_instance.unpause()
-            self.is_trigger_muted = False
-            Utils.print_info("Kalliope now listening for trigger detection")
-            HookManager.on_unmute()
-
-    def get_mute_status(self):
-        """
-        return the current state of the trigger (muted or not)
-        :return: Boolean
-        """
-        return self.is_trigger_muted