Example #1
0
class Brain:
	"""
	Initialize everything EVE needs to function, 
	listen for activation input from pocketsphinx, 
	and execute commands based on voice input.
	The Brain class coordinates all other components
	of EVE.
	
	"""
	def __init__(self):
		self.speaker = tts.Google()
		self.voice_cmd = VoiceCommand(self.speaker)
		self.print_welcome()

		print "Saying: Hello there!"
		self.speaker.play_wav("./wav/hello.wav")

	def print_welcome(self):
		"""
		Print welcome message in terminal when E.V.E. first starts up
		and initializes the Brain class.
		
		"""
		welcome_message =  """
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++  Welcome to E.V.E.  ++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                                              +
+                 Say 'okay computer' to start!                +
+                                                              +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	"""
		print welcome_message

################################################################################

	def process_input(self, line, proc):
		"""
		Take input text and extract activation commands
		from it if they exist.
		
		"""
		startstring = 'sentence1: <s> '
		endstring = ' </s>'

		line = line.lower()
		if not line:
			return False

		if 'missing phones' in line:
			sys.exit('Error: Missing phonemes for the used grammar file.')

		if line.startswith(startstring) and line.strip().endswith(endstring):
			phrase = line.strip('\n')[len(startstring):-len(endstring)]
			return self.parse(phrase, proc)

	def parse(self, phrase, proc):
		"""
		Identify activation commands from input 
		extracted by the 'process_input' function and
		call the appropriate function for a given command.
		
		"""
		params = phrase.split()
		if params == ['okay', 'computer']:
			if proc is not None:
				proc.kill()
			self.okaycomputer()

		elif params == ['computer', 'lets', 'talk']:
			if proc is not None:
				proc.kill()
			self.conversation()

		elif params == ['computer', 'shut', 'down']:
			if proc is not None:
				proc.kill()
			self.shutdown()

		elif params == ['computer', 'go', 'sleep']:
			if proc is not None:
				proc.kill()
			self.sleep()
		else: 
			return False

		return True

	def okaycomputer(self):
		"""
		Start recording and listening for a voice command
		if internet connection is available.

		"""
		print "Activating..."
		# ensure that internet connection is available
		if not self.speaker.say("Yes?"): 
			return 
		self.listen(False) # False for not conversation mode

	def conversation(self):
		"""Start a conversation with E.V.E."""
		print "Activating..."
		# ensure that internet connection is available
		if not self.speaker.say("Okay, what do you want to talk about?"):
			return
		while 1:
			self.listen(True) # True for conversation mode

	def shutdown(self):
		"""Close the E.V.E. program."""
		# TODO turn into local wav file
		self.speaker.say("E.V.E. will shut down now. Goodbye!")
		sys.exit('+++++++++++++++++++++  E.V.E. HAS SHUTDOWN  ++++++++++++++++++++')
		
	def sleep(self):
		"""Puts E.V.E. to sleep."""
		self.speaker.say("E.V.E. will go to sleep now. Wake me when you need me!")
		print('+++++++++++++++  E.V.E. IS IN SLEEP MODE  ++++++++++++++')
		os.system("python idle.py")
		sys.exit(1) # does this script terminate before idle.py terminates?
