import logging import os import random from flask import Flask from core import Utils from core.ConfigurationManager import SettingLoader from core.OrderAnalyser import OrderAnalyser from core.OrderListener import OrderListener from core.Players import Mplayer from core.RestAPI.FlaskAPI import FlaskAPI from core.TriggerLauncher import TriggerLauncher from neurons.say.say import Say logging.basicConfig() logger = logging.getLogger("kalliope") class MainController: """ This Class is the global controller of the application. """ def __init__(self, brain=None): self.brain = brain # get global configuration self.settings = SettingLoader.get_settings() # run the api if the user want it if self.settings.rest_api.active: Utils.print_info("Starting REST API Listening port: %s" % self.settings.rest_api.port) app = Flask(__name__) flask_api = FlaskAPI(app, port=self.settings.rest_api.port, brain=self.brain) flask_api.daemon = True flask_api.start() # create an order listener object. This last will the trigger callback before starting self.order_listener = OrderListener(self.analyse_order) # Wait that the kalliope trigger is pronounced by the user self.trigger_instance = self._get_default_trigger() self.trigger_instance.start() Utils.print_info("Waiting for trigger detection") def callback(self): """ we have detected the hotword, we can now pause the Trigger for a while The user can speak out loud his order during this time. """ # pause the trigger process self.trigger_instance.pause() # start listening for an order self.order_listener.start() # if random wake answer sentence are present, we play this if self.settings.random_wake_up_answers is not None: Say(message=self.settings.random_wake_up_answers) else: random_sound_to_play = self._get_random_sound(self.settings.random_wake_up_sounds) Mplayer.play(random_sound_to_play) def analyse_order(self, order): """ Receive an order, try to retrieve it in the brain.yml to launch to attached plugins :param order: the sentence received :type order: str """ if order is not None: # maybe we have received a null audio from STT engine order_analyser = OrderAnalyser(order, main_controller=self, brain=self.brain) order_analyser.start() # restart the trigger when the order analyser has finish his job Utils.print_info("Waiting for trigger detection") self.trigger_instance.unpause() # create a new order listener that will wait for start self.order_listener = OrderListener(self.analyse_order) def _get_default_trigger(self): """ Return an instance of the default trigger :return: Trigger """ for trigger in self.settings.triggers: if trigger.name == self.settings.default_trigger_name: return TriggerLauncher.get_trigger(trigger, callback=self.callback) @staticmethod def _get_random_sound(random_wake_up_sounds): """ Return a path of a sound to play If the path is absolute, test if file exist If the path is relative, we check if the file exist in the sound folder :param random_wake_up_sounds: List of wake_up sounds :return: path of a sound to play """ # take first randomly a path random_path = random.choice(random_wake_up_sounds) logger.debug("Selected sound: %s" % random_path) if os.path.isabs(random_path): logger.debug("Path of file %s is absolute" % random_path) return random_path else: logger.debug("Path of file %s is relative" % random_path) return "sounds" + os.sep + random_path