示例#1
0
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()
示例#2
0
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
示例#3
0
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)
示例#4
0
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__})
示例#5
0
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
示例#6
0
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()
示例#7
0
    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', '')))
示例#9
0
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()
示例#10
0
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()
示例#11
0
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)
示例#12
0
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()
示例#13
0
    # 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)