Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to show and switch between media player sources #1009

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .hass_dev/views/media-player-view.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ cards:
square: false
- type: vertical-stack
title: Controls
cards:
cards:
- type: custom:mushroom-media-player-card
entity: media_player.lounge_room
name: Source controls
show_source_controls: true
- type: custom:mushroom-media-player-card
entity: media_player.kitchen
name: Volume controls
Expand Down
7 changes: 4 additions & 3 deletions docs/cards/media-player.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A media player card allows you to control a media player entity.
All the options are available in the lovelace editor but you can use `yaml` if you want.

| Name | Type | Default | Description |
| :--------------------- | :-------------------------------------------------- | :---------- | :------------------------------------------------------------------------------------- |
|:-----------------------| :-------------------------------------------------- |:------------|:---------------------------------------------------------------------------------------|
| `entity` | string | Required | Media Player entity |
| `icon` | string | Optional | Custom icon |
| `name` | string | Optional | Custom name |
Expand All @@ -21,8 +21,9 @@ All the options are available in the lovelace editor but you can use `yaml` if y
| `primary_info` | `name` `state` `last-changed` `last-updated` `none` | `name` | Info to show as primary info |
| `secondary_info` | `name` `state` `last-changed` `last-updated` `none` | `state` | Info to show as secondary info |
| `icon_type` | `icon` `entity-picture` `none` | `icon` | Type of icon to display |
| `use_media_info` | boolean | `false` | Use media info instead of name, state and icon when a media is playing |
| `show_volume_level` | boolean | `false` | Show volume level next to media state when media is playing |
| `use_media_info` | boolean | `false` | Use media info instead of name, state and icon when a media is playing |
| `show_volume_level` | boolean | `false` | Show volume level next to media state when media is playing |
| `show_source_controls` | boolean | `false` | Show available media sources |
| `media_controls` | list | `[]` | List of controls to display (on_off, shuffle, previous, play_pause_stop, next, repeat) |
| `volume_controls` | list | `[]` | List of controls to display (volume_mute, volume_set, volume_buttons) |
| `collapsible_controls` | boolean | `false` | Collapse controls when off |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import { computeRTL, HomeAssistant, MediaPlayerEntity } from "../../../ha";
import { styleMap } from "lit/directives/style-map.js";

@customElement("mushroom-media-player-source-control")
export class MediaPlayerSourceControls extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ attribute: false }) public entity!: MediaPlayerEntity;

@property({ attribute: false }) public source!: string;

@property({ attribute: false }) public icon!: string;

@property() public fill: boolean = false;

private _handleClick(e: MouseEvent): void {
e.stopPropagation();

this.hass.callService("media_player", "select_source", {
entity_id: this.entity.entity_id,
source: this.source
});
}

protected render(): TemplateResult {
const rtl = computeRTL(this.hass);
const buttonStyle = {};
if (this.entity.attributes.source == this.source) {
buttonStyle["--bg-color"] = this.getSourceColor();
}

return html`
<mushroom-button-group .fill=${this.fill} ?rtl=${rtl}>
<mushroom-button
.icon=${this.icon}
style=${styleMap(buttonStyle)}
@click=${this._handleClick}
title=${this.source}
></mushroom-button>
</mushroom-button-group>
`;
}

private getSourceColor(): string {
return `rgb(var(--rgb-media-source-${this.source.toLowerCase()}, var(--rgb-state-media-player)))`;
}
}
59 changes: 30 additions & 29 deletions src/cards/media-player-card/media-player-card-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,51 @@ import { array, assign, boolean, enums, object, optional } from "superstruct";
import { LovelaceCardConfig } from "../../ha";
import { ActionsSharedConfig, actionsSharedConfigStruct } from "../../shared/config/actions-config";
import {
AppearanceSharedConfig,
appearanceSharedConfigStruct,
AppearanceSharedConfig,
appearanceSharedConfigStruct,
} from "../../shared/config/appearance-config";
import { EntitySharedConfig, entitySharedConfigStruct } from "../../shared/config/entity-config";
import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config";

export const MEDIA_LAYER_MEDIA_CONTROLS = [
"on_off",
"shuffle",
"previous",
"play_pause_stop",
"next",
"repeat",
"on_off",
"shuffle",
"previous",
"play_pause_stop",
"next",
"repeat",
] as const;

export type MediaPlayerMediaControl = (typeof MEDIA_LAYER_MEDIA_CONTROLS)[number];

export const MEDIA_PLAYER_VOLUME_CONTROLS = [
"volume_mute",
"volume_set",
"volume_buttons",
"volume_mute",
"volume_set",
"volume_buttons",
] as const;

export type MediaPlayerVolumeControl = (typeof MEDIA_PLAYER_VOLUME_CONTROLS)[number];

export type MediaPlayerCardConfig = LovelaceCardConfig &
EntitySharedConfig &
AppearanceSharedConfig &
ActionsSharedConfig & {
use_media_info?: boolean;
show_volume_level?: boolean;
volume_controls?: MediaPlayerVolumeControl[];
media_controls?: MediaPlayerMediaControl[];
collapsible_controls?: boolean;
};
EntitySharedConfig &
AppearanceSharedConfig &
ActionsSharedConfig & {
use_media_info?: boolean;
show_volume_level?: boolean;
show_source_controls?: boolean;
volume_controls?: MediaPlayerVolumeControl[];
media_controls?: MediaPlayerMediaControl[];
collapsible_controls?: boolean;
};

export const mediaPlayerCardConfigStruct = assign(
lovelaceCardConfigStruct,
assign(entitySharedConfigStruct, appearanceSharedConfigStruct, actionsSharedConfigStruct),
object({
use_media_info: optional(boolean()),
show_volume_level: optional(boolean()),
volume_controls: optional(array(enums(MEDIA_PLAYER_VOLUME_CONTROLS))),
media_controls: optional(array(enums(MEDIA_LAYER_MEDIA_CONTROLS))),
collapsible_controls: optional(boolean()),
})
lovelaceCardConfigStruct,
assign(entitySharedConfigStruct, appearanceSharedConfigStruct, actionsSharedConfigStruct),
object({
use_media_info: optional(boolean()),
show_volume_level: optional(boolean()),
volume_controls: optional(array(enums(MEDIA_PLAYER_VOLUME_CONTROLS))),
media_controls: optional(array(enums(MEDIA_LAYER_MEDIA_CONTROLS))),
collapsible_controls: optional(boolean()),
})
);
2 changes: 2 additions & 0 deletions src/cards/media-player-card/media-player-card-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const MEDIA_LABELS = [
"use_media_info",
"use_media_artwork",
"show_volume_level",
"show_source_controls",
"media_controls",
"volume_controls",
];
Expand All @@ -38,6 +39,7 @@ const computeSchema = memoizeOne((localize: LocalizeFunc, icon?: string): HaForm
schema: [
{ name: "use_media_info", selector: { boolean: {} } },
{ name: "show_volume_level", selector: { boolean: {} } },
{ name: "show_source_controls", selector: { boolean: {} } },
],
},
{
Expand Down
Loading