merge with master

pull/195/head
Arron Atchison 2016-06-02 20:15:24 -05:00
commit b917b62f90
11 changed files with 157 additions and 18 deletions

View File

@ -16,11 +16,12 @@
# along with Mycroft Core. If not, see <http://www.gnu.org/licenses/>.
import serial
import sys
from Queue import Queue
from threading import Thread
import serial
from mycroft.client.enclosure.arduino import EnclosureArduino
from mycroft.client.enclosure.eyes import EnclosureEyes
from mycroft.client.enclosure.mouth import EnclosureMouth
@ -143,7 +144,7 @@ class Enclosure:
self.eyes = EnclosureEyes(self.client, self.writer)
self.mouth = EnclosureMouth(self.client, self.writer)
self.system = EnclosureArduino(self.client, self.writer)
self.__init_events()
self.__register_events()
def __init_serial(self):
try:
@ -161,11 +162,30 @@ class Enclosure:
"It is not possible to connect to serial port: " + self.port)
raise
def __init_events(self):
def __register_events(self):
self.client.on('mycroft.paired', self.__update_events)
self.client.on('recognizer_loop:wakeword', self.eyes.blink)
self.__register_mouth_events()
def __register_mouth_events(self):
self.client.on('recognizer_loop:listening', self.mouth.listen)
self.client.on('recognizer_loop:audio_output_start', self.mouth.talk)
self.client.on('recognizer_loop:audio_output_end', self.mouth.reset)
self.client.on('recognizer_loop:wakeword', self.eyes.blink)
def __remove_mouth_events(self):
self.client.remove('recognizer_loop:listening', self.mouth.listen)
self.client.remove('recognizer_loop:audio_output_start',
self.mouth.talk)
self.client.remove('recognizer_loop:audio_output_end',
self.mouth.reset)
self.mouth.reset()
def __update_events(self, event=None):
if event and event.metadata:
if event.metadata.get('paired', False):
self.__register_mouth_events()
else:
self.__remove_mouth_events()
def run(self):
try:

View File

