Prepare for HACS custom wake words - #177676
Conversation
|
Hey there @jesserockz, @kbx81, @bdraco, mind taking a look at this pull request as it has been labeled with an integration ( Code owner commandsCode owners of
|
There was a problem hiding this comment.
Pull request overview
Enables ESPHome to discover HACS-installed custom wake words in nested directories while retaining namespaced IDs.
Changes:
- Recursively discovers wake-word manifests.
- Resolves model files from manifest metadata.
- Updates fixtures and tests for nested paths.
Reviewed changes
Copilot reviewed 2 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
homeassistant/components/esphome/assist_satellite.py |
Adds recursive discovery and namespaced IDs. |
tests/components/esphome/test_assist_satellite.py |
Updates nested wake-word expectations. |
tests/testing_config/custom_wake_words/choo_choo_homie/choo_choo_homie.json |
Relocates the test manifest. |
tests/testing_config/custom_wake_words/choo_choo_homie/choo_choo_homie.tflite |
Relocates the test model. |
Comments suppressed due to low confidence (1)
homeassistant/components/esphome/assist_satellite.py:928
- Require a regular model file before opening it. Values such as
"model": "."resolve to an existing directory, soexists()passes and the subsequent binary open raisesIsADirectoryError, aborting discovery of all custom wake words.
if not model_path.exists():
| ) | ||
| continue | ||
|
|
||
| model_path = config_path.parent / config["model"] |
| if not model_path.exists(): | ||
| # Missing model file | ||
| continue | ||
| for config_path in wake_words_dir.rglob("*.json"): |
The custom wake word inventory is cached for the lifetime of the Home Assistant process (_get_custom_wake_words is a singleton), so models added, updated or removed on disk at runtime (e.g. by HACS) did not take effect until a restart. Add a reload_custom_wake_words service that drops the cached inventory, re-scans the directory once, and dispatches a signal. Satellites that negotiate configuration subscribe to the signal and re-push their config so new models become available and removed models disappear immediately. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 7 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
homeassistant/components/esphome/assist_satellite.py:1005
- Invalidate the singleton decorator's cache, not only
hass.data. Because synchronous@singletonfunctions are also wrapped infunctools.lru_cache(homeassistant/helpers/singleton.py:50-55), this pop is bypassed after the first load and the original inventory is returned, so HACS installs and removals are never rescanned.
hass.data.pop(_DATA_WAKE_WORDS, None)
await async_get_custom_wake_words(hass)
homeassistant/components/esphome/assist_satellite.py:126
- Keep
modeloptional for existing local wake-word manifests. Previously, a manifest containing onlytypeandwake_wordloaded its same-stem.tflite; making this key required silently drops that valid legacy format, while the linked HACS validator only guaranteesmodelfor HACS-managed repositories. Fall back to the same-stem filename when omitted.
vol.Required("model"): str,
tests/components/esphome/test_assist_satellite.py:2336
- Test reload behavior through an observable filesystem change instead of mutating
_DATA_WAKE_WORDS. The singleton's hiddenlru_cacheretains the original inventory, so assigning{}here lets the broken reload implementation pass without rescanning; add or remove a model after initial setup, invoke the service, and assert that the advertised inventory changes.
assert _DATA_WAKE_WORDS in hass.data
# Poison the cache so the service must re-scan disk to recover.
hass.data[_DATA_WAKE_WORDS] = {}
Breaking change
Proposed change
Update the custom wake word logic for when HACS gains a new "wake_word" category: hacs/integration#5435
This is in service of the overall roadmap with regards to custom wake words: OpenHomeFoundation/roadmap#180
Specifically, this PR checks subdirectories in
config/custom_wake_wordssince HACS will store them ascustom_wake_words/<owner>/<repo_name>/<files>. The owner and repo name are retained for the wake word's internal id to avoid conflicts with the same named wake word.Type of change
Additional information
Checklist
ruff format homeassistant tests)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest.requirements_all.txt.Updated by running
python3 -m script.gen_requirements_all.To help with the load of incoming pull requests: