async def speak_sentence(self, sentence: str, language: typing.Optional[str] = None): """Speak a sentence using text to speech.""" tts_id = str(uuid4()) def handle_finished(): while True: _, message = yield if isinstance(message, TtsSayFinished) and (message.id == tts_id): return True, None say = TtsSay(id=tts_id, text=sentence, siteId=self.siteId) if language: say.lang = language messages = [say] topics = [TtsSayFinished.topic()] # Expecting only a single result async for result in self.publish_wait(handle_finished(), messages, topics): return result
async def speak_sentence( self, sentence: str, language: typing.Optional[str] = None, capture_audio: bool = False, wait_play_finished: bool = True, site_id: typing.Optional[str] = None, session_id: str = "", ) -> typing.Tuple[TtsSayFinished, typing.Optional[AudioPlayBytes]]: """Speak a sentence using text to speech.""" if (self.sound_system == "dummy") and ( not self.satellite_site_ids["text_to_speech"] ): raise TtsException("No text to speech system configured") site_id = site_id or self.site_id tts_id = str(uuid4()) def handle_finished(): say_finished: typing.Optional[TtsSayFinished] = None play_bytes: typing.Optional[ AudioPlayBytes ] = None if capture_audio else True play_finished = not wait_play_finished while True: topic, message = yield if isinstance(message, TtsSayFinished) and (message.id == tts_id): say_finished = message play_finished = True elif isinstance(message, TtsError): # Assume audio playback didn't happen say_finished = message play_bytes = True play_finished = True elif isinstance(message, AudioPlayBytes): request_id = AudioPlayBytes.get_request_id(topic) if request_id == tts_id: play_bytes = message elif isinstance(message, AudioPlayError): play_bytes = message if say_finished and play_bytes and play_finished: return (say_finished, play_bytes) say = TtsSay(id=tts_id, text=sentence, site_id=site_id, session_id=session_id) if language: say.lang = language messages = [say] message_types: typing.List[typing.Type[Message]] = [ TtsSayFinished, TtsError, AudioPlayBytes, AudioPlayError, ] # Expecting only a single result result = None async for response in self.publish_wait( handle_finished(), messages, message_types ): result = response assert isinstance(result, tuple), f"Expected tuple, got {result}" say_response, play_response = result if isinstance(say_response, TtsError): _LOGGER.error(say_response) raise TtsException(say_response.error) assert isinstance(say_response, TtsSayFinished), say_response if isinstance(play_response, AudioPlayError): _LOGGER.error(play_response) raise AudioServerException(play_response.error) if capture_audio: assert isinstance(play_response, AudioPlayBytes), play_response return typing.cast( typing.Tuple[TtsSayFinished, typing.Optional[AudioPlayBytes]], result )