示例#1
0
    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)