MainController.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import logging
  2. import os
  3. import random
  4. from flask import Flask
  5. from core import Utils
  6. from core.ConfigurationManager import SettingLoader
  7. from core.OrderAnalyser import OrderAnalyser
  8. from core.OrderListener import OrderListener
  9. from core.Players import Mplayer
  10. from core.RestAPI.FlaskAPI import FlaskAPI
  11. from core.TriggerLauncher import TriggerLauncher
  12. from neurons import Say
  13. logging.basicConfig()
  14. logger = logging.getLogger("kalliope")
  15. class MainController:
  16. """
  17. This Class is the global controller of the application.
  18. """
  19. def __init__(self, brain=None):
  20. self.brain = brain
  21. # get global configuration
  22. self.settings = SettingLoader.get_settings()
  23. # run the api if the user want it
  24. if self.settings.rest_api.active:
  25. Utils.print_info("Starting REST API Listening port: %s" % self.settings.rest_api.port)
  26. app = Flask(__name__)
  27. flask_api = FlaskAPI(app, port=self.settings.rest_api.port, brain=self.brain)
  28. flask_api.start()
  29. # create an order listener object. This last will the trigger callback before starting
  30. self.order_listener = OrderListener(self.analyse_order)
  31. # Wait that the kalliope trigger is pronounced by the user
  32. self.trigger_instance = self._get_default_trigger()
  33. self.trigger_instance.start()
  34. Utils.print_info("Waiting for trigger detection")
  35. def callback(self):
  36. """
  37. we have detected the hotword, we can now pause the Trigger for a while
  38. The user can speak out loud his order during this time.
  39. """
  40. # pause the trigger process
  41. self.trigger_instance.pause()
  42. # start listening for an order
  43. self.order_listener.start()
  44. # if random wake answer sentence are present, we play this
  45. if self.settings.random_wake_up_answers is not None:
  46. Say(message=self.settings.random_wake_up_answers)
  47. else:
  48. random_sound_to_play = self._get_random_sound(self.settings.random_wake_up_sounds)
  49. Mplayer.play(random_sound_to_play)
  50. def analyse_order(self, order):
  51. """
  52. Receive an order, try to retrieve it in the brain.yml to launch to attached plugins
  53. :param order: the sentence received
  54. :type order: str
  55. """
  56. if order is not None: # maybe we have received a null audio from STT engine
  57. order_analyser = OrderAnalyser(order, main_controller=self, brain=self.brain)
  58. order_analyser.start()
  59. # restart the trigger when the order analyser has finish his job
  60. Utils.print_info("Waiting for trigger detection")
  61. self.trigger_instance.unpause()
  62. # create a new order listener that will wait for start
  63. self.order_listener = OrderListener(self.analyse_order)
  64. # restart the trigger to catch the hotword
  65. self.trigger_instance.start()
  66. def _get_default_trigger(self):
  67. """
  68. Return an instance of the default trigger
  69. :return: Trigger
  70. """
  71. for trigger in self.settings.triggers:
  72. if trigger.name == self.settings.default_trigger_name:
  73. return TriggerLauncher.get_trigger(trigger, callback=self.callback)
  74. @staticmethod
  75. def _get_random_sound(random_wake_up_sounds):
  76. """
  77. Return a path of a sound to play
  78. If the path is absolute, test if file exist
  79. If the path is relative, we check if the file exist in the sound folder
  80. :param random_wake_up_sounds: List of wake_up sounds
  81. :return: path of a sound to play
  82. """
  83. # take first randomly a path
  84. random_path = random.choice(random_wake_up_sounds)
  85. logger.debug("Selected sound: %s" % random_path)
  86. if os.path.isabs(random_path):
  87. logger.debug("Path of file %s is absolute" % random_path)
  88. return random_path
  89. else:
  90. logger.debug("Path of file %s is relative" % random_path)
  91. return "sounds" + os.sep + random_path