From 8e009f24f989028d59fd08ade844c1e22ce2680e Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Thu, 25 Sep 2025 22:51:03 -0700 Subject: [PATCH] Add dropdown mode to water heater operation feature (#27201) --- ...ter-heater-operation-modes-card-feature.ts | 77 ++++++++++++++++--- src/panels/lovelace/card-features/types.ts | 1 + ...ter-operation-modes-card-feature-editor.ts | 20 +++++ src/translations/en.json | 7 +- 4 files changed, 95 insertions(+), 10 deletions(-) diff --git a/src/panels/lovelace/card-features/hui-water-heater-operation-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-water-heater-operation-modes-card-feature.ts index 7f28354ad6..3ee1ef8351 100644 --- a/src/panels/lovelace/card-features/hui-water-heater-operation-modes-card-feature.ts +++ b/src/panels/lovelace/card-features/hui-water-heater-operation-modes-card-feature.ts @@ -1,30 +1,32 @@ +import { mdiWaterBoiler } from "@mdi/js"; import type { PropertyValues, TemplateResult } from "lit"; import { html, LitElement } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { customElement, property, query, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; +import { stopPropagation } from "../../../common/dom/stop_propagation"; import { computeDomain } from "../../../common/entity/compute_domain"; import { stateColorCss } from "../../../common/entity/state_color"; -import "../../../components/ha-control-button"; -import "../../../components/ha-control-button-group"; import "../../../components/ha-control-select"; import type { ControlSelectOption } from "../../../components/ha-control-select"; -import "../../../components/ha-control-slider"; -import { UNAVAILABLE } from "../../../data/entity"; +import "../../../components/ha-control-select-menu"; +import type { HaControlSelectMenu } from "../../../components/ha-control-select-menu"; +import "../../../components/ha-list-item"; import type { OperationMode, WaterHeaterEntity, } from "../../../data/water_heater"; import { - compareWaterHeaterOperationMode, computeOperationModeIcon, + compareWaterHeaterOperationMode, } from "../../../data/water_heater"; +import { UNAVAILABLE } from "../../../data/entity"; import type { HomeAssistant } from "../../../types"; import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types"; import { cardFeatureStyles } from "./common/card-feature-styles"; import { filterModes } from "./common/filter-modes"; import type { - LovelaceCardFeatureContext, WaterHeaterOperationModesCardFeatureConfig, + LovelaceCardFeatureContext, } from "./types"; export const supportsWaterHeaterOperationModesCardFeature = ( @@ -52,6 +54,9 @@ class HuiWaterHeaterOperationModeCardFeature @state() _currentOperationMode?: OperationMode; + @query("ha-control-select-menu", true) + private _haSelect?: HaControlSelectMenu; + private get _stateObj() { if (!this.hass || !this.context || !this.context.entity_id) { return undefined; @@ -97,8 +102,23 @@ class HuiWaterHeaterOperationModeCardFeature } } + protected updated(changedProps: PropertyValues) { + super.updated(changedProps); + if (this._haSelect && changedProps.has("hass")) { + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if ( + this.hass && + this.hass.formatEntityAttributeValue !== + oldHass?.formatEntityAttributeValue + ) { + this._haSelect.layoutOptions(); + } + } + } + private async _valueChanged(ev: CustomEvent) { - const mode = (ev.detail as any).value as OperationMode; + const mode = + (ev.detail as any).value ?? ((ev.target as any).value as OperationMode); if (mode === this._stateObj!.state) return; @@ -143,9 +163,48 @@ class HuiWaterHeaterOperationModeCardFeature ).map((mode) => ({ value: mode, label: this.hass!.formatEntityState(this._stateObj!, mode), - path: computeOperationModeIcon(mode as OperationMode), + icon: html` + + `, })); + if (this._config.style === "dropdown") { + return html` + + ${this._currentOperationMode + ? html` + + ` + : html` + + `} + ${options.map( + (option) => html` + + ${option.icon}${option.label} + + ` + )} + + `; + } + return html` [ + { + name: "style", + selector: { + select: { + multiple: false, + mode: "list", + options: ["dropdown", "icons"].map((mode) => ({ + value: mode, + label: localize( + `ui.panel.lovelace.editor.features.types.water-heater-operation-modes.style_list.${mode}` + ), + })), + }, + }, + }, { name: "customize_modes", selector: { @@ -85,11 +102,13 @@ export class HuiWaterHeaterOperationModesCardFeatureEditor : undefined; const data: WaterHeaterOperationModesCardFeatureData = { + style: "icons", ...this._config, customize_modes: this._config.operation_modes !== undefined, }; const schema = this._schema( + this.hass.localize, this.hass.formatEntityState, stateObj, data.customize_modes @@ -131,6 +150,7 @@ export class HuiWaterHeaterOperationModesCardFeatureEditor ) => { switch (schema.name) { case "operation_modes": + case "style": case "customize_modes": return this.hass!.localize( `ui.panel.lovelace.editor.features.types.water-heater-operation-modes.${schema.name}` diff --git a/src/translations/en.json b/src/translations/en.json index b61ccbf6b8..9951e751fd 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -8217,7 +8217,12 @@ "water-heater-operation-modes": { "label": "Water heater operation modes", "operation_modes": "Operation modes", - "customize_modes": "Customize operation modes" + "customize_modes": "Customize operation modes", + "style": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style%]", + "style_list": { + "dropdown": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::dropdown%]", + "icons": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style_list::icons%]" + } }, "lawn-mower-commands": { "label": "Lawn mower commands",