In this log I'll outline the structure of VoiceBox.py. In later logs we'll look at features in more detail.
if __name__ == "__main__":
global mode, flask_thread, assistant
mode = 'hotword'
credentials = aiy.assistant.auth_helpers.get_assistant_credentials()
assistant = Assistant(credentials)
except Exception as e:
aiy.audio.say("Couldn't connect to Assistant, see error log.")
flask_thread = threading.Thread(target=flask_run_thread)
button_thread = threading.Thread(target=button_wait_thread)
At the start of the main program we set the global variable mode to the default value, 'hotword', meaning that the microphone is on and the Google Assistant will be listening for the keywords, "Hey Google" or "Hello Google" to trigger speech processing. (In 'button' mode, speech processing will only start when the button is pressed.)
We then try to connect to Google Assistant. Last night, I spent so much time tinkering with the program that I burned through my entire 500 query Google Assistant API daily quota. This caused the Assistant() call to fail with Error:429: hence the try/except wrapper.
After creating an Assistant client, we start a thread, flask_run_thread(), to process web requests. This just runs the app Flask() object as in the three previous servers we've looked at: sysinfo, piHole and Blinkter.
app.run(host='0.0.0.0', port=9011, debug=False)
We then start another thread, button_wait_thread(), to wait for button presses.
button = aiy.voicehat.get_button()
while mode != 'quit':
response = requests.get('http://localhost:9011/button')
The clue's in the name. This thread calls the aiy API to wait for a button press, and then triggers the flask thread's button_get(). Note that if the mode global variable is set to 'quit', the button thread will end.
print('Button press requested, enabling mic')
return 'button requested'
This switches on the microphone, nudges the Assistant, and rings a bell to let the user know that VoiceBox is ready to listen.
We mention a 'quit' mode, how is the mode set? Via flask routines:
func = request.environ.get('werkzeug.server.shutdown')
The routine quit_flask() can be called either in response to a browser 'GET' at url /quit, or to a programmatic 'POST' to the same url.
If /quit is requested from a browser, quit_flask() is called and the browser is redirected to the VoiceBox root page. (This prevents restart loops where a browser directed to /quit constantly shoots down the VoiceBox server after every restart whenever the browser refreshes.
The /quit 'POST' routine is triggered by a request from the Google Assistant thread - when the user says "Hey Google, quit".
And here is the quit() routine in the Assistant thread:
if mode != 'quit':
response = requests.post('http://localhost:9011/quit'...
Read more »