From 7095b0b325ae542ab8b4bbf9f616274b1073e95b Mon Sep 17 00:00:00 2001 From: Vitali Graf Date: Thu, 14 May 2026 17:40:36 +0200 Subject: [PATCH] =?UTF-8?q?feat(microphone):=20PollMonitor=20meldet=20fehl?= =?UTF-8?q?endes=20Ger=C3=A4t=20sofort=20beim=20Start?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_microphone_monitor.py | 30 ++++++++++++++++++++++++++++++ whisper_local/microphone/_poll.py | 6 ++++++ 2 files changed, 36 insertions(+) diff --git a/tests/test_microphone_monitor.py b/tests/test_microphone_monitor.py index f4d8f43..021cd14 100644 --- a/tests/test_microphone_monitor.py +++ b/tests/test_microphone_monitor.py @@ -65,3 +65,33 @@ async def test_on_device_removed_fires_when_device_disappears(): monitor.stop() assert removed == ["Mic B"] + + +@pytest.mark.asyncio +async def test_on_configured_missing_fires_immediately_at_start(): + monitor = PollMonitor(configured_device="Headset USB", interval=99.0) + missing_called = asyncio.Event() + + async def on_missing() -> None: + missing_called.set() + + monitor.on_configured_missing = on_missing + + with patch("sounddevice.query_devices", return_value=_fake_devices(["Mic A"])): + await monitor.start() + + assert missing_called.is_set() + monitor.stop() + + +@pytest.mark.asyncio +async def test_on_configured_missing_does_not_fire_when_device_present(): + monitor = PollMonitor(configured_device="Headset USB", interval=99.0) + missing_mock = AsyncMock() + monitor.on_configured_missing = missing_mock + + with patch("sounddevice.query_devices", return_value=_fake_devices(["Headset USB", "Mic A"])): + await monitor.start() + + missing_mock.assert_not_called() + monitor.stop() diff --git a/whisper_local/microphone/_poll.py b/whisper_local/microphone/_poll.py index 44c768f..a524e0a 100644 --- a/whisper_local/microphone/_poll.py +++ b/whisper_local/microphone/_poll.py @@ -32,6 +32,12 @@ class PollMonitor: async def start(self) -> None: self._known_devices = self._current_devices() + if ( + self.configured_device + and self.configured_device not in self._known_devices + and self.on_configured_missing + ): + await self.on_configured_missing() self._task = asyncio.create_task(self._loop()) def stop(self) -> None: