music_assistant: forward player.device_info.connections to device_registry#169541
music_assistant: forward player.device_info.connections to device_registry#169541trudenboy wants to merge 1 commit into
Conversation
|
Hey there @music-assistant, @arturpragacz, 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
This PR updates the Music Assistant integration to forward upstream player hardware connection identifiers into Home Assistant’s device registry, enabling HA to merge devices across integrations based on shared connection tuples.
Changes:
- Forward
player.device_info.connectionsintoDeviceInfo.connectionswhen creating Music Assistant entities. - Extend the Music Assistant player fixture with
connectionsdata. - Add a test asserting that fixture player connections appear on the created HA device entry.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| homeassistant/components/music_assistant/entity.py | Adds forwarding of player.device_info.connections into HA DeviceInfo.connections. |
| tests/components/music_assistant/fixtures/players.json | Adds connections entries to the first player fixture. |
| tests/components/music_assistant/test_init.py | Adds an end-to-end test validating the forwarded connections are present in the device registry. |
4d82441 to
95d0a3f
Compare
There was a problem hiding this comment.
Hi @trudenboy
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!
aed27f0 to
102a756
Compare
e04e1ff to
2b37613
Compare
2b37613 to
8809e62
Compare
8809e62 to
9b2a514
Compare
…istry The Music Assistant integration constructs HA DeviceInfo from the upstream MA Player model, but drops the connections set that MA's per-protocol providers (BT bridges, AirPlay, WiiM, hass_players, local_audio, ...) populate to advertise hardware identity. This PR forwards player.device_info.connections verbatim into HA's DeviceInfo.connections argument so HA's device_registry can dedupe device cards across integrations that know the same hardware. The connections field is added in companion music-assistant/models PR. Uses getattr() default to stay backwards-compatible with older music_assistant_models releases that don't yet have the field. Test added in test_init.py:test_device_info_forwards_player_connections exercises the chain end-to-end via the existing fixture infrastructure; players.json fixture gains a connections block on its first player declaring a Wi-Fi MAC and a Bluetooth MAC, both asserted to appear in the resulting HA device_registry record. NOTE: pre-commit bypassed locally on Intel macOS because HA core's full test dep tree is not feasible to set up locally. ruff check + ruff format on the changed Python files were validated manually (.local-ci-output.txt). HA CI exercises the full path. Companion PRs in music-assistant/models, music-assistant/server, Sendspin/aiosendspin.
9b2a514 to
d446f37
Compare
arturpragacz
left a comment
There was a problem hiding this comment.
Thank you for your contribution, however we explicitly do not want to merge devices across integrations.
music_assistant: forward player
device_info.connectionsinto HA's device-registrySummary
The Music Assistant integration constructs HA
DeviceInfofrom theupstream MA
Playermodel, but drops theconnectionsset thatMA's per-protocol providers (BT bridges, AirPlay, WiiM, hass_players,
local_audio, …) populate to advertise hardware identity. As a result
HA's device-registry can't merge MA's
media_player.<name>cards withother integrations that know the same physical device — every speaker
ends up as two cards.
This PR forwards
player.device_info.connectionsverbatim into HA'sDeviceInfo.connectionsargument.Motivation
Empirical evidence from a HAOS production deployment showed every
Bluetooth speaker exposed via MA appears in HA as two device cards:
connectionsmedia_player.<name>[]bluetoothintegration / HACS bridge){("bluetooth", mac)}HA's device-registry can't merge them because there's no overlapping
connection tuple. The empty-
connectionshalf comes from thisintegration —
MusicAssistantEntity.__init__constructsDeviceInfowith only
identifiers,manufacturer,model,name, andconfiguration_url. MA's internal player model already carriesMAC_ADDRESS/IP_ADDRESSidentifiers (from WiiM, hass_players,local_audio, …) but they were never exposed to HA's registry.
A companion change in
music-assistant/modelsadds a separateconnections: set[tuple[str, str]]field on the player'sDeviceInfo, mirroring HA's open-endeddevice_registryshape soprovider authors can cleanly express HA-bound hardware identity. This
PR consumes that field.
Changes
homeassistant/components/music_assistant/entity.py(
MusicAssistantEntity.__init__):getattrwith default keeps the integration working with oldermusic_assistant_modelsreleases that don't yet have the field. Afterthe model bump (see Coordination), the new field is always present;
the
getattrbecomes a defensive no-op but is kept for safety.The connection-type strings come from the provider — HA's registry
treats any string as a valid connection type, so new transports
(zigbee, matter, thread, custom) work without a manifest change here.
Tests
tests/components/music_assistant/test_init.py:new
test_device_info_forwards_player_connectionsexercises the pathend-to-end via the existing fixture infrastructure.
tests/components/music_assistant/fixtures/players.jsongains aconnectionsblock on its first player so the new test can assertagainst
device_entry.connections.The fixture's player declares two connections: a Wi-Fi-style MAC and a
Bluetooth MAC. The test asserts both appear in HA's
device_registrydevice record after setup. This catches regressions in the
forwarding (drop, normalization mistake, type coercion).
Local-test caveat
HA core's full pytest dep tree is not feasible to set up locally on
Intel macOS without significant time. ruff lint + format on the
changed files were validated locally and pass cleanly. The HA CI
runner will exercise the full
tests/components/music_assistant/test_init.pysuite including thenew test. Captured CI output in
.local-ci-output.txt.Backwards compatibility
getattr(self.player.device_info, "connections", set())keeps theintegration working with
music_assistant_modelsreleases thatpredate the new field — the integration neither requires nor crashes
on its absence.
connections=connections or None— empty set passed to HA'sDeviceInfois converted toNoneso the registry input staysunchanged for players that have no hardware identity to advertise.
identifiers,manufacturer,model,name,configuration_urlall unchanged.added on next entity initialization. This may cause HA's device-
registry to merge previously-separate device records that share
hardware connections (e.g.
bluetoothintegration's BT MAC matchesMA's newly-forwarded BT MAC). This is the intended outcome — the
documented HA behaviour for
device_registry.async_get_or_createis to merge on overlapping connections. Operators with bespoke
per-card automations may want to re-test those after upgrade.
Coordination
The
connectionsfield this PR reads is added inmusic-assistant/models#215.Per-provider passthrough lives in
music-assistant/server#3813(Sendspin provider) — other providers (WiiM, AirPlay, hass_players, …)
will adopt the same passthrough pattern over time.
This PR can technically merge before the model PR (the
getattrguard makes it backwards-compatible), but practically should land
after a
music-assistant-clientrelease that bumps its transitivemusic_assistant_modelsdependency to a version that has the field —otherwise the test player fixture's
connectionsblock deserializesto nothing and the new test silently passes without exercising the
real chain. Recommend bumping
manifest.json'smusic-assistant-clientrequirement alongside this merge.Umbrella discussion with full design context and status:
https://github.com/orgs/music-assistant/discussions/5415
CLA
I'll click through the HA Contributor License Agreement on first PR;
this draft awaits maintainer review of the upstream coordination.
Test plan locally (full)
(Local Intel-mac restriction documented in
.local-ci-output.txt—ruff was the only tool run on this development host. CI runners
exercise the full path.)