Support child devices - #5582
Conversation
There was a problem hiding this comment.
Hello @bgoncal,
When attempting to inspect the commits of your pull request for CLA signature status among all authors we encountered commit(s) which were not linked to a GitHub account, thus not allowing us to determine their status(es).
The commits that are missing a linked GitHub account are the following:
a36d748aa0d96b84f4c8d64cfe82b8bdda23069e- This commit has something that looks like an email address ([email protected]). Maybe try linking that to GitHub?.
Unfortunately, we are unable to accept this pull request until this situation is corrected.
Here are your options:
-
If you had an email address set for the commit that simply wasn't linked to your GitHub account you can link that email now and it will retroactively apply to your commits. The simplest way to do this is to click the link to one of the above commits and look for a blue question mark in a blue circle in the top left. Hovering over that bubble will show you what email address you used. Clicking on that button will take you to your email address settings on GitHub. Just add the email address on that page and you're all set. GitHub has more information about this option in their help center.
-
If you didn't use an email address at all, it was an invalid email, or it's one you can't link to your GitHub, you will need to change the authorship information of the commit and your global Git settings so this doesn't happen again going forward. GitHub provides some great instructions on how to change your authorship information in their help center.
- If you only made a single commit you should be able to run
(substituting "Author Name" and "
git commit --amend --author="Author Name <[email protected]>"[email protected]" for your actual information) to set the authorship information. - If you made more than one commit and the commit with the missing authorship information is not the most recent one you have two options:
- You can re-create all commits missing authorship information. This is going to be the easiest solution for developers that aren't extremely confident in their Git and command line skills.
- You can use this script that GitHub provides to rewrite history. Please note: this should be used only if you are very confident in your abilities and understand its impacts.
- Whichever method you choose, I will come by to re-check the pull request once you push the fixes to this branch.
- If you only made a single commit you should be able to run
We apologize for this inconvenience, especially since it usually bites new contributors to Home Assistant. We hope you understand the need for us to protect ourselves and the great community we all have built legally. The best thing to come out of this is that you only need to fix this once and it benefits the entire Home Assistant and GitHub community.
Thanks, I look forward to checking this PR again soon! ❤️
|
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
0a2e637 to
09abee8
Compare
There was a problem hiding this comment.
Pull request overview
Adds end-to-end support for Home Assistant “child devices” (devices that are logical parts of a parent device) across ingestion, persistence, watch UI, Spotlight search, area resolution, and the entity picker UI.
Changes:
- Resolve stripped child-device registry entries at ingestion time by inheriting hardware/display fields from the parent while keeping identity/config-entry fields on the child.
- Make child devices inherit their parent’s area when the child has no area, so area-based features continue to surface child entities correctly.
- Improve presentation and search: watch device/area screens sort child device sections under the parent and show “Part of …”; Spotlight and entity search incorporate parent naming; entity picker gains “Group by Device”.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| Tests/Shared/Watch/WatchGroupedEntities.test.swift | Adds watch grouping tests for child sorting and per-device flattening. |
| Tests/Shared/Models/DeviceRegistry.test.swift | Adds decoding + child-resolution + effective-area unit tests. |
| Tests/App/EntityPicker/EntityPickerViewModel.test.swift | Adds test coverage for “Group by Device” behavior including child placement. |
| Tests/App/Area/AreasService.test.swift | Adds test ensuring child entities land in the parent’s area when child has none. |
| Sources/WatchApp/Home/Devices/WatchDeviceEntitiesViewModel.swift | Includes child-device entities when viewing a parent device; flattens parent grouping. |
| Sources/WatchApp/Home/Devices/WatchDeviceEntitiesView.swift | Keeps child-device sections on device screen while unwrapping the viewed device’s own section. |
| Sources/WatchApp/Home/Areas/WatchAreaDeviceSectionHeader.swift | Shows “Part of …” subtitle for child device section headers (configurable). |
| Sources/Shared/Watch/WatchGroupedEntities.swift | Adds parent name to device groups, sorts child groups under parent, and adds flattening helper. |
| Sources/Shared/Watch/WatchEntitySections.swift | Enriches watch entity entries with parent device naming for child devices. |
| Sources/Shared/Watch/WatchEntityEntry.swift | Extends watch entry device metadata with optional parent name. |
| Sources/Shared/Resources/Swiftgen/Strings.swift | Updates SwiftGen accessors for new Localizable keys. |
| Sources/Shared/Environment/EntityFuzzySearch/EntityFuzzySearchIndex.swift | Improves fuzzy search by combining child + parent device names. |
| Sources/Shared/Environment/DeviceRegistryEntry.swift | Decodes child-specific fields and resolves child devices during registry ingestion. |
| Sources/Shared/Environment/AppDatabaseUpdater.swift | Uses child-device resolution when persisting device registry updates. |
| Sources/Shared/Database/AppDeviceRegistryTable.swift | Adds parentDeviceId column (indexed) to the GRDB device registry table. |
| Sources/Shared/AreasService.swift | Uses effective-area logic so child devices inherit parent area when appropriate. |
| Sources/HAModels/Sources/DatabaseTables.swift | Adds parentDeviceId to device-registry column definitions. |
| Sources/HAModels/Sources/AppDeviceRegistry.swift | Persists parentDeviceId and adds effectiveAreaId(in:) helper. |
| Sources/Extensions/Widgets/HAAppEntityAppIntentEntity.swift | Adds parentDeviceName field to support Spotlight keywording. |
| Sources/App/Utilities/Spotlight/SpotlightEntityIndexer.swift | Indexes parent-device name for child devices to improve Spotlight search matches. |
| Sources/App/Utilities/Spotlight/HAAppEntityAppIntentEntity+IndexedEntity.swift | Includes parent-device name in Spotlight keywords/contextual names. |
| Sources/App/Settings/EntityPicker/EntityPickerViewModel.swift | Adds device grouping mode and caches for device-based grouping/sorting. |
| Sources/App/Settings/EntityPicker/EntityPickerGroup.swift | Makes group identity stable via explicit id (not derived from title). |
| Sources/App/Settings/EntityPicker/EntityPicker.swift | Updates grouping UI visibility logic to account for device grouping. |
| Sources/App/Resources/en.lproj/Localizable.strings | Adds English strings for “Group by Device”, “No device”, and “Part of %@”. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated 3 comments.
Suppressed comments (1)
Sources/App/Settings/EntityPicker/EntityPickerViewModel.swift:185
- These detached rebuilds are not ordered. The initial
Publishedemission can start a rebuild with an empty entity cache, thenfetchEntities()starts a populated rebuild for the same server; because the guard checks onlyserverId, the older empty result can finish last and erase all subtitles/icons. Retain and cancel a row-content task or use a dedicated generation token, and clear the published maps when starting a server change.
Task.detached(priority: .userInitiated) { [weak self] in
let subtitles = serverEntities.contextualSubtitles(for: serverId)
let icons = serverEntities.reduce(into: [String: MaterialDesignIcons]()) { icons, entity in
icons[entity.entityId] = entity.materialDesignIcon
}
await MainActor.run { [weak self] in
guard let self, selectedServerId == serverId else { return }
|
On hold until further definition in frontend |
|
Found 1 unused localization strings in the codebase. Click to see detailsTo remove them, run the |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #5582 +/- ##
==========================================
+ Coverage 35.29% 35.93% +0.63%
==========================================
Files 1013 1032 +19
Lines 73124 74255 +1131
==========================================
+ Hits 25812 26681 +869
- Misses 47312 47574 +262
☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
# Conflicts: # Sources/Extensions/Widgets/HAAppEntityAppIntentEntity.swift
AI Policy
Select exactly one option that describes AI usage in this contribution:
Summary
Adds support for child devices (core PR home-assistant/core#178666, frontend PRs home-assistant/frontend#53617 and home-assistant/frontend#53619), where a device can be a logical part of another one, e.g. one outlet of a power strip.
Children arrive on
config/device_registry/liststripped of everything they inherit from their parent, so, like the frontend does, they are resolved into complete devices at ingestion: hardware and display fields come from the parent, the config entry from the child's ownconfig_entry_id, and identity fields are never inherited. A child without an area of its own now inherits its parent's, so its entities keep showing up in areas (watch areas, CarPlay areas, area actions, entity picker).On the watch, a child device's section sorts under its parent and shows what it is part of, and a parent's device screen also lists its children's entities. Searching the parent's name finds a child's entities, both in the entity picker and in Spotlight.
Also adds a "Group by Device" option to the entity picker, with child devices listed under their parent.
Screenshots
To be added.
Link to pull request in Documentation repository
Documentation: home-assistant/companion.home-assistant#
Any other notes
Servers without child devices are unaffected: the new fields are simply absent and every device behaves as before.