Add support for watchdog in skills and speech client
If no watchdog is provided a dummy function will be calledpull/2601/head
parent
09b1deb511
commit
a1fdae3415
|
@ -207,7 +207,7 @@ def connect_bus_events(bus):
|
||||||
bus.on('message', create_echo_function('VOICE'))
|
bus.on('message', create_echo_function('VOICE'))
|
||||||
|
|
||||||
|
|
||||||
def main(ready_hook=on_ready, error_hook=on_error):
|
def main(ready_hook=on_ready, error_hook=on_error, watchdog=lambda: None):
|
||||||
global bus
|
global bus
|
||||||
global loop
|
global loop
|
||||||
global config
|
global config
|
||||||
|
@ -219,7 +219,7 @@ def main(ready_hook=on_ready, error_hook=on_error):
|
||||||
config = Configuration.get()
|
config = Configuration.get()
|
||||||
|
|
||||||
# Register handlers on internal RecognizerLoop bus
|
# Register handlers on internal RecognizerLoop bus
|
||||||
loop = RecognizerLoop()
|
loop = RecognizerLoop(watchdog)
|
||||||
connect_loop_events(loop)
|
connect_loop_events(loop)
|
||||||
connect_bus_events(bus)
|
connect_bus_events(bus)
|
||||||
create_daemon(bus.run_forever)
|
create_daemon(bus.run_forever)
|
||||||
|
|
|
@ -275,10 +275,15 @@ class RecognizerLoop(BaseEventEmitter):
|
||||||
""" EventEmitter loop running speech recognition.
|
""" EventEmitter loop running speech recognition.
|
||||||
|
|
||||||
Local wake word recognizer and remote general speech recognition.
|
Local wake word recognizer and remote general speech recognition.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
watchdog: (callable) function to call periodically indicating
|
||||||
|
operational status.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, watchdog=None):
|
||||||
super(RecognizerLoop, self).__init__()
|
super(RecognizerLoop, self).__init__()
|
||||||
|
self._watchdog = watchdog
|
||||||
self.mute_calls = 0
|
self.mute_calls = 0
|
||||||
self._load_config()
|
self._load_config()
|
||||||
|
|
||||||
|
@ -305,7 +310,7 @@ class RecognizerLoop(BaseEventEmitter):
|
||||||
# TODO - localization
|
# TODO - localization
|
||||||
self.wakeup_recognizer = self.create_wakeup_recognizer()
|
self.wakeup_recognizer = self.create_wakeup_recognizer()
|
||||||
self.responsive_recognizer = ResponsiveRecognizer(
|
self.responsive_recognizer = ResponsiveRecognizer(
|
||||||
self.wakeword_recognizer)
|
self.wakeword_recognizer, self._watchdog)
|
||||||
self.state = RecognizerLoopState()
|
self.state = RecognizerLoopState()
|
||||||
|
|
||||||
def create_wake_word_recognizer(self):
|
def create_wake_word_recognizer(self):
|
||||||
|
|
|
@ -336,7 +336,8 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
|
||||||
# Time between pocketsphinx checks for the wake word
|
# Time between pocketsphinx checks for the wake word
|
||||||
SEC_BETWEEN_WW_CHECKS = 0.2
|
SEC_BETWEEN_WW_CHECKS = 0.2
|
||||||
|
|
||||||
def __init__(self, wake_word_recognizer):
|
def __init__(self, wake_word_recognizer, watchdog=None):
|
||||||
|
self._watchdog = watchdog or (lambda: None) # Default to dummy func
|
||||||
self.config = Configuration.get()
|
self.config = Configuration.get()
|
||||||
listener_config = self.config.get('listener')
|
listener_config = self.config.get('listener')
|
||||||
self.upload_url = listener_config['wake_word_upload']['url']
|
self.upload_url = listener_config['wake_word_upload']['url']
|
||||||
|
@ -474,6 +475,7 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
|
||||||
|
|
||||||
# Periodically write the energy level to the mic level file.
|
# Periodically write the energy level to the mic level file.
|
||||||
if num_chunks % 10 == 0:
|
if num_chunks % 10 == 0:
|
||||||
|
self._watchdog()
|
||||||
self.write_mic_level(energy, source)
|
self.write_mic_level(energy, source)
|
||||||
|
|
||||||
return byte_data
|
return byte_data
|
||||||
|
@ -654,6 +656,7 @@ class ResponsiveRecognizer(speech_recognition.Recognizer):
|
||||||
# Periodically output energy level stats. This can be used to
|
# Periodically output energy level stats. This can be used to
|
||||||
# visualize the microphone input, e.g. a needle on a meter.
|
# visualize the microphone input, e.g. a needle on a meter.
|
||||||
if mic_write_counter % 3:
|
if mic_write_counter % 3:
|
||||||
|
self._watchdog()
|
||||||
self.write_mic_level(energy, source)
|
self.write_mic_level(energy, source)
|
||||||
mic_write_counter += 1
|
mic_write_counter += 1
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ def on_error(e='Unknown'):
|
||||||
LOG.info('Skill service failed to launch ({})'.format(repr(e)))
|
LOG.info('Skill service failed to launch ({})'.format(repr(e)))
|
||||||
|
|
||||||
|
|
||||||
def main(ready_hook=on_ready, error_hook=on_error):
|
def main(ready_hook=on_ready, error_hook=on_error, watchdog=None):
|
||||||
reset_sigint_handler()
|
reset_sigint_handler()
|
||||||
# Create PID file, prevent multiple instances of this service
|
# Create PID file, prevent multiple instances of this service
|
||||||
mycroft.lock.Lock('skills')
|
mycroft.lock.Lock('skills')
|
||||||
|
@ -193,7 +193,7 @@ def main(ready_hook=on_ready, error_hook=on_error):
|
||||||
bus = _start_message_bus_client()
|
bus = _start_message_bus_client()
|
||||||
_register_intent_services(bus)
|
_register_intent_services(bus)
|
||||||
event_scheduler = EventScheduler(bus)
|
event_scheduler = EventScheduler(bus)
|
||||||
skill_manager = _initialize_skill_manager(bus)
|
skill_manager = _initialize_skill_manager(bus, watchdog)
|
||||||
|
|
||||||
_wait_for_internet_connection()
|
_wait_for_internet_connection()
|
||||||
|
|
||||||
|
@ -244,14 +244,14 @@ def _register_intent_services(bus):
|
||||||
bus.on('intent_failure', FallbackSkill.make_intent_failure_handler(bus))
|
bus.on('intent_failure', FallbackSkill.make_intent_failure_handler(bus))
|
||||||
|
|
||||||
|
|
||||||
def _initialize_skill_manager(bus):
|
def _initialize_skill_manager(bus, watchdog):
|
||||||
"""Create a thread that monitors the loaded skills, looking for updates
|
"""Create a thread that monitors the loaded skills, looking for updates
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
SkillManager instance or None if it couldn't be initialized
|
SkillManager instance or None if it couldn't be initialized
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
skill_manager = SkillManager(bus)
|
skill_manager = SkillManager(bus, watchdog)
|
||||||
skill_manager.load_priority()
|
skill_manager.load_priority()
|
||||||
except MsmException:
|
except MsmException:
|
||||||
# skill manager couldn't be created, wait for network connection and
|
# skill manager couldn't be created, wait for network connection and
|
||||||
|
|
|
@ -110,14 +110,17 @@ def _shutdown_skill(instance):
|
||||||
class SkillManager(Thread):
|
class SkillManager(Thread):
|
||||||
_msm = None
|
_msm = None
|
||||||
|
|
||||||
def __init__(self, bus):
|
def __init__(self, bus, watchdog=None):
|
||||||
"""Constructor
|
"""Constructor
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
bus (event emitter): Mycroft messagebus connection
|
bus (event emitter): Mycroft messagebus connection
|
||||||
|
watchdog (callable): optional watchdog function
|
||||||
"""
|
"""
|
||||||
super(SkillManager, self).__init__()
|
super(SkillManager, self).__init__()
|
||||||
self.bus = bus
|
self.bus = bus
|
||||||
|
# Set watchdog to argument or function returning None
|
||||||
|
self._watchdog = watchdog or (lambda: None)
|
||||||
self._stop_event = Event()
|
self._stop_event = Event()
|
||||||
self._connected_event = Event()
|
self._connected_event = Event()
|
||||||
self.config = Configuration.get()
|
self.config = Configuration.get()
|
||||||
|
@ -243,6 +246,7 @@ class SkillManager(Thread):
|
||||||
self.skill_updater.post_manifest()
|
self.skill_updater.post_manifest()
|
||||||
self.upload_queue.send()
|
self.upload_queue.send()
|
||||||
|
|
||||||
|
self._watchdog()
|
||||||
sleep(2) # Pause briefly before beginning next scan
|
sleep(2) # Pause briefly before beginning next scan
|
||||||
except Exception:
|
except Exception:
|
||||||
LOG.exception('Something really unexpected has occured '
|
LOG.exception('Something really unexpected has occured '
|
||||||
|
|
Loading…
Reference in New Issue