diff --git a/gallery/public/images/sunflowers.jpg b/gallery/public/images/sunflowers.jpg new file mode 100644 index 0000000000..961d2a7bf3 Binary files /dev/null and b/gallery/public/images/sunflowers.jpg differ diff --git a/gallery/src/data/media_players.ts b/gallery/src/data/media_players.ts index a28f679c53..07dc174e8c 100644 --- a/gallery/src/data/media_players.ts +++ b/gallery/src/data/media_players.ts @@ -6,7 +6,9 @@ export const createMediaPlayerEntities = () => [ media_content_type: "music", media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)", media_artist: "Technohead", - supported_features: 64063, + // Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media + + // Select Source + Stop + Clear + Play + Shuffle Set + Browse Media + supported_features: 195135, entity_picture: "/images/album_cover_2.jpg", media_duration: 300, media_position: 50, @@ -14,12 +16,15 @@ export const createMediaPlayerEntities = () => [ // 23 seconds in new Date().getTime() - 23000 ).toISOString(), + volume_level: 0.5, }), getEntity("media_player", "music_playing", "playing", { friendly_name: "Playing The Music", media_content_type: "music", media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)", media_artist: "Technohead", + // Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media + + // Select Source + Stop + Clear + Play + Shuffle Set supported_features: 64063, entity_picture: "/images/album_cover.jpg", media_duration: 300, @@ -28,6 +33,7 @@ export const createMediaPlayerEntities = () => [ // 23 seconds in new Date().getTime() - 23000 ).toISOString(), + volume_level: 0.5, }), getEntity("media_player", "stream_playing", "playing", { friendly_name: "Playing the Stream", @@ -35,50 +41,125 @@ export const createMediaPlayerEntities = () => [ media_title: "Epic sax guy 10 hours", app_name: "YouTube", entity_picture: "/images/frenck.jpg", - supported_features: 33, + // Pause + Next Track + Play + Browse Media + supported_features: 147489, }), - getEntity("media_player", "living_room", "playing", { - friendly_name: "Pause, No skip, tvshow", + getEntity("media_player", "stream_paused", "paused", { + friendly_name: "Paused the Stream", + media_content_type: "movie", + media_title: "Epic sax guy 10 hours", + app_name: "YouTube", + entity_picture: "/images/frenck.jpg", + // Pause + Next Track + Play + supported_features: 16417, + }), + getEntity("media_player", "stream_playing_previous", "playing", { + friendly_name: 'Playing the Stream (with "previous" support)', + media_content_type: "movie", + media_title: "Epic sax guy 10 hours", + app_name: "YouTube", + entity_picture: "/images/frenck.jpg", + // Pause + Previous Track + Play + supported_features: 16401, + }), + getEntity("media_player", "tv_playing", "playing", { + friendly_name: "Playing non-skip TV Show", media_content_type: "tvshow", media_title: "Chapter 1", media_series_title: "House of Cards", app_name: "Netflix", entity_picture: "/images/netflix.jpg", + // Pause supported_features: 1, }), getEntity("media_player", "sonos_idle", "idle", { friendly_name: "Sonos Idle", + // Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media + + // Select Source + Stop + Clear + Play + Shuffle Set supported_features: 64063, + volume_level: 0.33, + is_volume_muted: true, }), - getEntity("media_player", "theater", "off", { + getEntity("media_player", "idle_browse_media", "idle", { + friendly_name: "Idle waiting for Browse Media (e.g. Spotify)", + // Pause + Seek + Volume Set + Previous Track + Next Track + Play Media + + // Select Source + Play + Shuffle Set + Browse Media + supported_features: 182839, + volume_level: 0.79, + }), + getEntity("media_player", "theater_off", "off", { friendly_name: "TV Off", + // On + Off + Play + Next + Pause + supported_features: 16801, + }), + getEntity("media_player", "theater_on", "on", { + friendly_name: "TV On", + // On + Off + Play + Next + Pause + supported_features: 16801, + }), + getEntity("media_player", "theater_off_static", "off", { + friendly_name: "TV Off (cannot be switched on)", + // Off + Next + Pause + supported_features: 289, + }), + getEntity("media_player", "theater_on_static", "on", { + friendly_name: "TV On (cannot be switched off)", + // On + Next + Pause supported_features: 161, }), getEntity("media_player", "android_cast", "playing", { - friendly_name: "Casting App", + friendly_name: "Casting App (no supported features)", media_title: "Android Screen Casting", app_name: "Screen Mirroring", - // supported_features: 21437, + }), + getEntity("media_player", "image_display", "playing", { + friendly_name: "Digital Picture Frame", + media_content_type: "image", + media_title: "Famous Painting", + media_artist: "Famous Artist", + entity_picture: "/images/sunflowers.jpg", + // On + Off + Browse Media + supported_features: 131456, }), getEntity("media_player", "unavailable", "unavailable", { friendly_name: "Player Unavailable", + // Pause + Volume Set + Volume Mute + Previous Track + Next Track + + // Play Media + Stop + Play supported_features: 21437, }), getEntity("media_player", "unknown", "unknown", { friendly_name: "Player Unknown", + // Pause + Volume Set + Volume Mute + Previous Track + Next Track + + // Play Media + Stop + Play supported_features: 21437, }), + getEntity("media_player", "playing", "playing", { + friendly_name: "Player Playing (no Pause support)", + // Volume Set + Volume Mute + Previous Track + Next Track + + // Play Media + Stop + Play + supported_features: 21436, + volume_level: 1, + }), + getEntity("media_player", "idle", "idle", { + friendly_name: "Player Idle", + // Pause + Volume Set + Volume Mute + Previous Track + Next Track + + // Play Media + Stop + Play + supported_features: 21437, + volume_level: 0, + }), getEntity("media_player", "receiver_on", "on", { source_list: ["AirPlay", "Blu-Ray", "TV", "USB", "iPod (USB)"], volume_level: 0.63, is_volume_muted: false, source: "TV", - friendly_name: "Receiver", + friendly_name: "Receiver (selectable sources)", + // Volume Set + Volume Mute + On + Off + Select Source + Play + Sound Mode supported_features: 84364, }), getEntity("media_player", "receiver_off", "off", { source_list: ["AirPlay", "Blu-Ray", "TV", "USB", "iPod (USB)"], - friendly_name: "Receiver", + friendly_name: "Receiver (selectable sources)", + // Volume Set + Volume Mute + On + Off + Select Source + Play + Sound Mode supported_features: 84364, }), ]; diff --git a/gallery/src/demos/demo-hui-media-control-card.ts b/gallery/src/demos/demo-hui-media-control-card.ts index a26a13a8a3..6298163a25 100644 --- a/gallery/src/demos/demo-hui-media-control-card.ts +++ b/gallery/src/demos/demo-hui-media-control-card.ts @@ -7,40 +7,61 @@ import { createMediaPlayerEntities } from "../data/media_players"; const CONFIGS = [ { - heading: "Paused music", + heading: "Paused Music", config: ` - type: media-control entity: media_player.music_paused `, }, { - heading: "Playing music", + heading: "Playing Music", config: ` - type: media-control entity: media_player.music_playing `, }, { - heading: "Playing stream", + heading: "Playing Stream", config: ` - type: media-control entity: media_player.stream_playing `, }, { - heading: "Pause, No skip, tvshow", + heading: "Paused Stream", config: ` - type: media-control - entity: media_player.living_room + entity: media_player.stream_paused `, }, { - heading: "Screen casting", + heading: 'Playing Stream (with "previous" support)', + config: ` + - type: media-control + entity: media_player.stream_playing_previous + `, + }, + { + heading: "Playing non-skip TV Show", + config: ` + - type: media-control + entity: media_player.tv_playing + `, + }, + { + heading: "Screen Casting", config: ` - type: media-control entity: media_player.android_cast `, }, + { + heading: "Digital Picture Frame", + config: ` + - type: media-control + entity: media_player.image_display + `, + }, { heading: "Sonos Idle", config: ` @@ -48,11 +69,53 @@ const CONFIGS = [ entity: media_player.sonos_idle `, }, + { + heading: "Idle waiting for Browse Media", + config: ` + - type: media-control + entity: media_player.idle_browse_media + `, + }, { heading: "Player Off", config: ` - type: media-control - entity: media_player.theater + entity: media_player.theater_off + `, + }, + { + heading: "Player On", + config: ` + - type: media-control + entity: media_player.theater_on + `, + }, + { + heading: "Player Off (cannot be switched on)", + config: ` + - type: media-control + entity: media_player.theater_off_static + `, + }, + { + heading: "Player On (cannot be switched off)", + config: ` + - type: media-control + entity: media_player.theater_on_static + `, + }, + { + heading: "Player Idle", + config: ` + - type: media-control + entity: media_player.idle + `, + }, + { + heading: "Player Playing", + config: ` + - type: media-control + entity: media_player.playing `, }, { @@ -70,14 +133,14 @@ const CONFIGS = [ `, }, { - heading: "Receiver On", + heading: "Receiver On (selectable sources)", config: ` - type: media-control entity: media_player.receiver_on `, }, { - heading: "Receiver Off", + heading: "Receiver Off (selectable sources)", config: ` - type: media-control entity: media_player.receiver_off diff --git a/gallery/src/demos/demo-hui-media-player-rows.ts b/gallery/src/demos/demo-hui-media-player-rows.ts index 1077e7a7b8..8287f5b773 100644 --- a/gallery/src/demos/demo-hui-media-player-rows.ts +++ b/gallery/src/demos/demo-hui-media-player-rows.ts @@ -12,23 +12,45 @@ const CONFIGS = [ - type: entities entities: - entity: media_player.music_paused - name: Paused music + name: Paused Music - entity: media_player.music_playing - name: Playing music + name: Playing Music - entity: media_player.stream_playing - name: Paused, no play - - entity: media_player.living_room - name: Pause, No skip, tvshow + name: Playing Stream + - entity: media_player.stream_paused + name: Paused Stream + - entity: media_player.stream_playing_previous + name: Playing Stream (with "previous" support) + - entity: media_player.tv_playing + name: Playing non-skip TV Show - entity: media_player.android_cast name: Screen casting + - entity: media_player.image_display + name: Digital Picture Frame - entity: media_player.sonos_idle - name: Chromcast Idle - - entity: media_player.theater + name: Sonos Idle + - entity: media_player.idle_browse_media + name: Idle waiting for Browse Media + - entity: media_player.theater_off name: Player Off + - entity: media_player.theater_on + name: Player On + - entity: media_player.theater_off_static + name: Player Off (cannot be switched on) + - entity: media_player.theater_on_static + name: Player On (cannot be switched off) + - entity: media_player.idle + name: Player Idle + - entity: media_player.playing + name: Player Playing - entity: media_player.unavailable name: Player Unavailable - entity: media_player.unknown name: Player Unknown + - entity: media_player.receiver_on + name: Receiver On (selectable sources) + - entity: media_player.receiver_off + name: Receiver Off (selectable sources) `, }, ]; diff --git a/src/data/media-player.ts b/src/data/media-player.ts index 393c06cb71..45bf6010ee 100644 --- a/src/data/media-player.ts +++ b/src/data/media-player.ts @@ -18,6 +18,8 @@ import { } from "@mdi/js"; import type { HassEntity } from "home-assistant-js-websocket"; import type { HomeAssistant } from "../types"; +import { UNAVAILABLE_STATES } from "./entity"; +import { supportsFeature } from "../common/entity/supports-feature"; export const SUPPORT_PAUSE = 1; export const SUPPORT_SEEK = 2; @@ -31,7 +33,7 @@ export const SUPPORT_PLAY_MEDIA = 512; export const SUPPORT_VOLUME_BUTTONS = 1024; export const SUPPORT_SELECT_SOURCE = 2048; export const SUPPORT_STOP = 4096; -export const SUPPORTS_PLAY = 16384; +export const SUPPORT_PLAY = 16384; export const SUPPORT_SELECT_SOUND_MODE = 65536; export const SUPPORT_BROWSE_MEDIA = 131072; export const CONTRAST_RATIO = 4.5; @@ -166,6 +168,7 @@ export const computeMediaDescription = (stateObj: HassEntity): string => { switch (stateObj.attributes.media_content_type) { case "music": + case "image": secondaryTitle = stateObj.attributes.media_artist; break; case "playlist": @@ -187,3 +190,85 @@ export const computeMediaDescription = (stateObj: HassEntity): string => { return secondaryTitle; }; + +export const computeMediaControls = ( + stateObj: HassEntity +): ControlButton[] | undefined => { + if (!stateObj) { + return undefined; + } + + const state = stateObj.state; + + if (UNAVAILABLE_STATES.includes(state)) { + return undefined; + } + + if (state === "off") { + return supportsFeature(stateObj, SUPPORT_TURN_ON) + ? [ + { + icon: "hass:power", + action: "turn_on", + }, + ] + : undefined; + } + + const buttons: ControlButton[] = []; + + if (supportsFeature(stateObj, SUPPORT_TURN_OFF)) { + buttons.push({ + icon: "hass:power", + action: "turn_off", + }); + } + + if ( + (state === "playing" || state === "paused") && + supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK) + ) { + buttons.push({ + icon: "hass:skip-previous", + action: "media_previous_track", + }); + } + + if ( + (state === "playing" && + (supportsFeature(stateObj, SUPPORT_PAUSE) || + supportsFeature(stateObj, SUPPORT_STOP))) || + ((state === "paused" || state === "idle") && + supportsFeature(stateObj, SUPPORT_PLAY)) || + (state === "on" && + (supportsFeature(stateObj, SUPPORT_PLAY) || + supportsFeature(stateObj, SUPPORT_PAUSE))) + ) { + buttons.push({ + icon: + state === "on" + ? "hass:play-pause" + : state !== "playing" + ? "hass:play" + : supportsFeature(stateObj, SUPPORT_PAUSE) + ? "hass:pause" + : "hass:stop", + action: + state === "playing" && !supportsFeature(stateObj, SUPPORT_PAUSE) + ? "media_stop" + : "media_play_pause", + }); + } + + if ( + (state === "playing" || state === "paused") && + supportsFeature(stateObj, SUPPORT_NEXT_TRACK) + ) { + buttons.push({ + icon: "hass:skip-next", + action: "media_next_track", + }); + } + + return buttons.length > 0 ? buttons : undefined; +}; diff --git a/src/dialogs/more-info/controls/more-info-media_player.ts b/src/dialogs/more-info/controls/more-info-media_player.ts index de427df88d..b1656d2ef9 100644 --- a/src/dialogs/more-info/controls/more-info-media_player.ts +++ b/src/dialogs/more-info/controls/more-info-media_player.ts @@ -25,19 +25,12 @@ import "../../../components/ha-svg-icon"; import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog"; import { UNAVAILABLE, UNAVAILABLE_STATES, UNKNOWN } from "../../../data/entity"; import { - ControlButton, + computeMediaControls, MediaPickedEvent, - SUPPORTS_PLAY, SUPPORT_BROWSE_MEDIA, - SUPPORT_NEXT_TRACK, - SUPPORT_PAUSE, SUPPORT_PLAY_MEDIA, - SUPPORT_PREVIOUS_TRACK, SUPPORT_SELECT_SOUND_MODE, SUPPORT_SELECT_SOURCE, - SUPPORT_STOP, - SUPPORT_TURN_OFF, - SUPPORT_TURN_ON, SUPPORT_VOLUME_BUTTONS, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, @@ -57,8 +50,8 @@ class MoreInfoMediaPlayer extends LitElement { return html``; } - const controls = this._getControls(); const stateObj = this.stateObj; + const controls = computeMediaControls(stateObj); return html` ${!controls @@ -254,89 +247,6 @@ class MoreInfoMediaPlayer extends LitElement { `; } - private _getControls(): ControlButton[] | undefined { - const stateObj = this.stateObj; - - if (!stateObj) { - return undefined; - } - - const state = stateObj.state; - - if (UNAVAILABLE_STATES.includes(state)) { - return undefined; - } - - if (state === "off") { - return supportsFeature(stateObj, SUPPORT_TURN_ON) - ? [ - { - icon: "hass:power", - action: "turn_on", - }, - ] - : undefined; - } - - if (state === "idle") { - return supportsFeature(stateObj, SUPPORTS_PLAY) - ? [ - { - icon: "hass:play", - action: "media_play", - }, - ] - : undefined; - } - - const buttons: ControlButton[] = []; - - if (supportsFeature(stateObj, SUPPORT_TURN_OFF)) { - buttons.push({ - icon: "hass:power", - action: "turn_off", - }); - } - - if (supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK)) { - buttons.push({ - icon: "hass:skip-previous", - action: "media_previous_track", - }); - } - - if ( - (state === "playing" && - (supportsFeature(stateObj, SUPPORT_PAUSE) || - supportsFeature(stateObj, SUPPORT_STOP))) || - (state === "paused" && supportsFeature(stateObj, SUPPORTS_PLAY)) || - (state === "on" && - supportsFeature(stateObj, SUPPORTS_PLAY) || - supportsFeature(stateObj, SUPPORT_PAUSE)) - ) { - buttons.push({ - icon: - state === "on" - ? "hass:play-pause" - : state !== "playing" - ? "hass:play" - : supportsFeature(stateObj, SUPPORT_PAUSE) - ? "hass:pause" - : "hass:stop", - action: state === "playing" && !supportsFeature(stateObj, SUPPORT_PAUSE) ? "media_stop" : "media_play_pause", - }); - } - - if (supportsFeature(stateObj, SUPPORT_NEXT_TRACK)) { - buttons.push({ - icon: "hass:skip-next", - action: "media_next_track", - }); - } - - return buttons.length > 0 ? buttons : undefined; - } - private _handleClick(e: MouseEvent): void { this.hass!.callService( "media_player", diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index 0f521e96c9..9ff35c43f6 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -32,18 +32,12 @@ import { showMediaBrowserDialog } from "../../../components/media-player/show-me import { UNAVAILABLE_STATES } from "../../../data/entity"; import { computeMediaDescription, + computeMediaControls, CONTRAST_RATIO, - ControlButton, getCurrentProgress, MediaPickedEvent, - SUPPORTS_PLAY, SUPPORT_BROWSE_MEDIA, - SUPPORT_NEXT_TRACK, - SUPPORT_PAUSE, - SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK, - SUPPORT_STOP, - SUPPORT_TURN_OFF, SUPPORT_TURN_ON, } from "../../../data/media-player"; import type { HomeAssistant, MediaEntity } from "../../../types"; @@ -297,7 +291,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { UNAVAILABLE_STATES.includes(state) || (state === "off" && !supportsFeature(stateObj, SUPPORT_TURN_ON)); const hasNoImage = !this._image; - const controls = this._getControls(); + const controls = computeMediaControls(stateObj); const showControls = controls && (!this._veryNarrow || isOffState || state === "idle" || state === "on"); @@ -361,9 +355,9 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { > - ${isUnavailable - ? "" - : html` + ${!isUnavailable && + (mediaDescription || stateObj.attributes.media_title || showControls) + ? html`
`} - `} + ` + : ""}
`; @@ -518,88 +513,6 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { } } - private _getControls(): ControlButton[] | undefined { - const stateObj = this._stateObj; - - if (!stateObj) { - return undefined; - } - - const state = stateObj.state; - - if (UNAVAILABLE_STATES.includes(state)) { - return undefined; - } - - if (state === "off") { - return supportsFeature(stateObj, SUPPORT_TURN_ON) - ? [ - { - icon: "hass:power", - action: "turn_on", - }, - ] - : undefined; - } - - if (state === "on") { - return supportsFeature(stateObj, SUPPORT_TURN_OFF) - ? [ - { - icon: "hass:power", - action: "turn_off", - }, - ] - : undefined; - } - - if (state === "idle") { - return supportsFeature(stateObj, SUPPORTS_PLAY) - ? [ - { - icon: "hass:play", - action: "media_play", - }, - ] - : undefined; - } - - const buttons: ControlButton[] = []; - - if (supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK)) { - buttons.push({ - icon: "hass:skip-previous", - action: "media_previous_track", - }); - } - - if ( - (state === "playing" && - (supportsFeature(stateObj, SUPPORT_PAUSE) || - supportsFeature(stateObj, SUPPORT_STOP))) || - (state === "paused" && supportsFeature(stateObj, SUPPORTS_PLAY)) - ) { - buttons.push({ - icon: - state !== "playing" - ? "hass:play" - : supportsFeature(stateObj, SUPPORT_PAUSE) - ? "hass:pause" - : "hass:stop", - action: "media_play_pause", - }); - } - - if (supportsFeature(stateObj, SUPPORT_NEXT_TRACK)) { - buttons.push({ - icon: "hass:skip-next", - action: "media_next_track", - }); - } - - return buttons.length > 0 ? buttons : undefined; - } - private get _image() { if (!this.hass || !this._config) { return undefined; @@ -866,6 +779,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard { ha-icon-button[action="media_play"], ha-icon-button[action="media_play_pause"], + ha-icon-button[action="media_stop"], ha-icon-button[action="turn_on"], ha-icon-button[action="turn_off"] { --mdc-icon-button-size: 56px; diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts index e1d132ebd4..654e4dd771 100644 --- a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts @@ -15,12 +15,13 @@ import { supportsFeature } from "../../../common/entity/supports-feature"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; import { debounce } from "../../../common/util/debounce"; import "../../../components/ha-slider"; -import { UNAVAILABLE, UNKNOWN } from "../../../data/entity"; +import { UNAVAILABLE, UNKNOWN, UNAVAILABLE_STATES } from "../../../data/entity"; import { - SUPPORTS_PLAY, + SUPPORT_PLAY, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK, + SUPPORT_STOP, SUPPORT_TURN_OFF, SUPPORT_TURN_ON, SUPPORT_VOLUME_BUTTONS, @@ -80,6 +81,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { } const stateObj = this.hass.states[this._config.entity]; + const state = stateObj.state; if (!stateObj) { return html` @@ -90,7 +92,9 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { } const buttons = html` - ${!this._narrow && supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK) + ${!this._narrow && + state === "playing" && + supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK) ? html` ` : ""} - ${stateObj.state !== "playing" && - !supportsFeature(stateObj, SUPPORTS_PLAY) - ? "" - : html` + ${(state === "playing" && + (supportsFeature(stateObj, SUPPORT_PAUSE) || + supportsFeature(stateObj, SUPPORT_STOP))) || + ((state === "paused" || state === "idle") && + supportsFeature(stateObj, SUPPORT_PLAY)) || + (state === "on" && + (supportsFeature(stateObj, SUPPORT_PLAY) || + supportsFeature(stateObj, SUPPORT_PAUSE))) + ? html` - `} - ${supportsFeature(stateObj, SUPPORT_NEXT_TRACK) + ` + : ""} + ${state === "playing" && supportsFeature(stateObj, SUPPORT_NEXT_TRACK) ? html`
${supportsFeature(stateObj, SUPPORT_TURN_ON) && - stateObj.state === "off" + state === "off" && + !UNAVAILABLE_STATES.includes(state) ? html` ${(supportsFeature(stateObj, SUPPORT_VOLUME_SET) || supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS)) && - ![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state) + ![UNAVAILABLE, UNKNOWN, "off"].includes(state) ? html`
@@ -220,12 +233,11 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { } private _computeControlIcon(stateObj: HassEntity): string { - if (stateObj.state !== "playing") { - return "hass:play"; - } - - // eslint-disable-next-line:no-bitwise - return supportsFeature(stateObj, SUPPORT_PAUSE) + return stateObj.state === "on" + ? "hass:play-pause" + : stateObj.state !== "playing" + ? "hass:play" + : supportsFeature(stateObj, SUPPORT_PAUSE) ? "hass:pause" : "hass:stop"; }