3 """A module to serve as a local client library around HTTP calls to
4 the Google Assistant via a local gateway."""
8 from dataclasses import dataclass
9 from typing import Optional
12 import speech_recognition as sr # type: ignore
16 logger = logging.getLogger(__name__)
18 parser = config.add_commandline_args(
19 f"Google Assistant ({__file__})",
20 "Args related to contacting the Google Assistant",
23 "--google_assistant_bridge",
25 default="http://kiosk.house:3000",
27 help="How to contact the Google Assistant bridge",
30 "--google_assistant_username",
32 metavar="GOOGLE_ACCOUNT",
33 default="scott.gasch",
34 help="The user account for talking to Google Assistant",
40 """A response wrapper."""
45 audio_transcription: Optional[str] = None # None if not available.
49 success: {self.success}
50 response: {self.response}
51 audio_transcription: {self.audio_transcription}
52 audio_url: {self.audio_url}"""
55 def tell_google(cmd: str, *, recognize_speech=True) -> GoogleResponse:
56 """Alias for ask_google."""
57 return ask_google(cmd, recognize_speech=recognize_speech)
60 def ask_google(cmd: str, *, recognize_speech=True) -> GoogleResponse:
61 """Send a command string to Google via the google_assistant_bridge as the
62 user google_assistant_username and return the response. If recognize_speech
63 is True, perform speech recognition on the audio response from Google so as
64 to translate it into text (best effort, YMMV).
66 logging.debug("Asking google: '%s'", cmd)
69 "user": config.config['google_assistant_username'],
71 url = f"{config.config['google_assistant_bridge']}/assistant"
72 r = requests.post(url, json=payload)
76 audio_transcription: Optional[str] = ""
77 if r.status_code == 200:
80 success = bool(j["success"])
81 response = j["response"] if success else j["error"]
83 logger.debug('Google request succeeded.')
85 logger.debug("Google said: '%s'", response)
86 audio = f"{config.config['google_assistant_bridge']}{j['audio']}"
88 recognizer = sr.Recognizer()
89 r = requests.get(audio)
90 if r.status_code == 200:
92 speech = sr.AudioData(
98 audio_transcription = recognizer.recognize_google(
101 logger.debug("Transcription: '%s'", audio_transcription)
102 except sr.UnknownValueError as e:
104 msg = 'Unable to parse Google assistant\'s response.'
106 warnings.warn(msg, stacklevel=3)
107 audio_transcription = None
108 return GoogleResponse(
112 audio_transcription=audio_transcription,
115 message = f'HTTP request to {url} with {payload} failed; code {r.status_code}'
116 logger.error(message)
117 return GoogleResponse(
121 audio_transcription=audio_transcription,