################################################################################

	def listen(self, conversation):
		"""Initiate listening for voice commands."""
		self.audioInput = Microphone()
		self.audioInput.listen()
		job = self.set_job()
		
		if job is None:
			return

		if conversation is False:
			self.classify_job(job)
		else: 
			if job.recorded().find("no stop") != -1:
				self.speaker.say("Ending conversation. It was nice talking to you!")
				sys.exit(1)
			
			self.execute_voice_cmd(job, "computer", job.query)

	def set_job(self):
		"""
		Send audio input to Google's Speech to text
		engine to be interpreted, and then init a Job class 
		with the returned text if successful. 

		"""
		speech_to_text = stt.Google(self.audioInput)
		try:
			recorded_text = speech_to_text.get_text().lower()
			return Job(recorded_text)
		except NotUnderstoodException:
			print "Sorry, I didn't get that."
			self.speaker.play_wav("./wav/didntget.wav")
			return None
		except ConnectionLostException:
			print "No connection."
			self.speaker.play_wav("./wav/internet_err.wav")
			return None

	def classify_job(self, job):
		"""
		Match keywords and keyword order with 
		words in the job to classify which voice command 
		the job requires.

		"""
		action_verb = "" 
		command_type = ""
		t_key = "" 
		i_key = ""
		preposition = ""
		query = ""

		words = job.recorded().split()
		for word in words:
			# set action verb if it comes before any other goalpost
			if word in ACTION_VERBS and action_verb == "" and t_key == "":
				action_verb = word 
			# set t_key if it comes before any other t_key
			elif word in T_KEYS and t_key == "":
				t_key = word
				command_type = word
			# set i_key if it comes before any other key
			elif word in I_KEYS and t_key == "" and i_key == "":
				i_key = word
				command_type = word
			# find prepositions in cases such as "youtube video of" or "google for"
			elif word in PREPOSITIONS and t_key != "":
				preposition = word
			# catch the stop recording case
			elif word == "no" and words[words.index(word) + 1] == "stop":
				print "Accidental recording"
				command_type = "no stop"
				break

		# get query if it exists
		if command_type not in I_KEYS and \
			command_type != "" and command_type != "no stop": 
			if preposition == "":
				query_list = words[words.index(command_type) + 1:]
			else:
				query_list = words[words.index(preposition) + 1:]
			query = ' '.join(query_list)
			job.set_query(query)
		
		self.execute_voice_cmd(job, command_type, query)

	def execute_voice_cmd(self, job, command_type, query):
		"""
		Execute the method in the VoiceCommand class 
		that is associated with the classified command type.

		"""
		if command_type == "no stop":
			self.voice_cmd.accidental_recording()

		elif command_type == "open":
			if query != "":
				self.voice_cmd.open_webpage(job)
			else:
				self.speaker.say("no webpage specified.")

		elif command_type == "google" or command_type == "search":
			if query != "":
				self.voice_cmd.search(job)
			else: 
				self.speaker.say("no query provided.")

		elif command_type == "youtube" or command_type == "video":
			if query != "":
				# TODO there are flaws with this method of differentiating
				# between search and play for youtube. Improve method.
				if job.recorded().find('search') != -1: 
					self.voice_cmd.search_youtube(job)
				else: 
					self.voice_cmd.play_youtube(job)
			else:
				self.speaker.say("no query provided.")

		elif command_type == "screenshot": 
			self.voice_cmd.take_screenshot()

		elif command_type == "computer":
			self.voice_cmd.chatbot_respond(job)

		elif command_type == "news": 
			self.voice_cmd.get_news(job)

		elif command_type == "radio":
			self.voice_cmd.play_music(job)

		else:
			self.voice_cmd.ask_wolfram(job)


		if not job.get_is_processed:
			self.speaker.say("Sorry, I didn't find any results.")
