diff --git a/src/data/fan.ts b/src/data/fan.ts index ca8e9e5a63..9dbef3fbb4 100644 --- a/src/data/fan.ts +++ b/src/data/fan.ts @@ -9,6 +9,8 @@ import { HassEntityAttributeBase, HassEntityBase, } from "home-assistant-js-websocket"; +import { blankBeforePercent } from "../common/translations/blank_before_percent"; +import { FrontendLocaleData } from "./translation"; export const enum FanEntityFeature { SET_SPEED = 1, @@ -91,3 +93,15 @@ export function computeFanSpeedIcon( : [mdiFanSpeed1, mdiFanSpeed2, mdiFanSpeed3][index - 1]; } export const FAN_SPEED_COUNT_MAX_FOR_BUTTONS = 4; + +export function computeFanSpeedStateDisplay( + stateObj: FanEntity, + locale: FrontendLocaleData, + speed?: number +) { + const currentSpeed = speed ?? stateObj.attributes.percentage; + + return currentSpeed + ? `${Math.round(currentSpeed)}${blankBeforePercent(locale)}%` + : ""; +} diff --git a/src/dialogs/more-info/controls/more-info-fan.ts b/src/dialogs/more-info/controls/more-info-fan.ts index 701dff67a2..72b5db5b7f 100644 --- a/src/dialogs/more-info/controls/more-info-fan.ts +++ b/src/dialogs/more-info/controls/more-info-fan.ts @@ -22,11 +22,12 @@ import { computeAttributeNameDisplay, computeAttributeValueDisplay, } from "../../../common/entity/compute_attribute_display"; +import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { supportsFeature } from "../../../common/entity/supports-feature"; -import { blankBeforePercent } from "../../../common/translations/blank_before_percent"; import "../../../components/ha-attributes"; import { UNAVAILABLE } from "../../../data/entity"; import { + computeFanSpeedStateDisplay, computeFanSpeedCount, FanEntity, FanEntityFeature, @@ -49,12 +50,16 @@ class MoreInfoFan extends LitElement { @state() public _presetMode?: string; - @state() private _selectedPercentage?: number; + @state() private _liveSpeed?: number; - private _percentageChanged(ev) { + private _speedSliderMoved(ev) { const value = (ev.detail as any).value; if (isNaN(value)) return; - this._selectedPercentage = value; + this._liveSpeed = value; + } + + private _speedValueChanged() { + this._liveSpeed = undefined; } private _toggle = () => { @@ -107,12 +112,35 @@ class MoreInfoFan extends LitElement { protected updated(changedProps: PropertyValues): void { if (changedProps.has("stateObj")) { this._presetMode = this.stateObj?.attributes.preset_mode; - this._selectedPercentage = this.stateObj?.attributes.percentage - ? Math.round(this.stateObj.attributes.percentage) - : undefined; } } + private get _stateOverride() { + const liveValue = this._liveSpeed; + + const forcedState = + this._liveSpeed != null ? (this._liveSpeed ? "on" : "off") : undefined; + + const stateDisplay = computeStateDisplay( + this.hass.localize, + this.stateObj!, + this.hass.locale, + this.hass.entities, + forcedState + ); + + const positionStateDisplay = computeFanSpeedStateDisplay( + this.stateObj!, + this.hass.locale, + liveValue + ); + + if (positionStateDisplay) { + return positionStateDisplay; + } + return stateDisplay; + } + protected render() { if (!this.hass || !this.stateObj) { return nothing; @@ -140,17 +168,11 @@ class MoreInfoFan extends LitElement { supportsSpeed && computeFanSpeedCount(this.stateObj) > FAN_SPEED_COUNT_MAX_FOR_BUTTONS; - const stateOverride = this._selectedPercentage - ? `${Math.round(this._selectedPercentage)}${blankBeforePercent( - this.hass!.locale - )}%` - : undefined; - return html`
${ @@ -159,7 +181,8 @@ class MoreInfoFan extends LitElement { ` diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index ffa97e181a..45269255b3 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -41,7 +41,7 @@ import { CoverEntity, } from "../../../data/cover"; import { isUnavailableState } from "../../../data/entity"; -import { FanEntity } from "../../../data/fan"; +import { computeFanSpeedStateDisplay, FanEntity } from "../../../data/fan"; import { LightEntity } from "../../../data/light"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor"; @@ -215,9 +215,12 @@ export class HuiTileCard extends LitElement implements LovelaceCard { } if (domain === "fan" && stateActive(stateObj)) { - const speed = (stateObj as FanEntity).attributes.percentage; - if (speed) { - return `${Math.round(speed)}${blankBeforePercent(this.hass!.locale)}%`; + const speedStateDisplay = computeFanSpeedStateDisplay( + stateObj as FanEntity, + this.hass!.locale + ); + if (speedStateDisplay) { + return speedStateDisplay; } }