Commit ·
300b49f
1
Parent(s): 3bc695f
fix: better pipeline state tracking to prevent duplicate audio
Browse files- Check was_active in _handle_run_end to ignore duplicate RUN_END events
- Stop previous TTS if RUN_START received while pipeline already active
- More robust pipeline state management
reachy_mini_ha_voice/satellite.py
CHANGED
|
@@ -136,6 +136,11 @@ class VoiceSatelliteProtocol(APIServer):
|
|
| 136 |
_LOGGER.debug("Voice event: type=%s, data=%s", event_type.name, data)
|
| 137 |
|
| 138 |
if event_type == VoiceAssistantEventType.VOICE_ASSISTANT_RUN_START:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
# Mark pipeline as active
|
| 140 |
self._pipeline_active = True
|
| 141 |
self._tts_url = data.get("url")
|
|
@@ -170,12 +175,12 @@ class VoiceSatelliteProtocol(APIServer):
|
|
| 170 |
self.play_tts()
|
| 171 |
|
| 172 |
elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_RUN_END:
|
| 173 |
-
# Pipeline run ended
|
| 174 |
-
self._pipeline_active = False
|
| 175 |
self._tts_played = False
|
| 176 |
self._is_streaming_audio = False
|
| 177 |
|
| 178 |
# Check if should continue conversation (after RUN_END is safe)
|
|
|
|
| 179 |
self._handle_run_end()
|
| 180 |
|
| 181 |
def handle_timer_event(
|
|
@@ -489,6 +494,15 @@ class VoiceSatelliteProtocol(APIServer):
|
|
| 489 |
|
| 490 |
This is called after HA has fully completed the pipeline run.
|
| 491 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 492 |
# Check if should continue conversation
|
| 493 |
# 1. HA requested continue (continue_conversation=1 in INTENT_END)
|
| 494 |
# 2. Tap conversation mode is active (user tapped to start continuous mode)
|
|
@@ -498,6 +512,9 @@ class VoiceSatelliteProtocol(APIServer):
|
|
| 498 |
_LOGGER.info("Continuing conversation (tap_mode=%s, ha_continue=%s)",
|
| 499 |
self._tap_conversation_mode, self._continue_conversation)
|
| 500 |
|
|
|
|
|
|
|
|
|
|
| 501 |
# Play prompt sound to indicate ready for next input
|
| 502 |
# Use wakeup sound as the prompt (short beep)
|
| 503 |
self.state.tts_player.play(self.state.wakeup_sound)
|
|
|
|
| 136 |
_LOGGER.debug("Voice event: type=%s, data=%s", event_type.name, data)
|
| 137 |
|
| 138 |
if event_type == VoiceAssistantEventType.VOICE_ASSISTANT_RUN_START:
|
| 139 |
+
# Check if pipeline is already active (shouldn't happen, but be safe)
|
| 140 |
+
if self._pipeline_active:
|
| 141 |
+
_LOGGER.warning("RUN_START received but pipeline already active, stopping previous")
|
| 142 |
+
self.state.tts_player.stop()
|
| 143 |
+
|
| 144 |
# Mark pipeline as active
|
| 145 |
self._pipeline_active = True
|
| 146 |
self._tts_url = data.get("url")
|
|
|
|
| 175 |
self.play_tts()
|
| 176 |
|
| 177 |
elif event_type == VoiceAssistantEventType.VOICE_ASSISTANT_RUN_END:
|
| 178 |
+
# Pipeline run ended
|
|
|
|
| 179 |
self._tts_played = False
|
| 180 |
self._is_streaming_audio = False
|
| 181 |
|
| 182 |
# Check if should continue conversation (after RUN_END is safe)
|
| 183 |
+
# Note: _pipeline_active is managed inside _handle_run_end
|
| 184 |
self._handle_run_end()
|
| 185 |
|
| 186 |
def handle_timer_event(
|
|
|
|
| 494 |
|
| 495 |
This is called after HA has fully completed the pipeline run.
|
| 496 |
"""
|
| 497 |
+
# Mark current pipeline as ended
|
| 498 |
+
was_active = self._pipeline_active
|
| 499 |
+
self._pipeline_active = False
|
| 500 |
+
|
| 501 |
+
# If pipeline wasn't active, this might be a duplicate RUN_END - ignore
|
| 502 |
+
if not was_active:
|
| 503 |
+
_LOGGER.debug("RUN_END received but pipeline wasn't active, ignoring")
|
| 504 |
+
return
|
| 505 |
+
|
| 506 |
# Check if should continue conversation
|
| 507 |
# 1. HA requested continue (continue_conversation=1 in INTENT_END)
|
| 508 |
# 2. Tap conversation mode is active (user tapped to start continuous mode)
|
|
|
|
| 512 |
_LOGGER.info("Continuing conversation (tap_mode=%s, ha_continue=%s)",
|
| 513 |
self._tap_conversation_mode, self._continue_conversation)
|
| 514 |
|
| 515 |
+
# Mark pipeline as active BEFORE sending request to prevent duplicates
|
| 516 |
+
self._pipeline_active = True
|
| 517 |
+
|
| 518 |
# Play prompt sound to indicate ready for next input
|
| 519 |
# Use wakeup sound as the prompt (short beep)
|
| 520 |
self.state.tts_player.play(self.state.wakeup_sound)
|