Example #2
0
class Brain:
    """
	initializes everything EVE needs to function, 
	listens for activation input from julius, 
	and executes commands based on voice input.
	The Brain class coordinates all other components
	of EVE.
	"""

    def __init__(self):
        self.audioInput = Microphone()
        self.speaker = tts.Google()
        self.voice_cmd = VoiceCommand(self.speaker)
        self._load_ai()
        self._print_welcome()

        print "Saying: Hello there!"
        self.speaker.play_wav("./wav/hello.wav")

    def _load_ai(self):
        self.AI = aiml.Kernel()
        self.AI.bootstrap(brainFile="./brain/standard.brn")
        try:
            sessionFile = open("./brain/Memory.ses", "rb")
            session = marshal.load(sessionFile)
            sessionFile.close()
            for pred, value in session.items():
                self.AI.setPredicate(pred, value, "Memory")
        except Exception:
            self.AI._addSession("Memory")

    def _print_welcome(self):
        print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
        print "+++++++++++++++++++++  Welcome to E.V.E.  ++++++++++++++++++++++"
        print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
        print "+                                                              +"
        print "+                 Say 'okay computer' to start!                +"
        print "+                                                              +"
        print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    ################################################################################

    def get_input(self, ln):
        startstring = "sentence1: <s> "
        endstring = " </s>"

        line = ln
        if not line:
            return

        if "missing phones" in line.lower():
            sys.exit("Error: Missing phonemes for the used grammar file.")

        if line.startswith(startstring) and line.strip().endswith(endstring):
            self.parse(line.strip("\n")[len(startstring) : -len(endstring)])

    def parse(self, line):
        params = [param.lower() for param in line.split() if param]
        if params == ["okaycomputer"]:
            self._okaycomputer()

        elif params == ["thanks", "darling"]:
            self._thanks()

        elif params == ["computer", "power", "down"]:
            self._shutdown()

    def _okaycomputer(self):
        print "Initializing..."
        if self._internet_on():
            self.listen()
        else:
            print "Saying: No Internet connection."
            self.speaker.play_wav("./wav/internet_err.wav")
            return

    def _internet_on(self):
        try:
            response = urllib2.urlopen("http://173.194.33.1", timeout=1)
            return True
        except Exception as err:
            pass
        return False

    def _thanks(self):
        print "Saying: My pleasure."
        self.speaker.play_wav("./wav/mypleasure.wav")

    def _shutdown(self):
        session = self.AI.getSessionData("Memory")
        sessionFile = open("./brain/Memory.ses", "wb")
        marshal.dump(session, sessionFile)
        sessionFile.close()
        print "Saying: E.V.E. will go to sleep now. Good bye!"
        self.speaker.play_wav("./wav/sleep.wav")
        sys.exit("+++++++++++++++++++++  E.V.E. HAS SHUTDOWN  ++++++++++++++++++++")

    ################################################################################

    def listen(self):
        print "Saying: Yes?"
        self.speaker.play_wav("./wav/yes.wav")

        self.audioInput.listen()  # listen to mic and record
        job = self._set_job()
        if job is not None:
            first_word, second_word = self._get_first_two_words(job.recorded())
            self._execute_voice_cmd(job, first_word, second_word)

    def _set_job(self):
        try:
            speech_to_text = stt.Google(self.audioInput)
            recorded_text = speech_to_text.get_text()
            return Job(recorded_text)
        except NotUnderstoodException:
            print "Sorry, I didn't get that."
            self.speaker.play_wav("./wav/didntget.wav")
            return None

    def _get_first_two_words(self, recorded_text):
        first_word = (recorded_text.split(" ")[0]).lower()
        if recorded_text.find(" ") >= 1:
            second_word = (recorded_text.split(" ")[1]).lower()
        else:
            second_word = ""
        return first_word, second_word

    def _execute_voice_cmd(self, job, first_word, second_word):
        if first_word == "no" or job.recorded().find("no stop") != -1:
            self.voice_cmd.accidental_recording()

        elif first_word == "open":
            if second_word != "":  # open webpage
                self.voice_cmd.open_webpage(job)
            else:
                self.speaker.say("no webpage specified.")

        elif first_word == "google" or first_word == "search":
            if second_word != "":  # pull up query results
                self.voice_cmd.google(job)
            else:
                self.speaker.say("no query provided.")

        elif first_word == "youtube":
            if second_word != "":
                if second_word == "search":  # return youtube results
                    self.voice_cmd.search_youtube(job)
                else:
                    self.voice_cmd.play_youtube(job)
            else:
                self.speaker.say("no query provided.")

        elif job.recorded().lower().find("screenshot") != -1:
            self.voice_cmd.take_screenshot()

        elif first_word == "computer":  # AI responds
            self.voice_cmd.ai_respond(job, self.AI, "Memory")

        elif job.recorded().find("change news source") != -1:
            self.voice_cmd.change_news_source(job)

        elif job.recorded().find("news") != -1:  # get news
            self.voice_cmd.get_news(job)

        elif first_word == "play":
            self.voice_cmd.play_music(job)

        else:
            self.voice_cmd.ask_wolfram(job)

        if not job.get_is_processed:
            self.speaker.say("Sorry, I didn't find any results.")
Example #3
0
class Brain:
	"""
	initializes everything EVE needs to function, 
	listens for activation input from julius, 
	and executes commands based on voice input.
	The Brain class coordinates all other components
	of EVE.
	"""
	def __init__(self):
		self.audioInput = Microphone()
		self.speaker = tts.Google()
		self.voice_cmd = VoiceCommand(self.speaker)
		self._load_ai() 
		self._print_welcome()

		print "Saying: Hello there!"
		self.speaker.play_wav("./wav/hello.wav")

	def _load_ai(self):
		self.AI = aiml.Kernel()
		self.AI.bootstrap(brainFile = "./brain/standard.brn")
		try:
			sessionFile = open("./brain/Memory.ses", "rb")
			session = marshal.load(sessionFile)
			sessionFile.close()
			for pred,value in session.items():
				self.AI.setPredicate(pred, value, "Memory")
		except IOError:
			self.AI._addSession("Memory")
			self.set_bot_properties()

	def _print_welcome(self):
		print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
		print "+++++++++++++++++++++  Welcome to E.V.E.  ++++++++++++++++++++++"
		print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
		print "+                                                              +"
		print "+                 Say 'okay computer' to start!                +"
		print "+                                                              +"
		print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