@ -81,7 +81,7 @@ class AudioConsumer(threading.Thread):
"""
# In seconds, the minimum audio size to be sent to remote STT
MIN_AUDIO_SIZE = 1.0
MIN_AUDIO_SIZE = 0.5
def __init__(self, state, queue, emitter, wakeup_recognizer,
mycroft_recognizer, remote_recognizer):

View File

@ -17,14 +17,15 @@
import json
from multiprocessing.pool import ThreadPool
import time
from mycroft.configuration.config import ConfigurationManager
from mycroft.messagebus.message import Message
import mycroft.util.log
from multiprocessing.pool import ThreadPool
from pyee import EventEmitter
from websocket import WebSocketApp
import mycroft.util.log
from mycroft.configuration.config import ConfigurationManager
from mycroft.messagebus.message import Message
from mycroft.util import str2bool
__author__ = 'seanfitz'
@ -99,6 +100,9 @@ class WebsocketClient(object):
def once(self, event_name, func):
self.emitter.once(event_name, func)
def remove(self, event_name, func):
self.emitter.remove_listener(event_name, func)
def run_forever(self):
self.client.run_forever()

View File

@ -17,6 +17,7 @@
import shortuuid
from mycroft.configuration.config import ConfigurationManager
from mycroft.identity import IdentityManager
from mycroft.messagebus.client.ws import WebsocketClient
@ -34,6 +35,7 @@ def generate_pairing_code():
class DevicePairingClient(object):
def __init__(self, config=_config, pairing_code=None):
self.config = config
self.paired = False
self.ws_client = WebsocketClient(host=config.get("host"),
port=config.get("port"),
path=config.get("route"),
@ -53,6 +55,7 @@ class DevicePairingClient(object):
identity.owner = register_payload.get('user')
self.identity_manager.update(identity)
self.ws_client.close()
self.paired = True
def send_device_info(self):
msg = Message("device_info",
@ -63,7 +66,8 @@ class DevicePairingClient(object):
self.ws_client.emit(msg)
def print_error(self, message):
@staticmethod
def print_error(message):
print(repr(message))
def run(self):
@ -76,5 +80,6 @@ class DevicePairingClient(object):
def main():
DevicePairingClient().run()
if __name__ == "__main__":
main()

View File

@ -15,11 +15,12 @@
# You should have received a copy of the GNU General Public License
# along with Mycroft Core. If not, see <http://www.gnu.org/licenses/>.
import threading
from threading import Thread
from adapt.intent import IntentBuilder
from os.path import dirname
from mycroft.messagebus.message import Message
from mycroft.pairing.client import DevicePairingClient
from mycroft.skills.core import MycroftSkill
@ -27,21 +28,41 @@ from mycroft.skills.core import MycroftSkill
class PairingSkill(MycroftSkill):
def __init__(self):
super(PairingSkill, self).__init__(name="PairingSkill")
self.client = None
self.displaying = False
def initialize(self):
intent = IntentBuilder("PairingIntent").require(
"DevicePairingPhrase").build()
"DevicePairingPhrase").build()
self.load_data_files(dirname(__file__))
self.register_intent(intent, handler=self.handle_pairing_request)
def handle_pairing_request(self, message):
pairing_client = DevicePairingClient()
pairing_code = pairing_client.pairing_code
threading.Thread(target=pairing_client.run).start()
self.enclosure.mouth_text("Pairing code is: " + pairing_code)
if not self.client:
self.displaying = False
self.__emit_paired(False)
self.client = DevicePairingClient()
Thread(target=self.client.run).start()
self.emitter.on("recognizer_loop:audio_output_start",
self.__display_pairing_code)
self.speak_dialog(
"pairing.instructions",
data={"pairing_code": ', ,'.join(pairing_code)})
"pairing.instructions",
data={"pairing_code": ', ,'.join(self.client.pairing_code)})
def __display_pairing_code(self, event=None):
if self.client.paired:
self.enclosure.mouth_talk()
self.client = None
self.__emit_paired(True)
self.emitter.remove("recognizer_loop:audio_output_start",
self.__display_pairing_code)
elif not self.displaying:
self.displaying = True
self.enclosure.mouth_text(self.client.pairing_code)
def __emit_paired(self, paired):
msg = Message('mycroft.paired', metadata={'paired': paired})
self.emitter.emit(msg)
def stop(self):
pass

View File

@ -0,0 +1,48 @@
# Copyright 2016 Mycroft AI, Inc.
#
# This file is part of Mycroft Core.
#
# Mycroft Core is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Mycroft Core is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Mycroft Core. If not, see <http://www.gnu.org/licenses/>.
from os.path import dirname
from adapt.intent import IntentBuilder
from mycroft.skills.core import MycroftSkill
from mycroft.util.log import getLogger
__author__ = 'eward'
LOGGER = getLogger(__name__)
class WelcomeSkill(MycroftSkill):
def __init__(self):
super(WelcomeSkill, self).__init__(name="WelcomeSkill")
def initialize(self):
self.load_data_files(dirname(__file__))
welcome_intent = IntentBuilder("WelcIntent").require("WelcKey").build()
self.register_intent(welcome_intent, self.handle_welcome_intent)
def handle_welcome_intent(self, message):
self.speak_dialog('Welcome')
def stop(self):
pass
def create_skill():
return WelcomeSkill()

View File

@ -0,0 +1 @@
You're welcome.

View File

@ -0,0 +1,2 @@
thank you
thanks

View File

@ -190,3 +190,41 @@ class AudioConsumerTest(unittest.TestCase):
self.assertIsNotNone(utterances)
self.assertTrue(len(utterances) == 1)
self.assertEquals("what's the weather next week", utterances[0])
def test_stop(self):
self.queue.put(self.__create_sample_from_test_file('mycroft'))
self.consumer.read_audio()
self.queue.put(self.__create_sample_from_test_file('stop'))
self.recognizer.set_transcriptions(["stop"])
monitor = {}
def utterance_callback(message):
monitor['utterances'] = message.get('utterances')
self.loop.once('recognizer_loop:utterance', utterance_callback)
self.consumer.read_audio()
utterances = monitor.get('utterances')
self.assertIsNotNone(utterances)
self.assertTrue(len(utterances) == 1)
self.assertEquals("stop", utterances[0])
def test_record(self):
self.queue.put(self.__create_sample_from_test_file('mycroft'))
self.consumer.read_audio()
self.queue.put(self.__create_sample_from_test_file('record'))
self.recognizer.set_transcriptions(["record"])
monitor = {}
def utterance_callback(message):
monitor['utterances'] = message.get('utterances')
self.loop.once('recognizer_loop:utterance', utterance_callback)
self.consumer.read_audio()
utterances = monitor.get('utterances')
self.assertIsNotNone(utterances)
self.assertTrue(len(utterances) == 1)
self.assertEquals("record", utterances[0])

BIN
test/client/data/record.wav Normal file

Binary file not shown.

BIN
test/client/data/stop.wav Normal file

Binary file not shown.