Enhance the behavior of the Mark 1 button (#1668)

The Mark 1 button press can now be "consumed" when a skill handles
the Stop command.  When this happens, the button press will not
trigger listening mode.  An additional press would be needed to
trigger listening.

This introduces the "mycroft.stop.handled" messagebus message.  It
carries a data field called "by" which identifies who handled it.
Currently the values are "TTS" for when speaking ends or the name
of a skill which implements Stop and returns True from the call.

Also fixed a potential bug when the flag to clear queued visemes
was left set after a button press.
pull/1657/head
Steve Penrod 2018-07-05 13:56:54 -05:00 committed by Åke
parent db4740d407
commit 17aab53fae
4 changed files with 29 additions and 17 deletions

View File

@ -21,6 +21,7 @@ from mycroft.metrics import report_timing, Stopwatch
from mycroft.tts import TTSFactory
from mycroft.util import create_signal, check_for_signal
from mycroft.util.log import LOG
from mycroft.messagebus.message import Message
ws = None # TODO:18.02 - Rename to "messagebus"
config = None
@ -129,11 +130,12 @@ def handle_stop(event):
_last_stop_signal = time.time()
tts.playback.clear_queue()
tts.playback.clear_visimes()
ws.emit(Message("mycroft.stop.handled", {"by": "TTS"}))
def init(websocket):
"""
Start speach related handlers
Start speech related handlers
"""
global ws

View File

@ -32,7 +32,7 @@ from mycroft.configuration import Configuration, LocalConf, USER_CONFIG
from mycroft.messagebus.client.ws import WebsocketClient
from mycroft.messagebus.message import Message
from mycroft.util import play_wav, create_signal, connected, \
wait_while_speaking
wait_while_speaking, check_for_signal
from mycroft.util.audio_test import record
from mycroft.util.log import LOG
from queue import Queue
@ -62,6 +62,9 @@ class EnclosureReader(Thread):
self.lang = lang or 'en-us'
self.start()
# Notifications from mycroft-core
self.ws.on("mycroft.stop.handled", self.on_stop_handled)
def read(self):
while self.alive:
try:
@ -71,6 +74,10 @@ class EnclosureReader(Thread):
except Exception as e:
LOG.error("Reading error: {0}".format(e))
def on_stop_handled(self, event):
# A skill performed a stop
check_for_signal('buttonPress')
def process(self, data):
# TODO: Look into removing this emit altogether.
# We need to check if any other serial bus messages

View File

@ -25,7 +25,7 @@ import abc
import re
from adapt.intent import Intent, IntentBuilder
from os.path import join, abspath, dirname, basename, exists
from threading import Event
from threading import Event, Timer
from mycroft import dialog
from mycroft.api import DeviceApi
@ -253,9 +253,9 @@ class MycroftSkill(object):
def bind(self, emitter):
""" Register emitter with skill. """
if emitter:
self.emitter = emitter
self.emitter = emitter # TODO:18.08 - move to self.messagbus name
self.enclosure = EnclosureAPI(emitter, self.name)
self.__register_stop()
self.add_event('mycroft.stop', self.__handle_stop)
self.add_event('mycroft.skill.enable_intent',
self.handle_enable_intent)
self.add_event('mycroft.skill.disable_intent',
@ -266,12 +266,6 @@ class MycroftSkill(object):
emitter.on(name, func)
self.events.append((name, func))
def __register_stop(self):
self.stop_time = time.time()
self.stop_threshold = self.config_core.get("skills").get(
'stop_threshold')
self.add_event('mycroft.stop', self.__handle_stop)
def detach(self):
for (name, intent) in self.registered_intents:
name = str(self.skill_id) + ':' + name
@ -903,10 +897,22 @@ class MycroftSkill(object):
Handler for the "mycroft.stop" signal. Runs the user defined
`stop()` method.
"""
self.stop_time = time.time()
def __stop_timeout():
# The self.stop() call took more than 100ms, assume it handled Stop
self.emitter.emit(
Message("mycroft.stop.handled",
{"skill_id": str(self.skill_id) + ":"}))
timer = Timer(0.1, __stop_timeout) # set timer for 100ms
try:
self.stop()
if self.stop():
self.emitter.emit(
Message("mycroft.stop.handled",
{"by": "skill:"+str(self.skill_id)}))
timer.cancel()
except:
timer.cancel()
LOG.error("Failed to stop skill: {}".format(self.name),
exc_info=True)
@ -914,10 +920,6 @@ class MycroftSkill(object):
def stop(self):
pass
def is_stop(self):
passed_time = time.time() - self.stop_time
return passed_time < self.stop_threshold
def shutdown(self):
"""
This method is intended to be called during the skill

View File

@ -107,6 +107,7 @@ class PlaybackThread(Thread):
if self.queue.empty():
self.tts.end_audio()
self._processing_queue = False
self._clear_visimes = False
self.blink(0.2)
except Empty:
pass