Add Samsung WAM player provider#3334
Add Samsung WAM player provider#3334Oliver-Stevens wants to merge 2 commits intomusic-assistant:devfrom
Conversation
Adds native support for Samsung's Wireless Audio Multiroom (WAM) speakers via the pywam library. - Auto-discovery via SSDP with manual IP fallback - Full playback control (play, pause, stop, source selection) - Volume and mute control, with hardware button state synchronised to MA - Native multi-room grouping with support for externally-initiated changes - Command retry with exponential backoff and automatic connection recovery - Tiered dependency logging to control verbosity
🔒 Dependency Security Report📦 Modified Dependencies
|
Pin async-upnp-client to 0.46.2
|
Pinning pywam to 0.1.0rc6 as v0.2.0 requires Python >=3.13. The two versions are functionally identical with only changes to error message formatting and docstrings. |
|
Doc draft as follows: Samsung Wireless Audio (WAM)Music Assistant has support for Samsung's Wireless Audio Multiroom (WAM) speakers, providing auto-discovery, playback control, and native multi-room grouping. Features
SettingsFor information about the settings seen in the MA UI refer to the Player Provider Settings and Individual Player Settings pages. Known Issues / Notes
|
I think it's safe to bump music-assistant to 3.13 or even 3.14. @MarvinSchenkel FYI |
| from .models import DiscoveryEventType, DiscoveryInfo, DiscoverySource | ||
|
|
||
|
|
||
| class DiscoverySsdpListener: |
There was a problem hiding this comment.
For now this is fine to add but since this is the second or 3rd SSDP implementation we now added to individual providers, we should create a new core controller for discovery and move SSDP and MDNS discovery into that. So basically, just like Home Assistant, we have one discovery core controller (or builtin provider) that can handle the base logic for all providers that want it.
Anyways, outside the scope of this PR - this code looks fine!
@MarvinSchenkel can you put a task on the backlog for this ?
There was a problem hiding this comment.
No more need for a task anymore, I had a free hour while traveling;
#3378
| elif prov.logger.isEnabledFor(logging.DEBUG): | ||
| logging.getLogger("pywam").setLevel(logging.DEBUG) | ||
| logging.getLogger("pywam.client").setLevel(logging.INFO) | ||
| logging.getLogger("async_upnp_client").setLevel(logging.DEBUG) |
There was a problem hiding this comment.
Consider raising this. I think the async_upnp_client is really chatty.
|
|
||
| # --- Configuration Entries --- | ||
|
|
||
| CONF_ENTRY_SAMPLE_RATES_WAM = ConfigEntry.from_dict( |
There was a problem hiding this comment.
There is a helper function here that can help you with this.
| """ | ||
| await self.discovery.stop() | ||
| self.groups.stop_sync_task() | ||
| self.wam_players.clear() |
There was a problem hiding this comment.
I think we need to close the connections to the speakers here as well before clearing?
There was a problem hiding this comment.
In combination with the feedback above, we could simply do
for player in self.players:
self.logger.debug("Unloading player %s", player.name)
await self.mass.players.unregister(player.player_id)
| """Samsung WAM player provider.""" | ||
|
|
||
| supported_models: dict[str, dict[str, Any]] | ||
| wam_players: dict[str, WamPlayer] |
There was a problem hiding this comment.
No need to keep track of this yourself, you already have access to self.players from the base class
| self.logger.debug("Pre-flight connection to new player at %s", info.ip_address) | ||
|
|
||
| temp_speaker = Speaker(info.ip_address) | ||
| await temp_speaker.connect() |
There was a problem hiding this comment.
We should guard for ConnectionErrors here to avoid crashing the discovery process.
| self.states.clear() | ||
| self._child_to_leader.clear() | ||
| for player in self.players.values(): | ||
| synced_to = getattr(player, "synced_to_internal", None) |
There was a problem hiding this comment.
I don't think we need all those getattrs here? Looks like synced_to_internal is a property anyway.
| "pywam==0.1.0rc6", | ||
| "async-upnp-client==0.46.2" | ||
| ], | ||
| "documentation": "URL_TO_DOCUMENTATION", |
There was a problem hiding this comment.
| "documentation": "URL_TO_DOCUMENTATION", | |
| "documentation": "https://music-assistant.io/player-support/samsung_wam/", |
MarvinSchenkel
left a comment
There was a problem hiding this comment.
Few comments, but we are really close already 🙌 . Marking this PR as draft again so we can keep track of what needs our attention. Please mark this as 'Ready for review' again when you have addressed the feedback.
Adds native support for Samsung's Wireless Audio Multiroom (WAM) speakers via the pywam library.
Tested locally with the following speaker models:
What's included:
Notes:
pywam