MainController.py 4.0 KB

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