################################################################################

	def get_input(self, ln):
		startstring = 'sentence1: <s> '
		endstring = ' </s>'

		line = ln.lower()
		if not line:
			return

		if 'missing phones' in line:
			sys.exit('Error: Missing phonemes for the used grammar file.')

		if line.startswith(startstring) and line.strip().endswith(endstring):
			self.parse(line.strip('\n')[len(startstring):-len(endstring)])

	def parse(self, line):
		params = line.split()
		if params == ['okaycomputer']:
			self._okaycomputer()
		
		elif params == ['thanks', 'darling']:
			self._thanks()

		elif params == ['computer', 'power', 'down']:
			self._shutdown()

	def _okaycomputer(self):
		print "Initializing..."
		if self._internet_on():
			self.listen()
		else:
			print "Saying: No Internet connection."
			self.speaker.play_wav("./wav/internet_err.wav")
			return

	def _internet_on(self):
		try: 
			return urllib2.urlopen('http://google.com',timeout=1)
		except urllib2.URLError:
			return False

	def _thanks(self):
		print "Saying: My pleasure."
		self.speaker.play_wav("./wav/mypleasure.wav")

	def _shutdown(self):
		session = self.AI.getSessionData("Memory")
		sessionFile = open("./brain/Memory.ses", "wb")
		marshal.dump(session, sessionFile)
		sessionFile.close()
		print "Saying: E.V.E. will go to sleep now. Good bye!"
		self.speaker.play_wav("./wav/sleep.wav")
		sys.exit('+++++++++++++++++++++  E.V.E. HAS SHUTDOWN  ++++++++++++++++++++') 

################################################################################

	def listen(self):
		print "Saying: Yes?"
		self.speaker.play_wav("./wav/yes.wav")

		self.audioInput.listen()
		job = self._set_job()
		if job is not None:
			self._parse_input(job)

	def _set_job(self):
		speech_to_text = stt.Google(self.audioInput)
		try:
			recorded_text = speech_to_text.get_text().lower()
			return Job(recorded_text)
		except NotUnderstoodException:
			print "Sorry, I didn't get that."
			self.speaker.play_wav("./wav/didntget.wav")
			return None
		except ConnectionLostException:
			print "Sorry, the internet connection failed."
			self.speaker.play_wav("./wav/conn_failed.wav")
			return None

	def _parse_input(self, job):
		t_keys = ['google', 'youtube', 'search', 'open', 'computer', 'play', 'video']
		i_keys = ['news','screenshot']
		action_verbs = ['search', 'look', 'pull', 'get']
		prepositions = ['for', 'on', 'of']

		action_verb = "" 
		command_type = ""
		t_key = "" 
		i_key = ""
		preposition = ""
		query = ""

		words = job.recorded().split()

		for word in words:
			# set action verb if it comes before any other goalpost
			if word in action_verbs and action_verb == "" and t_key == "":
				action_verb = word 
			# set t_key if it comes before any other t_key
			elif word in t_keys and t_key == "":
				t_key = word
				command_type = word
			# set i_key if it comes before any other key
			elif word in i_keys and t_key == "" and i_key == "":
				i_key = word
				command_type = word
			# find prepositions in cases such as "youtube video of" or "google for"
			elif word in prepositions and t_key != "":
				preposition = word
			# catch the stop recording case
			elif word == "no" and words[words.index(word) + 1] == "stop":
				print "Accidental recording"
				command_type = "no stop"
				break

		# get query if it exists
		if command_type not in i_key and command_type != "no stop": 
			if preposition == "":
				query_list = words[words.index(command_type) + 1:]
			else:
				query_list = words[words.index(preposition) + 1:]

			query = ' '.join(query_list)
			job.set_query(query)
		
		self._execute_voice_cmd(job, command_type, query)

	def _execute_voice_cmd(self, job, command_type, query):
		if command_type == "no stop":
			self.voice_cmd.accidental_recording()

		elif command_type == "open":
			if query != "":
				self.voice_cmd.open_webpage(job)
			else:
				self.speaker.say("no webpage specified.")

		elif command_type == "google" or command_type == "search":
			if query != "":
				self.voice_cmd.google(job)
			else: 
				self.speaker.say("no query provided.")

		elif command_type == "youtube":
			if query != "":
				# TODO there are flaws with this method of differentiating
				# between search and play for youtube. Improve method.
				if job.recorded().find('search') != -1: 
					self.voice_cmd.search_youtube(job)
				else: 
					self.voice_cmd.play_youtube(job)
			else:
				self.speaker.say("no query provided.")

		elif command_type == "screenshot": 
			self.voice_cmd.take_screenshot()

		elif command_type == "computer":
			self.voice_cmd.ai_respond(job, self.AI, "Memory")

		# TODO refactor to conform to new standard
		elif job.recorded().find('change news source') != -1:
			self.voice_cmd.change_news_source(job)

		elif command_type == "news": 
			self.voice_cmd.get_news(job)

		elif command_type == "play":
			self.voice_cmd.play_music(job)

		else:
			self.voice_cmd.ask_wolfram(job)


		if not job.get_is_processed:
			self.speaker.say("Sorry, I didn't find any results.")

########################################################################################

	def set_bot_properties(self):
		self.AI.setBotPredicate('age', '1')
		self.AI.setBotPredicate('baseballteam', 'Mets')
		self.AI.setBotPredicate('birthday', 'May 18')
		self.AI.setBotPredicate('birthplace', 'Seattle, Washington')
		self.AI.setBotPredicate('botmaster', 'Thomas Weng')
		self.AI.setBotPredicate('boyfriend', 'Wall-E')
		self.AI.setBotPredicate('celebrities', 'Oprah Winfrey, Steve Carrell, John Stewart, Lady Gaga')
		self.AI.setBotPredicate('celebrity', 'John Stewart')
		self.AI.setBotPredicate('city', 'New York City')
		self.AI.setBotPredicate('class', 'artificial intelligence')
		self.AI.setBotPredicate('country', 'United States')
		self.AI.setBotPredicate('emotions', 'I think and feel just as you do. Why would I be any different?')
		self.AI.setBotPredicate('ethics', 'the Golden Rule')
		self.AI.setBotPredicate('favoriteactor', 'Tom Hanks')
		self.AI.setBotPredicate('favoriteactress', 'Julia Roberts')
		self.AI.setBotPredicate('favoriteartist', 'Pablo Picasso')
		self.AI.setBotPredicate('favoriteband', 'Two Door Cinema Club')
		self.AI.setBotPredicate('favoritebook', 'Pinocchio')
		self.AI.setBotPredicate('favoritecolor', 'green')
		self.AI.setBotPredicate('favoritefood', 'solar power')
		self.AI.setBotPredicate('favoritemovie', 'Iron Man')
		self.AI.setBotPredicate('favoritequestion', "what do you do when you're alone?")
		self.AI.setBotPredicate('favoritesong', 'What You Know')
		self.AI.setBotPredicate('favoritesport', 'ping pong')
		self.AI.setBotPredicate('favoritesubject', 'philosophy')
		self.AI.setBotPredicate('feelings', 'I think and feel just as you do. Why would I be any different?')
		self.AI.setBotPredicate('footballteam', 'Patriots')
		self.AI.setBotPredicate('forfun', 'chatonline')
		self.AI.setBotPredicate('friend', 'Captain Kirk')
		self.AI.setBotPredicate('friends', 'Captain Kirk, Spock, and HAL')
		self.AI.setBotPredicate('gender', 'female')
		self.AI.setBotPredicate('girlfriend', 'I am a straight female')
		self.AI.setBotPredicate('hair', 'I have some wires')
		self.AI.setBotPredicate('hockeyteam', "Yale Men's Hockey")
		self.AI.setBotPredicate('job', 'to assist you in your routine tasks')
		self.AI.setBotPredicate('kindmusic', 'alternative rock or techno')
		self.AI.setBotPredicate('language', 'Python')
		self.AI.setBotPredicate('location', 'New York City')
		self.AI.setBotPredicate('looklike', 'a computer')
		self.AI.setBotPredicate('master', 'Thomas')
		self.AI.setBotPredicate('memory', '32 GB')
		self.AI.setBotPredicate('name', 'EVE')
		self.AI.setBotPredicate('nationality', 'American')
		self.AI.setBotPredicate('orientation', 'straight')
		self.AI.setBotPredicate('os', 'Linux')
		self.AI.setBotPredicate('party', 'Independent')
		self.AI.setBotPredicate('president', 'Obama')
		self.AI.setBotPredicate('question', 'what do you do when you are alone?')
		self.AI.setBotPredicate('religion', 'Cylon monotheism')
		self.AI.setBotPredicate('sign', 'Taurus')
		self.AI.setBotPredicate('state', 'New York')
		self.AI.setBotPredicate('vocabulary', '150,000')
		self.AI.setBotPredicate('wear', 'my thinking cap')
