-
Notifications
You must be signed in to change notification settings - Fork 0
/
chatbot.py
156 lines (121 loc) · 4.85 KB
/
chatbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python
#pip install cleverbot SpeechRecognition pyserial pyttsx
import speech_recognition as sr
from cleverbot import Cleverbot
import pyttsx
import urllib2
import serial
import time,subprocess,json
import random
from multiprocessing import Process
from multiprocessing import Pipe
class Chatbot(object):
port = '/dev/ttyACM1'
##########################################################################
def __init__(self):
self.cb = Cleverbot()
self.r = sr.Recognizer()
self.ard = serial.Serial(self.port, 9600, timeout=5)
self.pyttsx_engine = pyttsx.init()
##########################################################################
@property
def get_input(self):
#Get audio input from user
with sr.Microphone() as source:
print("Say something!")
audio = self.r.listen(source)
# Speech recognition using Google Speech Recognition
try:
question=""
#for testing purposes, we're just using the default API key
#to use another API key, use `r.recognize_google(audio, key="GOOGLE_SPEECH_RECOGNITION_API_KEY")`
#instead of `r.recognize_google(audio)`
question = self.r.recognize_google(audio)
print("You said: " + question)
except (sr.UnknownValueError,sr.RequestError) as e:
question="Hello"
print("Google Speech Recognition encountered an error: {0}".format(e))
return question
##########################################################################
def query_cleverbot(self,question):
#Query Cleverbot with user input
print("Calling Cleverbot!")
try:
answer=self.cb.ask(question)
print("Cleverbot said: {}".format(answer))
#For *nix systems.
#subprocess.call(["espeak", answer])
self.pyttsx_engine.say(answer)
self.pyttsx_engine.runAndWait()
except:
print("Error!")
answer="Can you repeat that?"
##########################################################################
def query_watson(self,conn,question):
# Call watson to analysis the mood of input
print("Calling Watson!")
data = str(question)
url = 'https://watson-api-explorer.mybluemix.net/tone-analyzer/api/v3/tone?version=2016-05-19'
response=""
try:
req = urllib2.Request(url, data, {'Content-Type': 'text/plain'})
f = urllib2.urlopen(req)
for line in f:
response = response + line
f.close()
response = json.loads(response)
except IOError:
print("Failed to open {0}.".format(url))
except ValueError:
print("Could not decode JSON!")
watson_mood_values = {}
moods = ("Anger", "Disgust", "Fear", "Joy", "Sadness")
#if response from watson, choose the mood with the highest score
#else pick a random mood to return
if response:
for elem in response['document_tone']['tone_categories'][0]['tones']:
#print elem['tone_name']
watson_mood_values[elem['tone_name']] = elem['score']
#print elem['score']
maximum = max(watson_mood_values, key=watson_mood_values.get)
#print(maximum, mood_values[maximum])
#return maximum
else:
maximum = random.choice(moods)
#return result to parent
conn.send(maximum)
conn.close()
##########################################################################
def send_to_arduino(self,input_mood):
try:
self.ard.flush
#convert from unicode
input_mood = str(input_mood)
print ("Python value sent: {0}".format(input_mood))
#currently writes a string to Serial on Arduino
#this can be changed
self.ard.write(input_mood)
self.ard.flush
except:
print("Failed to write to Arduino!")
time.sleep(1)
##############################################################################
if __name__ == '__main__':
chat = Chatbot()
#wait for Arduino
time.sleep(2)
while(1):
#use Google Speech Recongiziton to get user input
question = chat.get_input
#send user input to both Cleverbot API and Watson Tone Analyzer API
#mutiple Procs to ensure Parallelism
parent_conn,child_conn = Pipe()
p1 = Process(target=chat.query_cleverbot,args=(question,))
p1.start()
p2 = Process(target=chat.query_watson,args=(child_conn,question,))
p2.start()
input_mood=parent_conn.recv()
p1.join()
p2.join()
#send string to arduino for apporiate motor response.
chat.send_to_arduino(input_mood)