Skip to content

Commit

Permalink
Added "Media player volume slider" card feature. (#23199)
Browse files Browse the repository at this point in the history
* Added "Media player volume" card feature.

* Make sure the feature is not displayed on unsupported players

Co-authored-by: Petar Petrov <[email protected]>

* Renamed to Media player volume *slider*

* Missed one rename.

---------

Co-authored-by: Simon Zumbrunnen <[email protected]>
Co-authored-by: Petar Petrov <[email protected]>
  • Loading branch information
3 people authored Dec 10, 2024
1 parent 9d83cc6 commit da727d3
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 0 deletions.
14 changes: 14 additions & 0 deletions gallery/src/pages/lovelace/tile-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { customElement, query } from "lit/decorators";
import { CoverEntityFeature } from "../../../../src/data/cover";
import { LightColorMode } from "../../../../src/data/light";
import { LockEntityFeature } from "../../../../src/data/lock";
import { MediaPlayerEntityFeature } from "../../../../src/data/media-player";
import { VacuumEntityFeature } from "../../../../src/data/vacuum";
import { getEntity } from "../../../../src/fake_data/entity";
import { provideHass } from "../../../../src/fake_data/provide_hass";
Expand All @@ -28,6 +29,10 @@ const ENTITIES = [
device_class: "lock",
supported_features: LockEntityFeature.OPEN,
}),
getEntity("media_player", "living_room", "playing", {
friendly_name: "Living room speaker",
supported_features: MediaPlayerEntityFeature.VOLUME_SET,
}),
getEntity("climate", "thermostat", "heat", {
current_temperature: 73,
min_temp: 45,
Expand Down Expand Up @@ -197,6 +202,15 @@ const CONFIGS = [
- type: "lock-open-door"
`,
},
{
heading: "Media player volume slider feature",
config: `
- type: tile
entity: media_player.living_room
features:
- type: "media-player-volume-slider"
`,
},
{
heading: "Vacuum commands feature",
config: `
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { HassEntity } from "home-assistant-js-websocket";
import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
import { computeDomain } from "../../../common/entity/compute_domain";
import { stateActive } from "../../../common/entity/state_active";
import "../../../components/ha-control-slider";
import { isUnavailableState } from "../../../data/entity";
import type { HomeAssistant } from "../../../types";
import type { LovelaceCardFeature } from "../types";
import { cardFeatureStyles } from "./common/card-feature-styles";
import type { MediaPlayerVolumeSliderCardFeatureConfig } from "./types";
import { MediaPlayerEntityFeature } from "../../../data/media-player";
import { supportsFeature } from "../../../common/entity/supports-feature";

export const supportsMediaPlayerVolumeSliderCardFeature = (
stateObj: HassEntity
) => {
const domain = computeDomain(stateObj.entity_id);
return (
domain === "media_player" &&
supportsFeature(stateObj, MediaPlayerEntityFeature.VOLUME_SET)
);
};

@customElement("hui-media-player-volume-slider-card-feature")
class HuiMediaPlayerVolumeSliderCardFeature
extends LitElement
implements LovelaceCardFeature
{
@property({ attribute: false }) public hass?: HomeAssistant;

@property({ attribute: false }) public stateObj?: HassEntity;

@state() private _config?: MediaPlayerVolumeSliderCardFeatureConfig;

static getStubConfig(): MediaPlayerVolumeSliderCardFeatureConfig {
return {
type: "media-player-volume-slider",
};
}

public setConfig(config: MediaPlayerVolumeSliderCardFeatureConfig): void {
if (!config) {
throw new Error("Invalid configuration");
}
this._config = config;
}

protected render() {
if (
!this._config ||
!this.hass ||
!this.stateObj ||
!supportsMediaPlayerVolumeSliderCardFeature(this.stateObj)
) {
return nothing;
}

const position =
this.stateObj.attributes.volume_level != null
? Math.round(this.stateObj.attributes.volume_level * 100)
: undefined;

return html`
<ha-control-slider
.value=${position}
min="0"
max="100"
.showHandle=${stateActive(this.stateObj)}
.disabled=${!this.stateObj || isUnavailableState(this.stateObj.state)}
@value-changed=${this._valueChanged}
unit="%"
.locale=${this.hass.locale}
></ha-control-slider>
`;
}

private _valueChanged(ev: CustomEvent) {
ev.stopPropagation();
const value = ev.detail.value;

this.hass!.callService("media_player", "volume_set", {
entity_id: this.stateObj!.entity_id,
volume_level: value / 100,
});
}

static get styles() {
return cardFeatureStyles;
}
}

declare global {
interface HTMLElementTagNameMap {
"hui-media-player-volume-slider-card-feature": HuiMediaPlayerVolumeSliderCardFeature;
}
}
5 changes: 5 additions & 0 deletions src/panels/lovelace/card-features/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export interface LockOpenDoorCardFeatureConfig {
type: "lock-open-door";
}

export interface MediaPlayerVolumeSliderCardFeatureConfig {
type: "media-player-volume-slider";
}

export interface FanPresetModesCardFeatureConfig {
type: "fan-preset-modes";
style?: "dropdown" | "icons";
Expand Down Expand Up @@ -161,6 +165,7 @@ export type LovelaceCardFeatureConfig =
| LightColorTempCardFeatureConfig
| LockCommandsCardFeatureConfig
| LockOpenDoorCardFeatureConfig
| MediaPlayerVolumeSliderCardFeatureConfig
| NumericInputCardFeatureConfig
| SelectOptionsCardFeatureConfig
| TargetHumidityCardFeatureConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import "../card-features/hui-light-brightness-card-feature";
import "../card-features/hui-light-color-temp-card-feature";
import "../card-features/hui-lock-commands-card-feature";
import "../card-features/hui-lock-open-door-card-feature";
import "../card-features/hui-media-player-volume-slider-card-feature";
import "../card-features/hui-numeric-input-card-feature";
import "../card-features/hui-select-options-card-feature";
import "../card-features/hui-target-temperature-card-feature";
Expand Down Expand Up @@ -51,6 +52,7 @@ const TYPES: Set<LovelaceCardFeatureConfig["type"]> = new Set([
"light-color-temp",
"lock-commands",
"lock-open-door",
"media-player-volume-slider",
"numeric-input",
"select-options",
"target-humidity",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { supportsLightBrightnessCardFeature } from "../../card-features/hui-ligh
import { supportsLightColorTempCardFeature } from "../../card-features/hui-light-color-temp-card-feature";
import { supportsLockCommandsCardFeature } from "../../card-features/hui-lock-commands-card-feature";
import { supportsLockOpenDoorCardFeature } from "../../card-features/hui-lock-open-door-card-feature";
import { supportsMediaPlayerVolumeSliderCardFeature } from "../../card-features/hui-media-player-volume-slider-card-feature";
import { supportsNumericInputCardFeature } from "../../card-features/hui-numeric-input-card-feature";
import { supportsSelectOptionsCardFeature } from "../../card-features/hui-select-options-card-feature";
import { supportsTargetHumidityCardFeature } from "../../card-features/hui-target-humidity-card-feature";
Expand Down Expand Up @@ -71,6 +72,7 @@ const UI_FEATURE_TYPES = [
"light-color-temp",
"lock-commands",
"lock-open-door",
"media-player-volume-slider",
"numeric-input",
"select-options",
"target-humidity",
Expand Down Expand Up @@ -123,6 +125,7 @@ const SUPPORTS_FEATURE_TYPES: Record<
"light-color-temp": supportsLightColorTempCardFeature,
"lock-commands": supportsLockCommandsCardFeature,
"lock-open-door": supportsLockOpenDoorCardFeature,
"media-player-volume-slider": supportsMediaPlayerVolumeSliderCardFeature,
"numeric-input": supportsNumericInputCardFeature,
"select-options": supportsSelectOptionsCardFeature,
"target-humidity": supportsTargetHumidityCardFeature,
Expand Down
3 changes: 3 additions & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -6599,6 +6599,9 @@
"lock-open-door": {
"label": "Lock open door"
},
"media-player-volume-slider": {
"label": "Media player volume slider"
},
"vacuum-commands": {
"label": "Vacuum commands",
"commands": "Commands",
Expand Down

0 comments on commit da727d3

Please sign in to comment.