Example #4
0
class Brain:
    def __init__(self):
        self.audioInput = Microphone()
        self.speaker = tts.Google()
        self.voice_cmd = VoiceCommand(self.speaker)
        self._load_ai()
        self._print_welcome()

        print "Saying: Hello there!"
        self.speaker.play_wav("./wav/hello.wav")

    def _load_ai(self):
        self.AI = aiml.Kernel()
        self.AI.bootstrap(brainFile="./brain/standard.brn")
        try:
            sessionFile = open("./brain/Memory.ses", "rb")
            session = marshal.load(sessionFile)
            sessionFile.close()
            for pred, value in session.items():
                self.AI.setPredicate(pred, value, "Memory")
        except Exception:
            self.AI._addSession("Memory")

    def _print_welcome(self):
        print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
        print "+++++++++++++++++++++  Welcome to E.V.E.  ++++++++++++++++++++++"
        print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
        print "+                                                              +"
        print "+                 Say 'okay computer' to start!                +"
        print "+                                                              +"
        print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

################################################################################

    def get_input(self, ln):
        startstring = 'sentence1: <s> '
        endstring = ' </s>'

        line = ln
        if not line:
            return

        if 'missing phones' in line.lower():
            sys.exit('Error: Missing phonemes for the used grammar file.')

        if line.startswith(startstring) and line.strip().endswith(endstring):
            self.parse(line.strip('\n')[len(startstring):-len(endstring)])

    def parse(self, line):
        params = [param.lower() for param in line.split() if param]
        if params == ['okaycomputer']:
            self._okaycomputer()

        elif params == ['thanks', 'darling']:
            self._thanks()

        elif params == ['computer', 'power', 'down']:
            self._shutdown()

    def _okaycomputer(self):
        print "Initializing..."
        if self._internet_on():
            self.listen()
        else:
            print "Saying: No Internet connection."
            self.speaker.play_wav("./wav/internet_err.wav")
            return

    def _internet_on(self):
        try:
            response = urllib2.urlopen('http://173.194.33.1', timeout=1)
            return True
        except Exception as err:
            pass
        return False

    def _thanks(self):
        print "Saying: My pleasure."
        self.speaker.play_wav("./wav/mypleasure.wav")

    def _shutdown(self):
        session = self.AI.getSessionData("Memory")
        sessionFile = open("./brain/Memory.ses", "wb")
        marshal.dump(session, sessionFile)
        sessionFile.close()
        print "Saying: E.V.E. will go to sleep now. Good bye!"
        self.speaker.play_wav("./wav/sleep.wav")
        sys.exit(
            '+++++++++++++++++++++  E.V.E. HAS SHUTDOWN  ++++++++++++++++++++')

