Skip to content

Media player source selection - #396

Open
jamesmulcahy wants to merge 4 commits into
NSPManager:develfrom
jamesmulcahy:feat/media-player-sources
Open

jamesmulcahy wants to merge 4 commits into
NSPManager:develfrom
jamesmulcahy:feat/media-player-sources

Conversation

@jamesmulcahy

@jamesmulcahy jamesmulcahy commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Home Assistant media players have a list of sources (inputs) and can select one. This sends a media player's sources to the NSPanel and lets the panel select one.

A media player with a source volume strategy (#385) has two source lists: its own, and those of the source player feeding it. In an audio matrix setup that is the zone's inputs (Movie Theatre, James Matrix, …) and the Sonos Favorites of the speaker the zone is currently playing from.

Protobuf

  • NSPanelEntityState.MediaPlayer.player_sources / source_player_sources: a SourceSelection with the sources, the current source and whether one can be selected. source_player_sources is unset when there is no source player.
  • MediaPlayerCommand.select_player_source / select_source_player_source: select by name, empty means no change. By name because the source player's list changes completely when the zone switches source, so an index from an older state could select the wrong entry.
  • current_source is often empty for the source player: Sonos only reports source for Line-in/TV, not for a playing favourite.
  • The firmware C files were missing volume_step from Home Assistant media players and album art for NSPanels #385 and pick it up here.

Manager

  • HomeAssistantMediaPlayer reads source_list / source and calls media_player.select_source.
  • Following the source player now lives in a new HomeAssistantSourcePlayer, used by both source volume strategies. Before, only source_entity followed the source player; player_attributes only read the player's own attributes and so could not see the source player's sources. The strategies now only differ in where the source volume comes from. With player_attributes, the manager now also subscribes to the source player, which costs one Home Assistant state request per source change.
  • When the player switches source, the previous source player's sources are dropped straight away instead of being offered until the new ones arrive.
  • The NSPanel can only receive 4 KB in one MQTT message (larger messages are silently dropped by the firmware today), so at most 32 sources of up to 64 bytes are sent per list. Longer names are cut on a UTF-8 boundary, and the shortened name sent back by the panel is matched to the full name before selecting.

Not in this PR

  • Panel UI: separate firmware PR. It needs to page through lists longer than 12.
  • No web UI or REST changes; the existing source volume settings already identify the source player.

Status

Draft: built in Docker and unit tested (10 new tests in tests/media_player_test.cpp covering both source lists, selection, the feature flag, the 32×64 limits and dropping stale source-player sources; *MediaPlayer*:*SourcePlayer* passes). Not yet run against Home Assistant.

🤖 Generated with Claude Code

@jamesmulcahy
jamesmulcahy force-pushed the feat/media-player-sources branch from e820964 to d084dcd Compare October 13, 2026 18:14
jamesmulcahy and others added 3 commits October 16, 2026 18:53
Home Assistant media players have a list of sources (inputs) and can
select one. A media player with a source volume strategy also has a
source player feeding it, which has its own sources, for example the
Sonos Favorites of the speaker an audio matrix zone is playing from.

NSPanelEntityState.MediaPlayer gets both lists as a SourceSelection
(sources, current source and whether one can be selected).
source_player_sources is unset when there is no source player.

MediaPlayerCommand selects a source from either list by name. The lists
change when the player switches source, so an index from an older state
could select the wrong one. An empty name means no change, as no source
is called "".

The firmware C files were also missing volume_step from NSPManager#385 and pick
it up here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The manager now reads source_list and source from Home Assistant and
sends them to the NSPanel with the media player state. Select commands
from the panel call media_player.select_source.

Sources of the source player (the player feeding this one, as set up
with the source volume strategy) are sent too. Only the source_entity
strategy used to follow the source player in Home Assistant, the
player_attributes strategy only read attributes of the player itself
and so could not see the source player's sources. Following the source
player now lives in HomeAssistantSourcePlayer, which both strategies
use. They only differ in where the source volume comes from. When the
player switches source, the sources of the previous source player are
dropped straight away rather than offered until the new ones arrive.

The NSPanel can only receive 4 KB in one MQTT message, so at most 32
sources of up to 64 bytes each are sent per list. Longer names are
shortened without splitting a UTF-8 character, and the shortened name
the panel sends back is matched to the full one before selecting it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Covers publishing a player's sources from Home Assistant, selecting a
source from the panel, ignoring sources that are unknown or can't be
selected, and limiting source lists to 32 names of at most 64 bytes
without splitting a UTF-8 character (selecting a shortened name sends
the full name to Home Assistant).

Also covers a source player feeding the media player: its sources are
published and selected on the source player, and switching to another
source player drops the previous one's sources.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jamesmulcahy
jamesmulcahy force-pushed the feat/media-player-sources branch from 9913fcb to 569a23f Compare October 17, 2026 01:54
The media player tests use hand written Home Assistant states, which are
always tidy. Real ones are not, so this adds seven states recorded from
a real Home Assistant (personal names and the album art token replaced)
and checks what the manager publishes for the NSPanels from each:

- An audio matrix zone fed by a Sonos player: the zone's inputs, the
  Sonos favorites as source player sources, and the source volume. The
  Sonos player is playing a station that is not a favorite, so it has
  no current source. A favorite with a curly apostrophe is selected by
  its exact name.
- An Apple TV with 41 apps: only the first 32 reach the panel, and as
  the list is alphabetical that leaves out YouTube and TV.
- A receiver that is off, a matrix controller in an unknown state, and
  Music Assistant players with and without a source list.

The recorded states include album art, so the tests set the manager
address and port that album art URLs are built from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jamesmulcahy added a commit to jamesmulcahy/NSPanelManager-firmware that referenced this pull request Oct 18, 2026
Pressing the album art on the media player page lists the player's
sources on the items4 page, or on items8 when there are more than four,
paging through it when there are more than eight. The current source is
highlighted. Pressing a source, or the back button, returns to the
media player page with the source switch as it was.

A media player fed by another player has two lists, as in the manager's
protobuf (NSPManager/NSPanelManager#396): its own, such as an audio
matrix zone's inputs, and the source player's, such as the favorites of
the Sonos speaker feeding the zone. The list follows the source switch,
like the volume buttons, and the header reads "Input" or "Favorites".

The media player state does not carry its sources yet, so both lists
are hard coded, and a selection is only logged, as the command it will
become (select_player_source or select_source_player_source), until
#396 adds the lists and the commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jamesmulcahy
jamesmulcahy marked this pull request as ready for review October 18, 2026 15:18
jamesmulcahy added a commit to jamesmulcahy/NSPanelManager-firmware that referenced this pull request Oct 19, 2026
Pressing the album art on the media player page lists the player's
sources on the items4 page, or on items8 when there are more than four,
paging through it when there are more than eight. Only the names are
shown, the current one highlighted: the items pages' icon font has
entity icons only, so the slots' icon buttons are hidden. Pressing a
source, or the back button, returns to the media player page with the
source switch as it was.

A media player fed by another player has two lists, as in the manager's
protobuf (NSPManager/NSPanelManager#396): its own, such as an audio
matrix zone's inputs, and the source player's, such as the favorites of
the Sonos speaker feeding the zone. The list follows the source switch,
like the volume buttons, and the header reads "Input" or "Favorites".

The media player state does not carry its sources yet, so both lists
are hard coded, and a selection is only logged, as the command it will
become (select_player_source or select_source_player_source), until
#396 adds the lists and the commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant