def main(ready_hook=on_ready, error_hook=on_error, stopping_hook=on_stopping): """ Main function. Run when file is invoked. """ try: reset_sigint_handler() check_for_signal("isSpeaking") bus = MessageBusClient() # Connect to the Mycroft Messagebus Configuration.set_config_update_handlers(bus) speech.init(bus) LOG.info("Starting Audio Services") bus.on('message', create_echo_function('AUDIO', ['mycroft.audio.service'])) # Connect audio service instance to message bus audio = AudioService(bus) except Exception as e: error_hook(e) else: create_daemon(bus.run_forever) if audio.wait_for_load() and len(audio.service) > 0: # If at least one service exists, report ready ready_hook() wait_for_exit_signal() stopping_hook() else: error_hook('No audio services loaded') speech.shutdown() audio.shutdown()
def start_message_bus_client(service, bus=None, whitelist=None): """Start the bus client daemon and wait for connection. Arguments: service (str): name of the service starting the connection bus (MessageBusClient): an instance of the Mycroft MessageBusClient whitelist (list, optional): List of "type" strings. If defined, only messages in this list will be logged. Returns: A connected instance of the MessageBusClient """ # Local imports to avoid circular importing from mycroft.messagebus.client import MessageBusClient from mycroft.configuration import Configuration # Create a client if one was not provided if bus is None: bus = MessageBusClient() Configuration.set_config_update_handlers(bus) bus_connected = Event() bus.on('message', create_echo_function(service, whitelist)) # Set the bus connected event when connection is established bus.once('open', bus_connected.set) create_daemon(bus.run_forever) # Wait for connection bus_connected.wait() LOG.info('Connected to messagebus') return bus
def before_all(context): log = create_voight_kampff_logger() bus = InterceptAllBusClient() bus_connected = Event() bus.once('open', bus_connected.set) create_daemon(bus.run_forever) context.msm = MycroftSkillsManager() # Wait for connection log.info('Waiting for messagebus connection...') bus_connected.wait() log.info('Waiting for skills to be loaded...') start = monotonic() while True: response = bus.wait_for_response(Message('mycroft.skills.all_loaded')) if response and response.data['status']: break elif monotonic() - start >= 2 * 60: raise Exception('Timeout waiting for skills to become ready.') else: sleep(1) context.bus = bus context.step_timeout = 10 # Reset the step_timeout to 10 seconds context.matched_message = None context.log = log context.config = Configuration.get() Configuration.set_config_update_handlers(bus)
def handle_speak(event): """Handle "speak" message Parse sentences and invoke text to speech service. """ config = Configuration.get() Configuration.set_config_update_handlers(bus) global _last_stop_signal # Get conversation ID if event.context and 'ident' in event.context: ident = event.context['ident'] else: ident = 'unknown' start = time.time() # Time of speech request with lock: stopwatch = Stopwatch() stopwatch.start() utterance = event.data['utterance'] listen = event.data.get('expect_response', False) # This is a bit of a hack for Picroft. The analog audio on a Pi blocks # for 30 seconds fairly often, so we don't want to break on periods # (decreasing the chance of encountering the block). But we will # keep the split for non-Picroft installs since it give user feedback # faster on longer phrases. # # TODO: Remove or make an option? This is really a hack, anyway, # so we likely will want to get rid of this when not running on Mimic if (config.get('enclosure', {}).get('platform') != "picroft" and len(re.findall('<[^>]*>', utterance)) == 0): # Remove any whitespace present after the period, # if a character (only alpha) ends with a period # ex: A. Lincoln -> A.Lincoln # so that we don't split at the period utterance = re.sub(r'\b([A-za-z][\.])(\s+)', r'\g<1>', utterance) chunks = re.split(r'(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\;|\?)\s', utterance) # Apply the listen flag to the last chunk, set the rest to False chunks = [(chunks[i], listen if i == len(chunks) - 1 else False) for i in range(len(chunks))] for chunk, listen in chunks: # Check if somthing has aborted the speech if (_last_stop_signal > start or check_for_signal('buttonPress')): # Clear any newly queued speech tts.playback.clear() break try: mute_and_speak(chunk, ident, listen) except KeyboardInterrupt: raise except Exception: LOG.error('Error in mute_and_speak', exc_info=True) else: mute_and_speak(utterance, ident) stopwatch.stop() report_timing(ident, 'speech', stopwatch, {'utterance': utterance, 'tts': tts.__class__.__name__})
def _start_message_bus_client(): """Start the bus client daemon and wait for connection.""" bus = MessageBusClient() Configuration.set_config_update_handlers(bus) bus_connected = Event() bus.on('message', create_echo_function('SKILLS')) # Set the bus connected event when connection is established bus.once('open', bus_connected.set) create_daemon(bus.run_forever) # Wait for connection bus_connected.wait() LOG.info('Connected to messagebus') return bus
def main(): """ Main function. Run when file is invoked. """ reset_sigint_handler() check_for_signal("isSpeaking") bus = MessageBusClient() # Connect to the Mycroft Messagebus Configuration.set_config_update_handlers(bus) speech.init(bus) LOG.info("Starting Audio Services") bus.on('message', create_echo_function('AUDIO', ['mycroft.audio.service'])) audio = AudioService(bus) # Connect audio service instance to message bus create_daemon(bus.run_forever) wait_for_exit_signal() speech.shutdown() audio.shutdown()
def __init__(self): # Establish Enclosure's websocket connection to the messagebus self.bus = MessageBusClient() # Load full config Configuration.set_config_update_handlers(self.bus) config = Configuration.get() self.lang = config['lang'] self.config = config.get("enclosure") self.global_config = config # This datastore holds the data associated with the GUI provider. Data # is stored in Namespaces, so you can have: # self.datastore["namespace"]["name"] = value # Typically the namespace is a meaningless identifier, but there is a # special "SYSTEM" namespace. self.datastore = {} # self.loaded is a list, each element consists of a namespace named # tuple. # The namespace namedtuple has the properties "name" and "pages" # The name contains the namespace name as a string and pages is a # mutable list of loaded pages. # # [Namespace name, [List of loaded qml pages]] # [ # ["SKILL_NAME", ["page1.qml, "page2.qml", ... , "pageN.qml"] # [...] # ] self.loaded = [] # list of lists in order. self.explicit_move = True # Set to true to send reorder commands # Listen for new GUI clients to announce themselves on the main bus self.GUIs = {} # GUIs, either local or remote self.active_namespaces = [] self.bus.on("mycroft.gui.connected", self.on_gui_client_connected) self.register_gui_handlers() # First send any data: self.bus.on("gui.value.set", self.on_gui_set_value) self.bus.on("gui.page.show", self.on_gui_show_page) self.bus.on("gui.page.delete", self.on_gui_delete_page) self.bus.on("gui.clear.namespace", self.on_gui_delete_namespace) self.bus.on("gui.event.send", self.on_gui_send_event)
def init(messagebus): """Start speech related handlers. Arguments: messagebus: Connection to the Mycroft messagebus """ global bus global tts global tts_hash global config bus = messagebus Configuration.set_config_update_handlers(bus) config = Configuration.get() bus.on('mycroft.stop', handle_stop) bus.on('mycroft.audio.speech.stop', handle_stop) bus.on('speak', handle_speak) tts = TTSFactory.create() tts.init(bus) tts_hash = hash(str(config.get('tts', '')))
def main(): global bus global loop global config reset_sigint_handler() PIDLock("voice") bus = MessageBusClient() # Mycroft messagebus, see mycroft.messagebus Configuration.set_config_update_handlers(bus) config = Configuration.get() # Register handlers on internal RecognizerLoop bus loop = RecognizerLoop() loop.on('recognizer_loop:utterance', handle_utterance) loop.on('recognizer_loop:speech.recognition.unknown', handle_unknown) loop.on('speak', handle_speak) loop.on('recognizer_loop:record_begin', handle_record_begin) loop.on('recognizer_loop:awoken', handle_awoken) loop.on('recognizer_loop:wakeword', handle_wakeword) loop.on('recognizer_loop:record_end', handle_record_end) loop.on('recognizer_loop:no_internet', handle_no_internet) # Register handlers for events on main Mycroft messagebus bus.on('open', handle_open) bus.on('complete_intent_failure', handle_complete_intent_failure) bus.on('recognizer_loop:sleep', handle_sleep) bus.on('recognizer_loop:wake_up', handle_wake_up) bus.on('mycroft.mic.mute', handle_mic_mute) bus.on('mycroft.mic.unmute', handle_mic_unmute) bus.on('mycroft.mic.get_status', handle_mic_get_status) bus.on('mycroft.mic.listen', handle_mic_listen) bus.on("mycroft.paired", handle_paired) bus.on('recognizer_loop:audio_output_start', handle_audio_start) bus.on('recognizer_loop:audio_output_end', handle_audio_end) bus.on('mycroft.stop', handle_stop) bus.on('message', create_echo_function('VOICE')) create_daemon(bus.run_forever) create_daemon(loop.run) wait_for_exit_signal()
def main(ready_hook=on_ready, error_hook=on_error, stopping_hook=on_stopping, watchdog=lambda: None): global bus global loop global config try: reset_sigint_handler() PIDLock("voice") bus = MessageBusClient() # Mycroft messagebus, see mycroft.messagebus Configuration.set_config_update_handlers(bus) config = Configuration.get() # Register handlers on internal RecognizerLoop bus loop = RecognizerLoop(watchdog) connect_loop_events(loop) connect_bus_events(bus) create_daemon(bus.run_forever) create_daemon(loop.run) except Exception as e: error_hook(e) else: ready_hook() wait_for_exit_signal() stopping_hook()
def before_all(context): log = create_voight_kampff_logger() bus = InterceptAllBusClient() bus_connected = Event() bus.once('open', bus_connected.set) create_daemon(bus.run_forever) context.msm = MycroftSkillsManager() # Wait for connection log.info('Waiting for messagebus connection...') bus_connected.wait() log.info('Waiting for skills to be loaded...') start = monotonic() while True: response = bus.wait_for_response(Message('mycroft.skills.all_loaded')) if response and response.data['status']: break elif monotonic() - start >= 2 * 60: raise Exception('Timeout waiting for skills to become ready.') else: sleep(1) # Temporary bugfix - First test to run sometimes fails # Sleeping to see if something isn't finished setting up when tests start # More info in Jira Ticket MYC-370 # TODO - remove and fix properly dependant on if failures continue sleep(10) context.bus = bus context.matched_message = None context.log = log context.original_config = {} context.config = Configuration.get() Configuration.set_config_update_handlers(bus)
def load_mycroft_config(bus): """ Load the mycroft config and connect it to updates over the messagebus. """ Configuration.set_config_update_handlers(bus) return Configuration.get()
# use the audio file as the audio source r = sr.Recognizer() with sr.AudioFile(wave_file) as source: audio = r.record(source) return audio class FileConsumer: def __init__(self, emitter=None): super(FileConsumer, self).__init__() self.stt = None self.emitter = emitter LOG.info("Creating SST interface") self.stt = STTFactory.create() def handle_audio(self, audiofile): audio = read_wave_file(audiofile) text = self.stt.execute(audio).lower().strip() self.emitter.emit( Message("recognizer_loop:utterance", {"utterances": [text]}, {"source": "wav_client"})) ws = MessageBusClient() config = Configuration.get() Configuration.set_config_update_handlers(ws) event_thread = Thread(target=connect) event_thread.setDaemon(True) event_thread.start() file_consumer = FileConsumer(emitter=ws)