Skip to content

Commit

Permalink
feature: make it possible to use a player volume entity outside the g…
Browse files Browse the repository at this point in the history
…roup
  • Loading branch information
punxaphil committed Dec 1, 2024
1 parent c63439d commit 30253ad
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ entitiesToIgnoreVolumeLevelFor: # default is empty. Use this if you want to igno
artworkMinHeight: 10 # default is 5. Use this to change the minimum height of the artwork in the player section. Unit is in rem.
artworkAsBackground: true # default is false. Will show the artwork as background for the player section.
playerVolumeEntityId: media_player.bedroom # default is empty. Use this to control the volume of another player in the player section. Entity ID must the selected player or part of the selected player's group, otherwise it will not be controlled.
allowPlayerVolumeEntityOutsideOfGroup: true # default is false. Will allow the playerVolumeEntityId to be outside the group of the selected player.
showSourceInPlayer: true # default is false. Will show the source (if available) in the player section.
showBrowseMediaInPlayerSection: true # default is false. Will show the browse media button in the player section.
showChannelInPlayer: true # default is false. Will show the channel (if available) in the player section. This can for instance be the radio station name.
Expand Down
34 changes: 24 additions & 10 deletions src/components/player-controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CardConfig, MediaPlayerEntityFeature } from '../types';
import { mdiFastForward, mdiRewind, mdiVolumeMinus, mdiVolumePlus } from '@mdi/js';
import { MediaPlayer } from '../model/media-player';
import { until } from 'lit-html/directives/until.js';
import { findPlayer } from '../utils/utils';

const { SHUFFLE_SET, REPEAT_SET, PLAY, PAUSE, NEXT_TRACK, PREVIOUS_TRACK, BROWSE_MEDIA } = MediaPlayerEntityFeature;

Expand All @@ -15,14 +16,16 @@ class PlayerControls extends LitElement {
private activePlayer!: MediaPlayer;
private mediaControlService!: MediaControlService;
private volumePlayer!: MediaPlayer;
private updateMemberVolumes!: boolean;

render() {
this.config = this.store.config;
this.activePlayer = this.store.activePlayer;
this.mediaControlService = this.store.mediaControlService;
const noUpDown = !!this.config.showVolumeUpAndDownButtons && nothing;
const noFastForwardAndRewind = !!this.config.showFastForwardAndRewindButtons && nothing;
this.volumePlayer = this.activePlayer.getMember(this.config.playerVolumeEntityId) ?? this.activePlayer;
this.volumePlayer = this.getVolumePlayer();
this.updateMemberVolumes = !this.config.playerVolumeEntityId;
return html`
<div class="main" id="mediaControls">
<div class="icons">
Expand All @@ -42,26 +45,37 @@ class PlayerControls extends LitElement {
<sonos-ha-player .store=${this.store} .features=${this.showBrowseMedia()}></sonos-ha-player>
</div>
<sonos-volume .store=${this.store} .player=${this.volumePlayer}
.updateMembers=${!this.config.playerVolumeEntityId}></sonos-volume>
.updateMembers=${this.updateMemberVolumes}></sonos-volume>
<div class="icons">
<sonos-ha-player .store=${this.store} .features=${this.store.showPower(true)}></sonos-ha-player>
</div">
</div>
`;
}
private volDown = async () =>
await this.mediaControlService.volumeDown(this.volumePlayer, !this.config.playerVolumeEntityId);
private volUp = async () =>
await this.mediaControlService.volumeUp(this.volumePlayer, !this.config.playerVolumeEntityId);

private getVolumePlayer() {
let result;
if (this.config.playerVolumeEntityId) {
if (this.config.allowPlayerVolumeEntityOutsideOfGroup) {
result = findPlayer(this.store.allMediaPlayers, this.config.playerVolumeEntityId);
} else {
result = this.activePlayer.getMember(this.config.playerVolumeEntityId);
}
}
return result ?? this.activePlayer;
}

private volDown = async () => await this.mediaControlService.volumeDown(this.volumePlayer, this.updateMemberVolumes);
private volUp = async () => await this.mediaControlService.volumeUp(this.volumePlayer, this.updateMemberVolumes);
private rewind = async () =>
await this.mediaControlService.seek(
this.volumePlayer,
this.volumePlayer.attributes.media_position - (this.config.fastForwardAndRewindStepSizeSeconds || 15),
this.activePlayer,
this.activePlayer.attributes.media_position - (this.config.fastForwardAndRewindStepSizeSeconds || 15),
);
private fastForward = async () =>
await this.mediaControlService.seek(
this.volumePlayer,
this.volumePlayer.attributes.media_position + (this.config.fastForwardAndRewindStepSizeSeconds || 15),
this.activePlayer,
this.activePlayer.attributes.media_position + (this.config.fastForwardAndRewindStepSizeSeconds || 15),
);

private async getAudioInputFormat() {
Expand Down
4 changes: 4 additions & 0 deletions src/editor/advanced-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ export const ADVANCED_SCHEMA = [
name: 'playerVolumeEntityId',
selector: { entity: { multiple: false, filter: { domain: 'media_player' } } },
},
{
name: 'allowPlayerVolumeEntityOutsideOfGroup',
selector: { boolean: {} },
},
{
name: 'dontSwitchPlayerWhenGrouping',
selector: { boolean: {} },
Expand Down
4 changes: 2 additions & 2 deletions src/model/media-player.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HassEntity } from 'home-assistant-js-websocket';
import { CardConfig } from '../types';
import { getGroupPlayerIds } from '../utils/utils';
import { findPlayer, getGroupPlayerIds } from '../utils/utils';

export class MediaPlayer {
id: string;
Expand All @@ -24,7 +24,7 @@ export class MediaPlayer {
}

getMember(playerId?: string) {
return this.members.find((member) => member.id === playerId);
return findPlayer(this.members, playerId);
}

hasMember(playerId: string) {
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export interface CardConfig extends LovelaceCardConfig {
artworkMinHeight?: number;
artworkAsBackground?: boolean;
playerVolumeEntityId?: string;
allowPlayerVolumeEntityOutsideOfGroup?: boolean;
dontSwitchPlayerWhenGrouping?: boolean;
showSourceInPlayer?: boolean;
showBrowseMediaInPlayerSection?: boolean;
Expand Down
4 changes: 4 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,7 @@ export function sortEntities(config: CardConfig, filtered: HassEntity[]) {
return filtered.sort((a, b) => a.entity_id.localeCompare(b.entity_id));
}
}

export function findPlayer(mediaPlayers: MediaPlayer[], playerId: string | undefined) {
return mediaPlayers.find((member) => member.id === playerId);
}

0 comments on commit 30253ad

Please sign in to comment.