Desmond-Dong commited on
Commit
9308902
·
1 Parent(s): 3115532

"refactor_sdk_compliance"

Browse files
reachy_mini_ha_voice/main.py CHANGED
@@ -122,14 +122,10 @@ class ReachyMiniHaVoice(ReachyMiniApp):
122
  # Create and run the voice assistant service
123
  service = VoiceAssistantService(reachy_mini)
124
 
125
- # Try to get existing event loop, create new one if needed
126
- try:
127
- loop = asyncio.get_running_loop()
128
- logger.debug("Using existing event loop")
129
- except RuntimeError:
130
- loop = asyncio.new_event_loop()
131
- asyncio.set_event_loop(loop)
132
- logger.debug("Created new event loop")
133
 
134
  try:
135
  loop.run_until_complete(service.start())
@@ -169,22 +165,8 @@ class ReachyMiniHaVoice(ReachyMiniApp):
169
  except Exception as e:
170
  logger.error(f"Error stopping service: {e}")
171
 
172
- # Clean up robot connection if available
173
- if reachy_mini is not None:
174
- try:
175
- # Ensure media is explicitly closed before disconnecting
176
- if hasattr(reachy_mini, 'media'):
177
- reachy_mini.media.close()
178
- logger.debug("Robot media closed")
179
- except Exception as e:
180
- logger.debug(f"Error closing media during shutdown: {e}")
181
-
182
- try:
183
- # Prevent connection from keeping threads alive
184
- reachy_mini.client.disconnect()
185
- logger.debug("Robot client disconnected")
186
- except Exception as e:
187
- logger.debug(f"Error disconnecting client during shutdown: {e}")
188
 
189
  # Close event loop
190
  try:
 
122
  # Create and run the voice assistant service
123
  service = VoiceAssistantService(reachy_mini)
124
 
125
+ # Always create a new event loop to avoid conflicts with SDK
126
+ loop = asyncio.new_event_loop()
127
+ asyncio.set_event_loop(loop)
128
+ logger.debug("Created new event loop for voice assistant")
 
 
 
 
129
 
130
  try:
131
  loop.run_until_complete(service.start())
 
165
  except Exception as e:
166
  logger.error(f"Error stopping service: {e}")
167
 
168
+ # Note: Robot connection cleanup is handled by SDK's context manager
169
+ # in wrapped_run(). We only need to close our event loop here.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  # Close event loop
172
  try:
reachy_mini_ha_voice/voice_assistant.py CHANGED
@@ -136,11 +136,25 @@ class VoiceAssistantService:
136
  # Start Reachy Mini media system if available
137
  if self.reachy_mini is not None:
138
  try:
139
- # Only start if audio system is initialized but not yet recording
140
- # This avoids conflicts if SDK already started the media system
141
- if self.reachy_mini.media.audio is not None:
142
- self.reachy_mini.media.start_recording()
143
- self.reachy_mini.media.start_playing()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  _LOGGER.info("Reachy Mini media system initialized")
145
  else:
146
  _LOGGER.warning("Reachy Mini audio system not available")
@@ -151,11 +165,11 @@ class VoiceAssistantService:
151
  if self._motion is not None:
152
  self._motion.start()
153
 
154
- # Start audio processing thread
155
  self._running = True
156
  self._audio_thread = threading.Thread(
157
  target=self._process_audio,
158
- daemon=True,
159
  )
160
  self._audio_thread.start()
161
 
 
136
  # Start Reachy Mini media system if available
137
  if self.reachy_mini is not None:
138
  try:
139
+ # Check if media system is already running to avoid conflicts
140
+ media = self.reachy_mini.media
141
+ if media.audio is not None:
142
+ # Check recording state
143
+ is_recording = getattr(media, '_recording', False)
144
+ if not is_recording:
145
+ media.start_recording()
146
+ _LOGGER.info("Started Reachy Mini recording")
147
+ else:
148
+ _LOGGER.debug("Reachy Mini recording already active")
149
+
150
+ # Check playback state
151
+ is_playing = getattr(media, '_playing', False)
152
+ if not is_playing:
153
+ media.start_playing()
154
+ _LOGGER.info("Started Reachy Mini playback")
155
+ else:
156
+ _LOGGER.debug("Reachy Mini playback already active")
157
+
158
  _LOGGER.info("Reachy Mini media system initialized")
159
  else:
160
  _LOGGER.warning("Reachy Mini audio system not available")
 
165
  if self._motion is not None:
166
  self._motion.start()
167
 
168
+ # Start audio processing thread (non-daemon for proper cleanup)
169
  self._running = True
170
  self._audio_thread = threading.Thread(
171
  target=self._process_audio,
172
+ daemon=False,
173
  )
174
  self._audio_thread.start()
175