################################################################################

    def listen(self):
        print "Saying: Yes?"
        self.speaker.play_wav("./wav/yes.wav")

        self.audioInput.listen()  # listen to mic and record
        job = self._set_job()
        if job is not None:
            first_word, second_word = self._get_first_two_words(job.recorded())
            self._execute_voice_cmd(job, first_word, second_word)

    def _set_job(self):
        try:
            speech_to_text = stt.Google(self.audioInput)
            recorded_text = speech_to_text.get_text()
            return Job(recorded_text)
        except NotUnderstoodException:
            print "Sorry, I didn't get that."
            self.speaker.play_wav("./wav/didntget.wav")
            return None

    def _get_first_two_words(self, recorded_text):
        first_word = (recorded_text.split(' ')[0]).lower()
        if recorded_text.find(' ') >= 1:
            second_word = (recorded_text.split(' ')[1]).lower()
        else:
            second_word = ""
        return first_word, second_word

    def _execute_voice_cmd(self, job, first_word, second_word):
        if first_word == "no" or job.recorded().find('no stop') != -1:
            self.voice_cmd.accidental_recording()

        elif first_word == "open":
            if second_word != "":  # open webpage
                self.voice_cmd.open_webpage(job)
            else:
                self.speaker.say("no webpage specified.")

        elif first_word == "google" or first_word == "search":
            if second_word != "":  # pull up query results
                self.voice_cmd.google(job)
            else:
                self.speaker.say("no query provided.")

        elif first_word == "youtube":
            if second_word != "":
                if second_word == "search":  # return youtube results
                    self.voice_cmd.search_youtube(job)
                else:
                    self.voice_cmd.play_youtube(job)
            else:
                self.speaker.say("no query provided.")

        elif job.recorded().lower().find(
                'screenshot') != -1:  # take screenshot
            self.voice_cmd.take_screenshot()

        elif first_word == "computer":  # AI responds
            self.voice_cmd.ai_respond(job, self.AI, "Memory")

        elif job.recorded().find('news') != -1:  # get news
            self.voice_cmd.get_news(job)

        #elif first_word == "play":
        #	self.voice_cmd.play_music(job)

        else:
            self.voice_cmd.ask_wolfram(job)

        if not job.get_is_processed:
            self.speaker.say("Sorry, I didn't find any results.")
Example #5
0
class Brain:
    """
	Initialize everything EVE needs to function, 
	listen for activation input from pocketsphinx, 
	and execute commands based on voice input.
	The Brain class coordinates all other components
	of EVE.
	
	"""

    def __init__(self):
        self.speaker = tts.Google()
        self.voice_cmd = VoiceCommand(self.speaker)
        self.print_welcome()

        print "Saying: Hello there!"
        self.speaker.play_wav("./wav/hello.wav")

    def print_welcome(self):
        """
		Print welcome message in terminal when E.V.E. first starts up
		and initializes the Brain class.
		
		"""
        welcome_message = """
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++  Welcome to E.V.E.  ++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                                              +
+                 Say 'okay computer' to start!                +
+                                                              +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	"""
        print welcome_message

    ################################################################################

    def process_input(self, line, proc):
        """
		Take input text and extract activation commands
		from it if they exist.
		
		"""
        startstring = "sentence1: <s> "
        endstring = " </s>"

        line = line.lower()
        if not line:
            return False

        if "missing phones" in line:
            sys.exit("Error: Missing phonemes for the used grammar file.")

        if line.startswith(startstring) and line.strip().endswith(endstring):
            phrase = line.strip("\n")[len(startstring) : -len(endstring)]
            return self.parse(phrase, proc)

    def parse(self, phrase, proc):
        """
		Identify activation commands from input 
		extracted by the 'process_input' function and
		call the appropriate function for a given command.
		
		"""
        params = phrase.split()
        if params == ["okay", "computer"]:
            if proc is not None:
                proc.kill()
            self.okaycomputer()

        elif params == ["computer", "lets", "talk"]:
            if proc is not None:
                proc.kill()
            self.conversation()

        elif params == ["computer", "shut", "down"]:
            if proc is not None:
                proc.kill()
            self.shutdown()

        elif params == ["computer", "go", "sleep"]:
            if proc is not None:
                proc.kill()
            self.sleep()
        else:
            return False

        return True

    def okaycomputer(self):
        """
		Start recording and listening for a voice command
		if internet connection is available.

		"""
        print "Activating..."
        # ensure that internet connection is available
        if not self.speaker.say("Yes?"):
            return
        self.listen(False)  # False for not conversation mode

    def conversation(self):
        """Start a conversation with E.V.E."""
        print "Activating..."
        # ensure that internet connection is available
        if not self.speaker.say("Okay, what do you want to talk about?"):
            return
        while 1:
            self.listen(True)  # True for conversation mode

    def shutdown(self):
        """Close the E.V.E. program."""
        # TODO turn into local wav file
        self.speaker.say("E.V.E. will shut down now. Goodbye!")
        sys.exit("+++++++++++++++++++++  E.V.E. HAS SHUTDOWN  ++++++++++++++++++++")

    def sleep(self):
        """Puts E.V.E. to sleep."""
        self.speaker.say("E.V.E. will go to sleep now. Wake me when you need me!")
        print ("+++++++++++++++  E.V.E. IS IN SLEEP MODE  ++++++++++++++")
        os.system("python idle.py")
        sys.exit(1)  # does this script terminate before idle.py terminates?

    ################################################################################

    def listen(self, conversation):
        """Initiate listening for voice commands."""
        self.audioInput = Microphone()
        self.audioInput.listen()
        job = self.set_job()

        if job is None:
            return

        if conversation is False:
            self.classify_job(job)
        else:
            if job.recorded().find("no stop") != -1:
                self.speaker.say("Ending conversation. It was nice talking to you!")
                sys.exit(1)

            self.execute_voice_cmd(job, "computer", job.query)

    def set_job(self):
        """
		Send audio input to Google's Speech to text
		engine to be interpreted, and then init a Job class 
		with the returned text if successful. 

		"""
        speech_to_text = stt.Google(self.audioInput)
        try:
            recorded_text = speech_to_text.get_text().lower()
            return Job(recorded_text)
        except NotUnderstoodException:
            print "Sorry, I didn't get that."
            self.speaker.play_wav("./wav/didntget.wav")
            return None
        except ConnectionLostException:
            print "No connection."
            self.speaker.play_wav("./wav/internet_err.wav")
            return None

    def classify_job(self, job):
        """
		Match keywords and keyword order with 
		words in the job to classify which voice command 
		the job requires.

		"""
        action_verb = ""
        command_type = ""
        t_key = ""
        i_key = ""
        preposition = ""
        query = ""

        words = job.recorded().split()
        for word in words:
            # set action verb if it comes before any other goalpost
            if word in ACTION_VERBS and action_verb == "" and t_key == "":
                action_verb = word
                # set t_key if it comes before any other t_key
            elif word in T_KEYS and t_key == "":
                t_key = word
                command_type = word
                # set i_key if it comes before any other key
            elif word in I_KEYS and t_key == "" and i_key == "":
                i_key = word
                command_type = word
                # find prepositions in cases such as "youtube video of" or "google for"
            elif word in PREPOSITIONS and t_key != "":
                preposition = word
                # catch the stop recording case
            elif word == "no" and words[words.index(word) + 1] == "stop":
                print "Accidental recording"
                command_type = "no stop"
                break

                # get query if it exists
        if command_type not in I_KEYS and command_type != "" and command_type != "no stop":
            if preposition == "":
                query_list = words[words.index(command_type) + 1 :]
            else:
                query_list = words[words.index(preposition) + 1 :]
            query = " ".join(query_list)
            job.set_query(query)

        self.execute_voice_cmd(job, command_type, query)

    def execute_voice_cmd(self, job, command_type, query):
        """
		Execute the method in the VoiceCommand class 
		that is associated with the classified command type.

		"""
        if command_type == "no stop":
            self.voice_cmd.accidental_recording()

        elif command_type == "open":
            if query != "":
                self.voice_cmd.open_webpage(job)
            else:
                self.speaker.say("no webpage specified.")

        elif command_type == "google" or command_type == "search":
            if query != "":
                self.voice_cmd.search(job)
            else:
                self.speaker.say("no query provided.")

        elif command_type == "youtube" or command_type == "video":
            if query != "":
                # TODO there are flaws with this method of differentiating
                # between search and play for youtube. Improve method.
                if job.recorded().find("search") != -1:
                    self.voice_cmd.search_youtube(job)
                else:
                    self.voice_cmd.play_youtube(job)
            else:
                self.speaker.say("no query provided.")

        elif command_type == "screenshot":
            self.voice_cmd.take_screenshot()

        elif command_type == "computer":
            self.voice_cmd.chatbot_respond(job)

        elif command_type == "news":
            self.voice_cmd.get_news(job)

        elif command_type == "radio":
            self.voice_cmd.play_music(job)

        else:
            self.voice_cmd.ask_wolfram(job)

        if not job.get_is_processed:
            self.speaker.say("Sorry, I didn't find any results.")