How to make your own Voice Assistant
童夢綺自習スタジオ

Keywords: Python, Voice Assistant, ChatterBot,

Preparation

Firstly, I have to introduce the version of the items although it seems not important for your coding. However, you'd better to refer the list below to download these packages in order to reduce the trouble that you will meet during coding time.

  1. The python version I recommend is 3.6.0
  2. ChatterBot 0.7.4
  3. Chatterbot-corpus 1.0.1
  4. Pyttsx3 2.9
  5. SpeechRecognition 3.8.1
  6. Playsound 1.2.2
ソースコード
1pip3 install pyttsx3
2pip3 install SpeechRecognition==3.8.1
3pip3 install playsound==1.2.2

The imports and their usages

ソースコード
1import pyttsx3                  # speaking program
2import datetime                 # time machine
3import speech_recognition as sr # speech_recognition 
4import wikipedia                # for search something
5import random                    # random
6import webbrowser                # operation of browser
7import os                        # os
8from playsound import playsound    # play sounds
9from chatterbot import ChatBot    # the chatting bot
10from chatterbot.trainers import ChatterBotCorpusTrainer

Initialization

bot:

in this ChatBot constructor, there are 3 parameters:

Alpha name of the bot,

storage_adapter ChatterBot comes with built in adapter classes that allow it to connect to different types of databases. In this code, I used the SQLStorageAdapter which allows the chat bot to connect to SQL databases. By default, this adapter will create a SQLite database in the folder storing main.py.

logic_adapters parameter is a list of logic adapters. In ChatterBot, a logic adapter is a class that takes an input statement and returns a response to that statement.

database_uri parameter is used to specify the path to the database that the chat bot will use.

ソースコード
1bot = ChatBot(
2        'Alpha',
3        storage_adapter='chatterbot.storage.SQLStorageAdapter',
4        logic_adapters=[
5            'chatterbot.logic.MathematicalEvaluation',
6            #'chatterbot.logic.TimeLogicAdapter',
7            'chatterbot.logic.BestMatch'
8        ],
9        database_uri='sqlite:///database.db'
10    )

pyttsx3:

ソースコード
1engine = pyttsx3.init()
2engine.setProperty('rate', 200)    # Speed percent (can go over 100)
3engine.setProperty('volume', 1)  # Volume only 0-1

Basic Functions

speak():

The function of speaking is using for read the information(str type) from bot response.

ソースコード
1def speak(audio):               # the function of machine speaking controlling
2    "speak function"
3    print(audio)
4    engine.say(audio)
5    engine.runAndWait()

takeCmd():

The function of taking commands from user. it will record your audio by the microphone and transform audio into string, so please make sure that your microphone is working.

ソースコード
1def takeCmd():              # get the commands from users
2    r = sr.Recognizer()
3    with sr.Microphone() as source:
4        r.adjust_for_ambient_noise(source)
5        audio = r.listen(source)
6    
7    try:
8        command = r.recognize_google(audio, language = "en")
9        print(command)
10       
11
12    except Exception as e:
13        print(e)
14        command = takeCmd()    # if failed then do again
15
16    return command

analyzeCmd():

This function will receive the string transformed by takeCmd() and analyse the order.

ソースコード
1def analyzeCmd(command):
2    global KEEPING_ORDER
3    command = command.lower()
4    print(command)
5    if "open google" in command:
6        openBrowser()
7
8    elif "shut down" in command:
9        speak("good bye sir")
10        os._exit(0)
11
12    else:
13        chatData(command)

chatData():

The function uses chatterbot for chat responding.

ソースコード
1def chatData(command):
2    
3    print('Chatbot is ready')
4
5    user_input = command
6
7    bot_response = bot.get_response(user_input)
8
9    speak(bot_response)

Source Code

