Skip to content

Commit

Permalink
Added "Media player volume" card feature.
Browse files Browse the repository at this point in the history
  • Loading branch information
simon-zumbrunnen committed Dec 7, 2024
1 parent 43f31dd commit 783688d
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 0 deletions.
12 changes: 12 additions & 0 deletions gallery/src/pages/lovelace/tile-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const ENTITIES = [
device_class: "lock",
supported_features: LockEntityFeature.OPEN,
}),
getEntity("media_player", "living_room", "playing", {
friendly_name: "Living room speaker",
}),
getEntity("climate", "thermostat", "heat", {
current_temperature: 73,
min_temp: 45,
Expand Down Expand Up @@ -197,6 +200,15 @@ const CONFIGS = [
- type: "lock-open-door"
`,
},
{
heading: "Media player volume feature",
config: `
- type: tile
entity: media_player.living_room
features:
- type: "media-player-volume"
`,
},
{
heading: "Vacuum commands feature",
config: `
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
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 { MediaPlayerCardFeatureConfig } from "./types";

export const supportsMediaPlayerVolumeCardFeature = (stateObj: HassEntity) => {
const domain = computeDomain(stateObj.entity_id);
return domain === "media_player";
};

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

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

@state() private _config?: MediaPlayerCardFeatureConfig;

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

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

protected render() {
if (
!this._config ||
!this.hass ||
!this.stateObj ||
!supportsMediaPlayerVolumeCardFeature(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-card-feature": HuiMediaPlayerVolumeCardFeature;
}
}
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 MediaPlayerCardFeatureConfig {
type: "media-player-volume";
}

export interface FanPresetModesCardFeatureConfig {
type: "fan-preset-modes";
style?: "dropdown" | "icons";
Expand Down Expand Up @@ -161,6 +165,7 @@ export type LovelaceCardFeatureConfig =
| LightColorTempCardFeatureConfig
| LockCommandsCardFeatureConfig
| LockOpenDoorCardFeatureConfig
| MediaPlayerCardFeatureConfig
| 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-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",
"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 { supportsMediaPlayerVolumeCardFeature } from "../../card-features/hui-media-player-volume-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",
"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": supportsMediaPlayerVolumeCardFeature,
"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 @@ -6597,6 +6597,9 @@
"lock-open-door": {
"label": "Lock open door"
},
"media-player-volume": {
"label": "Media player volume"
},
"vacuum-commands": {
"label": "Vacuum commands",
"commands": "Commands",
Expand Down

0 comments on commit 783688d

Please sign in to comment.