Desmond-Dong commited on
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

Files changed (1) hide show
  1. reachy_mini_ha_voice/satellite.py +19 -2
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 - mark as inactive
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)