ソースコード
1import pyttsx3                  # speaking program
2import datetime                 # time machine
3import speech_recognition as sr # speech_recognition 
4import wikipedia
5import random
6import webbrowser
7import os
8from playsound import playsound
9from chatterbot import ChatBot
10from chatterbot.trainers import ChatterBotCorpusTrainer
11
12KEEPING_ORDER = False
13bot = ChatBot(
14        'Alpha',
15        storage_adapter='chatterbot.storage.SQLStorageAdapter',
16        logic_adapters=[
17            'chatterbot.logic.MathematicalEvaluation',
18            #'chatterbot.logic.TimeLogicAdapter',
19            'chatterbot.logic.BestMatch'
20        ],
21        database_uri='sqlite:///database.db'
22    )
23
24
25engine = pyttsx3.init()
26engine.setProperty('rate', 200)    # Speed percent (can go over 100)
27engine.setProperty('volume', 1)  # Volume 0-1
28
29def speak(audio):               # the function of machine speaking controlling
30    "speak function"
31    print(audio)
32    engine.say(audio)
33    engine.runAndWait()
34
35
36def time():                     # get current time
37    "time function"
38    Time = datetime.datetime.now().strftime("%I:%M:%S")
39    speak("The current time is")
40    speak(Time)
41
42def date():                     # get date
43    "date function"
44    year = int(datetime.datetime.now().year)    # get year in int format
45    month = int(datetime.datetime.now().month)  # get month in int format
46    day = int(datetime.datetime.now().day)      # get day in int format
47    speak("The current date is")
48    speak(day)
49    speak(month)
50    speak(year)
51
52def wishme():                   # the greetings at begining
53    hour()
54    speak("Welcome back!")
55    speak("Alpha-2 at your service. Please tell me how can I help you?")
56
57def hour():                     # judgement of greetings
58    Hour = datetime.datetime.now().hour
59    if Hour >= 6 and Hour < 12:
60        speak("good morning sir!")
61    elif Hour >= 12 and Hour < 18:
62        speak("good afternoon sir!")
63    elif Hour >= 18 and Hour < 20:
64        speak("good evening sir!")
65    else:
66        speak("Good night sir")
67
68def takeCmd():              # get the commands from users
69    global KEEPING_ORDER
70    r = sr.Recognizer()
71    with sr.Microphone() as source:
72        #r.pause_threshold = 1
73        if KEEPING_ORDER:
74            playsound("G:\\JARVIS demo\\jarvis\\jarvis\\Music\\tip1.mp3")
75
76        r.adjust_for_ambient_noise(source)
77        audio = r.listen(source)
78    
79    try:
80        if KEEPING_ORDER:
81            playsound("G:\\JARVIS demo\\jarvis\\jarvis\\Music\\nono.mp3")
82        command = r.recognize_google(audio, language = "en")
83        print(command)
84       
85
86    except Exception as e:
87        print(e)
88        if KEEPING_ORDER:
89            speak(askRepeat())
90        command = takeCmd()
91
92    return command
93
94
95def wiki(command):              # searching information from wiki
96    text = wikipedia.summary(command)
97    print(text)
98    speak(text)
99
100def askRepeat():                # asking for repeating the commands
101    num = random.randint(0,3)
102    if num == 0:
103        return "Sorry?"
104    elif num == 1:
105        return "Pardon?"
106    elif num == 2:
107        return "I beg your pardon, sir."
108    else:
109        return "Say it again?"
110
111def openBrowser():
112    speak('Please waiting. the Google has just been opened')
113    url = 'http://www.google.com/'
114    path = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s"
115    webbrowser.get(path).open(url)
116    speak('Done')
117
118def searchingGoogle():
119    speak("what\'s you wanna search sir?")
120    target = takeCmd().lower()
121    if "searching" in target or "stop" in target:
122        openBrowser()
123    else:
124        while True:
125            speak("you wanna search: "+target+"right?")
126            if "yes" in takeCmd().lower():
127                break
128            else:
129                target = takeCmd().lower()
130
131        path = "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s"
132        url = "http://google.com/?#q="
133        webbrowser.get(path).open_new(url + target)
134
135def closeBrowser():
136    os.system('taskkill /F /IM chrome.exe')
137    speak('The Google has just been closed, sir')
138
139#----------------------------------------------------------------------------------------
140
141def analyzeCmd(command):
142    global KEEPING_ORDER
143    command = command.lower()
144    print(command)
145    if "open google" in command:
146        speak("shall I help you to search something?")
147        command = takeCmd().lower()
148        if "yes" in command or "sure" in command or "okay" in command:
149            searchingGoogle()
150        else:
151            openBrowser()
152
153    elif "close google" in command:
154        closeBrowser()
155
156    elif "time" in command:
157        time()
158
159    elif "date" in command:
160        date()
161
162    elif "your name" in command:
163        speak("my name is Alpha")
164
165    elif "what is" in command:
166        try:
167            wiki(command)
168        except:
169            speak("there\'s an exception with wiki, please try again")
170
171    elif "shut up" in command or "be quiet" in command:
172        playsound("G:\\JARVIS demo\\jarvis\\jarvis\\Music\\unhappy.mp3")
173        speak("as you wish sir")
174        KEEPING_ORDER = False
175
176    elif "shut down" in command:
177        speak("good bye sir")
178        os._exit(0)
179
180    else:
181        chatData(command)
182
183def chatData(command):
184    
185    #trainer = ChatterBotCorpusTrainer(bot)
186    #bot.set_trainer(ChatterBotCorpusTrainer)
187    #trainer.train("chatterbot.corpus.english")
188    print('Chatbot is ready')
189
190    user_input = command
191
192    bot_response = bot.get_response(user_input)
193
194    speak(bot_response)
195
196
197#----------------------------------------------------------------------------------------
198
199def major():
200    global KEEPING_ORDER
201    wishme()
202    while True:
203        Cmd = takeCmd()
204        if "Alpha" in Cmd or "hello" in Cmd:
205            speak("yes?")
206            KEEPING_ORDER = True
207        elif "shut down" in Cmd:
208            speak("good bye sir")
209            os._exit(0)
210        while KEEPING_ORDER:
211            analyzeCmd(takeCmd())
212
213
214major()