async def async_test_silence(self): """Check start/stop session with silence detection.""" fake_transcription = Transcription( text="turn on the living room lamp", likelihood=1, transcribe_seconds=0, wav_seconds=0, ) def fake_transcribe(stream, *args): """Return test trancription.""" for chunk in stream: if not chunk: break return fake_transcription self.transcriber.transcribe_stream = fake_transcribe # Start session start_listening = AsrStartListening( site_id=self.site_id, session_id=self.session_id, stop_on_silence=True, send_audio_captured=False, ) result = None async for response in self.hermes.on_message_blocking(start_listening): result = response # No response expected self.assertIsNone(result) # Send in "audio" wav_path = Path("etc/turn_on_the_living_room_lamp.wav") results = [] with open(wav_path, "rb") as wav_file: for wav_bytes in AudioFrame.iter_wav_chunked(wav_file, 4096): frame = AudioFrame(wav_bytes=wav_bytes) async for response in self.hermes.on_message_blocking( frame, site_id=self.site_id ): results.append(response) # Except transcription self.assertEqual( results, [ AsrRecordingFinished(site_id=self.site_id, session_id=self.session_id), AsrTextCaptured( text=fake_transcription.text, likelihood=fake_transcription.likelihood, seconds=fake_transcription.transcribe_seconds, site_id=self.site_id, session_id=self.session_id, ), ], )
async def async_test_workflow(self): """Test wake/asr/nlu workflow""" self.hotword_detected = None self.text_captured = None self.nlu_intent = None # Wait until connected self.hermes.on_message = self.on_message_test_workflow await asyncio.wait_for(self.hermes.mqtt_connected_event.wait(), timeout=5) # Start listening self.hermes.subscribe(HotwordDetected, AsrTextCaptured, NluIntent) message_task = asyncio.create_task(self.hermes.handle_messages_async()) # Send audio with realtime delays _LOGGER.debug("Sending %s", self.wav_path) with io.BytesIO(self.wav_bytes) as wav_io: for chunk in AudioFrame.iter_wav_chunked(wav_io, 4096, live_delay=True): self.hermes.publish(AudioFrame(wav_bytes=chunk), site_id="default") # Wait for up to 10 seconds await asyncio.wait_for(self.done_event.wait(), timeout=10) # Verify hotword self.assertIsNotNone( self.hotword_detected, f"No hotword detected (system={self.wake_system}, wav={self.wav_path})", ) # Verify transcription self.assertIsNotNone(self.text_captured, "No text captured") self.assertEqual(self.text_captured.text, "turn on the living room lamp") # Verify intent self.assertIsNotNone(self.nlu_intent, "No intent recognized") self.assertEqual(self.nlu_intent.intent.intent_name, "ChangeLightState") slots = {s.slot_name: s.value["value"] for s in self.nlu_intent.slots} self.assertEqual(slots.get("state"), "on") self.assertEqual(slots.get("name"), "living room lamp") message_task.cancel()
def messages(): yield AsrStartListening( site_id=self.site_id, session_id=session_id, stop_on_silence=stop_on_silence, send_audio_captured=send_audio_captured, intent_filter=intent_filter, ) # Break WAV into chunks num_bytes_sent: int = 0 with io.BytesIO(wav_bytes) as wav_buffer: for wav_chunk in AudioFrame.iter_wav_chunked( wav_buffer, frames_per_chunk ): num_bytes_sent += len(wav_chunk) yield ( AudioSessionFrame(wav_bytes=wav_chunk), {"site_id": self.site_id, "session_id": session_id}, ) _LOGGER.debug("Sent %s byte(s) of WAV data", num_bytes_sent) yield AsrStopListening(site_id=self.site_id, session_id=session_id)