103 lines
2.9 KiB
Python
103 lines
2.9 KiB
Python
import asyncio
|
|
import logging
|
|
import os
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
from wyoming.audio import AudioChunk
|
|
from wyoming.wake import Detection
|
|
from wyoming.client import AsyncClient
|
|
from wyoming.event import Event, async_write_event
|
|
from wyoming.server import AsyncServer, AsyncEventHandler
|
|
from wyoming_satellite import (
|
|
AlwaysStreamingSatellite,
|
|
EventSettings,
|
|
SatelliteSettings,
|
|
MicSettings,
|
|
WakeSettings,
|
|
)
|
|
|
|
from .shared import WYOMING_INFO, AUDIO_CHUNK
|
|
|
|
_LOGGER = logging.getLogger()
|
|
|
|
class MicEventHandler(AsyncEventHandler):
|
|
def __init__(self, *args, **kwargs) -> None:
|
|
super().__init__(*args, **kwargs)
|
|
self._is_connected = True
|
|
self._task = asyncio.create_task(self.stream_audio())
|
|
|
|
async def handle_event(self, event: Event) -> bool:
|
|
"""Output only."""
|
|
return True
|
|
|
|
async def stream_audio(self) -> None:
|
|
while self._is_connected:
|
|
await self.write_event(AUDIO_CHUNK.event())
|
|
await asyncio.sleep(AUDIO_CHUNK.seconds)
|
|
|
|
async def disconnect(self) -> None:
|
|
self._is_connected = False
|
|
await self._task
|
|
|
|
|
|
class WakeEventHandler(AsyncEventHandler):
|
|
async def handle_event(self, event: Event) -> bool:
|
|
_LOGGER.error(event)
|
|
if AudioChunk.is_type(event.type):
|
|
await self.write_event(Detection().event())
|
|
|
|
return True
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_multiple_wakeups(tmp_path: Path) -> None:
|
|
mic_socket = tmp_path / "mic.socket"
|
|
os.mkfifo(mic_socket)
|
|
mic_uri = f"unix://{mic_socket}"
|
|
mic_server = AsyncServer.from_uri(mic_uri)
|
|
mic_task = asyncio.create_task(mic_server.run(MicEventHandler))
|
|
|
|
wake_socket = tmp_path / "wake.socket"
|
|
os.mkfifo(wake_socket)
|
|
wake_uri = f"unix://{wake_socket}"
|
|
wake_server = AsyncServer.from_uri(wake_uri)
|
|
wake_task = asyncio.create_task(wake_server.run(WakeEventHandler))
|
|
|
|
wake_event = asyncio.Event()
|
|
|
|
class EventEventHandler(AsyncEventHandler):
|
|
async def handle_event(self, event: Event) -> bool:
|
|
if Detection.is_type(event.type):
|
|
wake_event.set()
|
|
|
|
return True
|
|
|
|
event_socket = tmp_path / "event.socket"
|
|
os.mkfifo(event_socket)
|
|
event_uri = f"unix://{event_socket}"
|
|
event_server = AsyncServer.from_uri(event_uri)
|
|
event_task = asyncio.create_task(event_server.run(EventEventHandler))
|
|
|
|
satellite = AlwaysStreamingSatellite(
|
|
SatelliteSettings(
|
|
mic=MicSettings(uri=mic_uri),
|
|
wake=WakeSettings(uri=wake_uri),
|
|
event=EventSettings(uri=event_uri),
|
|
)
|
|
)
|
|
|
|
satellite_task = asyncio.create_task(satellite.run())
|
|
|
|
await asyncio.sleep(0.5)
|
|
|
|
# async with asyncio.timeout(1):
|
|
# await wake_event.wait()
|
|
|
|
# await satellite.stop()
|
|
|
|
tasks = [mic_task, wake_task, event_task]
|
|
for task in tasks:
|
|
task.cancel()
|
|
await asyncio.wait(tasks)
|