Commit ·
6ed5b09
1
Parent(s): 06a6f96
v0.5.10: Actually fix wake word switching - set id attribute on loaded models
Browse files- index.html +9 -0
- pyproject.toml +1 -1
- reachy_mini_ha_voice/satellite.py +4 -1
- reachy_mini_ha_voice/voice_assistant.py +17 -7
index.html
CHANGED
|
@@ -97,6 +97,15 @@
|
|
| 97 |
<h2>Changelog</h2>
|
| 98 |
<div class="how-to-use changelog-container">
|
| 99 |
<div class="changelog-scroll">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
<div class="changelog-entry">
|
| 101 |
<span class="version">v0.5.9</span>
|
| 102 |
<span class="date">2026-01-10</span>
|
|
|
|
| 97 |
<h2>Changelog</h2>
|
| 98 |
<div class="how-to-use changelog-container">
|
| 99 |
<div class="changelog-scroll">
|
| 100 |
+
<div class="changelog-entry">
|
| 101 |
+
<span class="version">v0.5.10</span>
|
| 102 |
+
<span class="date">2026-01-10</span>
|
| 103 |
+
<ul>
|
| 104 |
+
<li>Fix: Wake word models now have 'id' attribute set correctly</li>
|
| 105 |
+
<li>Fix: Wake word switching from Home Assistant now actually works</li>
|
| 106 |
+
<li>Fix: _update_wake_words_list properly filters by active_wake_words</li>
|
| 107 |
+
</ul>
|
| 108 |
+
</div>
|
| 109 |
<div class="changelog-entry">
|
| 110 |
<span class="version">v0.5.9</span>
|
| 111 |
<span class="date">2026-01-10</span>
|
pyproject.toml
CHANGED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
| 4 |
|
| 5 |
[project]
|
| 6 |
name = "reachy_mini_ha_voice"
|
| 7 |
-
version = "0.5.
|
| 8 |
description = "Home Assistant Voice Assistant for Reachy Mini"
|
| 9 |
readme = "README.md"
|
| 10 |
requires-python = ">=3.10"
|
|
|
|
| 4 |
|
| 5 |
[project]
|
| 6 |
name = "reachy_mini_ha_voice"
|
| 7 |
+
version = "0.5.10"
|
| 8 |
description = "Home Assistant Voice Assistant for Reachy Mini"
|
| 9 |
readme = "README.md"
|
| 10 |
requires-python = ">=3.10"
|
reachy_mini_ha_voice/satellite.py
CHANGED
|
@@ -322,7 +322,10 @@ class VoiceSatelliteProtocol(APIServer):
|
|
| 322 |
self.state.available_wake_words[wake_word_id] = model_info
|
| 323 |
|
| 324 |
_LOGGER.debug("Loading wake word: %s", model_info.wake_word_path)
|
| 325 |
-
|
|
|
|
|
|
|
|
|
|
| 326 |
_LOGGER.info("Wake word loaded: %s", wake_word_id)
|
| 327 |
active_wake_words.add(wake_word_id)
|
| 328 |
# Don't break - load ALL requested wake words, not just the first one
|
|
|
|
| 322 |
self.state.available_wake_words[wake_word_id] = model_info
|
| 323 |
|
| 324 |
_LOGGER.debug("Loading wake word: %s", model_info.wake_word_path)
|
| 325 |
+
loaded_model = model_info.load()
|
| 326 |
+
# Set id attribute on the model for later identification
|
| 327 |
+
setattr(loaded_model, 'id', wake_word_id)
|
| 328 |
+
self.state.wake_words[wake_word_id] = loaded_model
|
| 329 |
_LOGGER.info("Wake word loaded: %s", wake_word_id)
|
| 330 |
active_wake_words.add(wake_word_id)
|
| 331 |
# Don't break - load ALL requested wake words, not just the first one
|
reachy_mini_ha_voice/voice_assistant.py
CHANGED
|
@@ -521,7 +521,10 @@ class VoiceAssistantService:
|
|
| 521 |
|
| 522 |
try:
|
| 523 |
_LOGGER.debug("Loading wake model: %s", wake_word_id)
|
| 524 |
-
|
|
|
|
|
|
|
|
|
|
| 525 |
active_wake_words.add(wake_word_id)
|
| 526 |
except Exception as e:
|
| 527 |
_LOGGER.warning("Failed to load wake model %s: %s", wake_word_id, e)
|
|
@@ -532,7 +535,10 @@ class VoiceAssistantService:
|
|
| 532 |
if wake_word:
|
| 533 |
try:
|
| 534 |
_LOGGER.debug("Loading default wake model: %s", self.wake_model)
|
| 535 |
-
|
|
|
|
|
|
|
|
|
|
| 536 |
active_wake_words.add(self.wake_model)
|
| 537 |
except Exception as e:
|
| 538 |
_LOGGER.error("Failed to load default wake model: %s", e)
|
|
@@ -641,16 +647,20 @@ class VoiceAssistantService:
|
|
| 641 |
if (not ctx.wake_words) or (self._state.wake_words_changed and self._state.wake_words):
|
| 642 |
self._state.wake_words_changed = False
|
| 643 |
ctx.wake_words.clear()
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
| 647 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 648 |
|
| 649 |
ctx.has_oww = any(isinstance(ww, OpenWakeWord) for ww in ctx.wake_words)
|
| 650 |
if ctx.has_oww and ctx.oww_features is None:
|
| 651 |
ctx.oww_features = OpenWakeWordFeatures.from_builtin()
|
| 652 |
|
| 653 |
-
_LOGGER.
|
| 654 |
|
| 655 |
def _get_reachy_audio_chunk(self) -> Optional[bytes]:
|
| 656 |
"""Get audio chunk from Reachy Mini's microphone.
|
|
|
|
| 521 |
|
| 522 |
try:
|
| 523 |
_LOGGER.debug("Loading wake model: %s", wake_word_id)
|
| 524 |
+
loaded_model = wake_word.load()
|
| 525 |
+
# Set id attribute on the model for later identification
|
| 526 |
+
setattr(loaded_model, 'id', wake_word_id)
|
| 527 |
+
wake_models[wake_word_id] = loaded_model
|
| 528 |
active_wake_words.add(wake_word_id)
|
| 529 |
except Exception as e:
|
| 530 |
_LOGGER.warning("Failed to load wake model %s: %s", wake_word_id, e)
|
|
|
|
| 535 |
if wake_word:
|
| 536 |
try:
|
| 537 |
_LOGGER.debug("Loading default wake model: %s", self.wake_model)
|
| 538 |
+
loaded_model = wake_word.load()
|
| 539 |
+
# Set id attribute on the model for later identification
|
| 540 |
+
setattr(loaded_model, 'id', self.wake_model)
|
| 541 |
+
wake_models[self.wake_model] = loaded_model
|
| 542 |
active_wake_words.add(self.wake_model)
|
| 543 |
except Exception as e:
|
| 544 |
_LOGGER.error("Failed to load default wake model: %s", e)
|
|
|
|
| 647 |
if (not ctx.wake_words) or (self._state.wake_words_changed and self._state.wake_words):
|
| 648 |
self._state.wake_words_changed = False
|
| 649 |
ctx.wake_words.clear()
|
| 650 |
+
# state.wake_words is Dict[str, MicroWakeWord/OpenWakeWord]
|
| 651 |
+
# We need to filter by active_wake_words (which contains the IDs/keys)
|
| 652 |
+
for ww_id, ww_model in self._state.wake_words.items():
|
| 653 |
+
if ww_id in self._state.active_wake_words:
|
| 654 |
+
# Ensure the model has an 'id' attribute for later use
|
| 655 |
+
if not hasattr(ww_model, 'id'):
|
| 656 |
+
setattr(ww_model, 'id', ww_id)
|
| 657 |
+
ctx.wake_words.append(ww_model)
|
| 658 |
|
| 659 |
ctx.has_oww = any(isinstance(ww, OpenWakeWord) for ww in ctx.wake_words)
|
| 660 |
if ctx.has_oww and ctx.oww_features is None:
|
| 661 |
ctx.oww_features = OpenWakeWordFeatures.from_builtin()
|
| 662 |
|
| 663 |
+
_LOGGER.info("Active wake words updated: %s", list(self._state.active_wake_words))
|
| 664 |
|
| 665 |
def _get_reachy_audio_chunk(self) -> Optional[bytes]:
|
| 666 |
"""Get audio chunk from Reachy Mini's microphone.
|