4 from typing import NamedTuple
7 import speech_recognition as sr # type: ignore
11 logger = logging.getLogger(__name__)
13 parser = config.add_commandline_args(
14 f"Google Assistant ({__file__})",
15 "Args related to contacting the Google Assistant",
18 "--google_assistant_bridge",
20 default="http://kiosk.house:3000",
22 help="How to contact the Google Assistant bridge"
25 "--google_assistant_username",
27 metavar="GOOGLE_ACCOUNT",
28 default="scott.gasch",
29 help="The user account for talking to Google Assistant"
33 class GoogleResponse(NamedTuple):
37 audio_transcription: str
41 success: {self.success}
42 response: {self.response}
43 audio_transcription: {self.audio_transcription}
44 audio_url: {self.audio_url}"""
47 def tell_google(cmd: str, *, recognize_speech=True) -> GoogleResponse:
48 return ask_google(cmd, recognize_speech=recognize_speech)
51 def ask_google(cmd: str, *, recognize_speech=True) -> GoogleResponse:
52 logging.debug(f"Asking google: '{cmd}'")
55 "user": config.config['google_assistant_username'],
57 url = f"{config.config['google_assistant_bridge']}/assistant"
58 r = requests.post(url, json=payload)
62 audio_transcription = ""
63 if r.status_code == 200:
65 success = bool(j["success"])
66 response = j["response"] if success else j["error"]
68 logger.debug('Google request succeeded.')
70 logger.debug(f"Google said: '{response}'")
71 audio = f"{config.config['google_assistant_bridge']}{j['audio']}"
73 recognizer = sr.Recognizer()
74 r = requests.get(audio)
75 if r.status_code == 200:
77 speech = sr.AudioData(
83 audio_transcription = recognizer.recognize_google(
86 logger.debug(f"Transcription: '{audio_transcription}'")
87 except sr.UnknownValueError as e:
89 logger.warning('Unable to parse Google assistant\'s response.')
90 audio_transcription = None
93 f'HTTP request to {url} with {payload} failed; code {r.status_code}'
95 return GoogleResponse(
99 audio_transcription=audio_transcription,