/
/
# What does this implement/fix? Lets Music Assistant natively group official WiiM/Audio Pro speakers together with generic LinkPlay speakers (e.g. Edifier) into a single multiroom group, in either leader direction. Builds on top of the generic LinkPlay support (#5729) and depends on it — this PR targets that branch. A small provider-owned `NativeGroupCoordinator` now acts as the single native topology authority across both backends (official WiiM SDK and the generic LinkPlay shell), while each SDK/protocol stays the authority for playback/state only. Group role and membership are derived from the leader's own live slave list and resolved against the registered players, so a device grouped from either backend shows the correct leader/follower/member state. **Related issue (if applicable):** - N/A ## Types of changes - [ ] Bugfix (non-breaking change which fixes an issue) — `bugfix` - [ ] New feature (non-breaking change which adds functionality) — `new-feature` - [x] Enhancement to an existing feature — `enhancement` - [ ] New music/player/metadata/plugin provider — `new-provider` - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) — `breaking-change` - [ ] Refactor (no behaviour change) — `refactor` - [ ] Documentation only — `documentation` - [ ] Maintenance / chore — `maintenance` - [ ] CI / workflow change — `ci` - [ ] Dependencies bump — `dependencies` Changes: - Add `NativeGroupCoordinator` as the single native topology authority across both WiiM backends (role, membership, reconcile, `can_group_with`, grouping commands). - Route grouping by backend: official↔official via the WiiM SDK, and generic↔generic and mixed groups over the low-level LinkPlay client (follower `join_slave` / `leave_group`, leader-side kick for cross-backend removal); every operation is verified against the leader's own live slave list and raises a typed error on a no-op. - Gate generic and mixed joins to known, router-based, same-generation devices; refuse legacy Wi-Fi Direct groups that would move a follower out of MA's reach. - Widen `can_group_with` to compatible available players of both backends, and remove the interim read-only lock on externally-created mixed groups. - Derive follower state from the leader for both backends (a follower publishes only its own volume/mute and manages no members of its own). - Self-heal topology from the existing player polls and events (no extra polling loop): leaders re-read their slave list over a low-level command client on a slow TTL or when forced, and a debounced reconcile heals discovery-order misses. - Add extensive unit tests covering all four leader/follower backend combinations, mixed grouping, verification/no-op failures, concurrency/ordering, and topology healing. ## Checklist - [x] The code change is tested and works locally. - [x] `pre-commit run --all-files` passes. - [x] `pytest` passes, and tests have been added/updated under `tests/` where applicable. - [ ] For changes to shared models, the companion PR in `music-assistant/models` is linked. - [ ] For changes affecting the UI, the companion PR in `music-assistant/frontend` is linked. - [x] I have read and complied with the project's [AI Policy](https://github.com/music-assistant/.github/blob/main/AI_POLICY.md) for any AI-assisted contributions. - [ ] I have [raised a PR against the documentation repository](https://github.com/music-assistant/music-assistant.io/blob/main/CONTRIBUTING.md) targeting the main or beta branch as appropriate.