mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Fix fan speed for new more info and tile feature (#16050)
This commit is contained in:
parent
9764a0f23f
commit
99e6547807
@ -2,6 +2,7 @@ import {
|
|||||||
HassEntityAttributeBase,
|
HassEntityAttributeBase,
|
||||||
HassEntityBase,
|
HassEntityBase,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
|
import { stateActive } from "../common/entity/state_active";
|
||||||
import { supportsFeature } from "../common/entity/supports-feature";
|
import { supportsFeature } from "../common/entity/supports-feature";
|
||||||
import { blankBeforePercent } from "../common/translations/blank_before_percent";
|
import { blankBeforePercent } from "../common/translations/blank_before_percent";
|
||||||
import { UNAVAILABLE } from "./entity";
|
import { UNAVAILABLE } from "./entity";
|
||||||
@ -114,10 +115,12 @@ export function computeCoverPositionStateDisplay(
|
|||||||
locale: FrontendLocaleData,
|
locale: FrontendLocaleData,
|
||||||
position?: number
|
position?: number
|
||||||
) {
|
) {
|
||||||
const currentPosition =
|
const statePosition = stateActive(stateObj)
|
||||||
position ??
|
? stateObj.attributes.current_position ??
|
||||||
stateObj.attributes.current_position ??
|
stateObj.attributes.current_tilt_position
|
||||||
stateObj.attributes.current_tilt_position;
|
: undefined;
|
||||||
|
|
||||||
|
const currentPosition = position ?? statePosition;
|
||||||
|
|
||||||
return currentPosition && currentPosition !== 100
|
return currentPosition && currentPosition !== 100
|
||||||
? `${Math.round(currentPosition)}${blankBeforePercent(locale)}%`
|
? `${Math.round(currentPosition)}${blankBeforePercent(locale)}%`
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
HassEntityAttributeBase,
|
HassEntityAttributeBase,
|
||||||
HassEntityBase,
|
HassEntityBase,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
|
import { stateActive } from "../common/entity/state_active";
|
||||||
import { blankBeforePercent } from "../common/translations/blank_before_percent";
|
import { blankBeforePercent } from "../common/translations/blank_before_percent";
|
||||||
import { FrontendLocaleData } from "./translation";
|
import { FrontendLocaleData } from "./translation";
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ export function fanSpeedToPercentage(
|
|||||||
if (speedValue === -1) {
|
if (speedValue === -1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return Math.round(speedValue * step);
|
return Math.floor(speedValue * step);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function computeFanSpeedCount(stateObj: FanEntity): number {
|
export function computeFanSpeedCount(stateObj: FanEntity): number {
|
||||||
@ -99,9 +100,12 @@ export function computeFanSpeedStateDisplay(
|
|||||||
locale: FrontendLocaleData,
|
locale: FrontendLocaleData,
|
||||||
speed?: number
|
speed?: number
|
||||||
) {
|
) {
|
||||||
const currentSpeed = speed ?? stateObj.attributes.percentage;
|
const percentage = stateActive(stateObj)
|
||||||
|
? stateObj.attributes.percentage
|
||||||
|
: undefined;
|
||||||
|
const currentSpeed = speed ?? percentage;
|
||||||
|
|
||||||
return currentSpeed
|
return currentSpeed
|
||||||
? `${Math.round(currentSpeed)}${blankBeforePercent(locale)}%`
|
? `${Math.floor(currentSpeed)}${blankBeforePercent(locale)}%`
|
||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { customElement, property, state } from "lit/decorators";
|
|||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { computeAttributeNameDisplay } from "../../../../common/entity/compute_attribute_display";
|
import { computeAttributeNameDisplay } from "../../../../common/entity/compute_attribute_display";
|
||||||
import { computeStateDisplay } from "../../../../common/entity/compute_state_display";
|
import { computeStateDisplay } from "../../../../common/entity/compute_state_display";
|
||||||
|
import { stateActive } from "../../../../common/entity/state_active";
|
||||||
import { stateColorCss } from "../../../../common/entity/state_color";
|
import { stateColorCss } from "../../../../common/entity/state_color";
|
||||||
import "../../../../components/ha-control-select";
|
import "../../../../components/ha-control-select";
|
||||||
import type { ControlSelectOption } from "../../../../components/ha-control-select";
|
import type { ControlSelectOption } from "../../../../components/ha-control-select";
|
||||||
@ -26,20 +27,25 @@ export class HaMoreInfoFanSpeed extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public stateObj!: FanEntity;
|
@property({ attribute: false }) public stateObj!: FanEntity;
|
||||||
|
|
||||||
@state() value?: number;
|
@state() sliderValue?: number;
|
||||||
|
|
||||||
|
@state() speedValue?: FanSpeed;
|
||||||
|
|
||||||
protected updated(changedProp: Map<string | number | symbol, unknown>): void {
|
protected updated(changedProp: Map<string | number | symbol, unknown>): void {
|
||||||
if (changedProp.has("stateObj")) {
|
if (changedProp.has("stateObj")) {
|
||||||
this.value =
|
const percentage = stateActive(this.stateObj)
|
||||||
this.stateObj.attributes.percentage != null
|
? this.stateObj.attributes.percentage ?? 0
|
||||||
? Math.max(Math.round(this.stateObj.attributes.percentage), 1)
|
: 0;
|
||||||
: undefined;
|
this.sliderValue = Math.max(Math.round(percentage), 0);
|
||||||
|
this.speedValue = fanPercentageToSpeed(this.stateObj, percentage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _speedValueChanged(ev: CustomEvent) {
|
private _speedValueChanged(ev: CustomEvent) {
|
||||||
const speed = (ev.detail as any).value as FanSpeed;
|
const speed = (ev.detail as any).value as FanSpeed;
|
||||||
|
|
||||||
|
this.speedValue = speed;
|
||||||
|
|
||||||
const percentage = fanSpeedToPercentage(this.stateObj, speed);
|
const percentage = fanSpeedToPercentage(this.stateObj, speed);
|
||||||
|
|
||||||
this.hass.callService("fan", "set_percentage", {
|
this.hass.callService("fan", "set_percentage", {
|
||||||
@ -52,6 +58,8 @@ export class HaMoreInfoFanSpeed extends LitElement {
|
|||||||
const value = (ev.detail as any).value;
|
const value = (ev.detail as any).value;
|
||||||
if (isNaN(value)) return;
|
if (isNaN(value)) return;
|
||||||
|
|
||||||
|
this.sliderValue = value;
|
||||||
|
|
||||||
this.hass.callService("fan", "set_percentage", {
|
this.hass.callService("fan", "set_percentage", {
|
||||||
entity_id: this.stateObj!.entity_id,
|
entity_id: this.stateObj!.entity_id,
|
||||||
percentage: value,
|
percentage: value,
|
||||||
@ -88,16 +96,11 @@ export class HaMoreInfoFanSpeed extends LitElement {
|
|||||||
})
|
})
|
||||||
).reverse();
|
).reverse();
|
||||||
|
|
||||||
const speed = fanPercentageToSpeed(
|
|
||||||
this.stateObj,
|
|
||||||
this.stateObj.attributes.percentage ?? 0
|
|
||||||
);
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-control-select
|
<ha-control-select
|
||||||
vertical
|
vertical
|
||||||
.options=${options}
|
.options=${options}
|
||||||
.value=${speed}
|
.value=${this.speedValue}
|
||||||
@value-changed=${this._speedValueChanged}
|
@value-changed=${this._speedValueChanged}
|
||||||
.ariaLabel=${computeAttributeNameDisplay(
|
.ariaLabel=${computeAttributeNameDisplay(
|
||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
@ -119,7 +122,7 @@ export class HaMoreInfoFanSpeed extends LitElement {
|
|||||||
vertical
|
vertical
|
||||||
min="0"
|
min="0"
|
||||||
max="100"
|
max="100"
|
||||||
.value=${this.value}
|
.value=${this.sliderValue}
|
||||||
.step=${this.stateObj.attributes.percentage_step ?? 1}
|
.step=${this.stateObj.attributes.percentage_step ?? 1}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
.ariaLabel=${computeAttributeNameDisplay(
|
.ariaLabel=${computeAttributeNameDisplay(
|
||||||
|
@ -23,6 +23,7 @@ import {
|
|||||||
computeAttributeValueDisplay,
|
computeAttributeValueDisplay,
|
||||||
} from "../../../common/entity/compute_attribute_display";
|
} from "../../../common/entity/compute_attribute_display";
|
||||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||||
|
import { stateActive } from "../../../common/entity/state_active";
|
||||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||||
import "../../../components/ha-attributes";
|
import "../../../components/ha-attributes";
|
||||||
import { UNAVAILABLE } from "../../../data/entity";
|
import { UNAVAILABLE } from "../../../data/entity";
|
||||||
@ -119,7 +120,7 @@ class MoreInfoFan extends LitElement {
|
|||||||
const liveValue = this._liveSpeed;
|
const liveValue = this._liveSpeed;
|
||||||
|
|
||||||
const forcedState =
|
const forcedState =
|
||||||
this._liveSpeed != null ? (this._liveSpeed ? "on" : "off") : undefined;
|
liveValue != null ? (liveValue ? "on" : "off") : undefined;
|
||||||
|
|
||||||
const stateDisplay = computeStateDisplay(
|
const stateDisplay = computeStateDisplay(
|
||||||
this.hass.localize,
|
this.hass.localize,
|
||||||
@ -135,7 +136,7 @@ class MoreInfoFan extends LitElement {
|
|||||||
liveValue
|
liveValue
|
||||||
);
|
);
|
||||||
|
|
||||||
if (positionStateDisplay) {
|
if (positionStateDisplay && (stateActive(this.stateObj!) || liveValue)) {
|
||||||
return positionStateDisplay;
|
return positionStateDisplay;
|
||||||
}
|
}
|
||||||
return stateDisplay;
|
return stateDisplay;
|
||||||
|
@ -214,7 +214,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (domain === "fan" && stateActive(stateObj)) {
|
if (domain === "fan") {
|
||||||
const speedStateDisplay = computeFanSpeedStateDisplay(
|
const speedStateDisplay = computeFanSpeedStateDisplay(
|
||||||
stateObj as FanEntity,
|
stateObj as FanEntity,
|
||||||
this.hass!.locale
|
this.hass!.locale
|
||||||
@ -231,12 +231,11 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
|||||||
this.hass!.entities
|
this.hass!.entities
|
||||||
);
|
);
|
||||||
|
|
||||||
if (domain === "cover" && stateActive(stateObj)) {
|
if (domain === "cover") {
|
||||||
const positionStateDisplay = computeCoverPositionStateDisplay(
|
const positionStateDisplay = computeCoverPositionStateDisplay(
|
||||||
stateObj as CoverEntity,
|
stateObj as CoverEntity,
|
||||||
this.hass!.locale
|
this.hass!.locale
|
||||||
);
|
);
|
||||||
|
|
||||||
if (positionStateDisplay) {
|
if (positionStateDisplay) {
|
||||||
return `${stateDisplay} ⸱ ${positionStateDisplay}`;
|
return `${stateDisplay} ⸱ ${positionStateDisplay}`;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import { customElement, property, state } from "lit/decorators";
|
|||||||
import { computeAttributeNameDisplay } from "../../../common/entity/compute_attribute_display";
|
import { computeAttributeNameDisplay } from "../../../common/entity/compute_attribute_display";
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
||||||
|
import { stateActive } from "../../../common/entity/state_active";
|
||||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||||
import "../../../components/ha-control-select";
|
import "../../../components/ha-control-select";
|
||||||
import type { ControlSelectOption } from "../../../components/ha-control-select";
|
import type { ControlSelectOption } from "../../../components/ha-control-select";
|
||||||
@ -12,6 +13,7 @@ import { UNAVAILABLE } from "../../../data/entity";
|
|||||||
import {
|
import {
|
||||||
computeFanSpeedCount,
|
computeFanSpeedCount,
|
||||||
computeFanSpeedIcon,
|
computeFanSpeedIcon,
|
||||||
|
FanEntity,
|
||||||
FanEntityFeature,
|
FanEntityFeature,
|
||||||
fanPercentageToSpeed,
|
fanPercentageToSpeed,
|
||||||
FanSpeed,
|
FanSpeed,
|
||||||
@ -34,7 +36,7 @@ export const supportsFanSpeedTileFeature = (stateObj: HassEntity) => {
|
|||||||
class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature {
|
class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature {
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false }) public stateObj?: HassEntity;
|
@property({ attribute: false }) public stateObj?: FanEntity;
|
||||||
|
|
||||||
@state() private _config?: FanSpeedTileFeatureConfig;
|
@state() private _config?: FanSpeedTileFeatureConfig;
|
||||||
|
|
||||||
@ -79,6 +81,10 @@ class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature {
|
|||||||
|
|
||||||
const speedCount = computeFanSpeedCount(this.stateObj);
|
const speedCount = computeFanSpeedCount(this.stateObj);
|
||||||
|
|
||||||
|
const percentage = stateActive(this.stateObj)
|
||||||
|
? this.stateObj.attributes.percentage ?? 0
|
||||||
|
: 0;
|
||||||
|
|
||||||
if (speedCount <= FAN_SPEED_COUNT_MAX_FOR_BUTTONS) {
|
if (speedCount <= FAN_SPEED_COUNT_MAX_FOR_BUTTONS) {
|
||||||
const options = FAN_SPEEDS[speedCount]!.map<ControlSelectOption>(
|
const options = FAN_SPEEDS[speedCount]!.map<ControlSelectOption>(
|
||||||
(speed) => ({
|
(speed) => ({
|
||||||
@ -88,10 +94,7 @@ class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const speed = fanPercentageToSpeed(
|
const speed = fanPercentageToSpeed(this.stateObj, percentage);
|
||||||
this.stateObj,
|
|
||||||
this.stateObj.attributes.percentage ?? 0
|
|
||||||
);
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -113,15 +116,12 @@ class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const percentage =
|
const value = Math.max(Math.round(percentage), 0);
|
||||||
this.stateObj.attributes.percentage != null
|
|
||||||
? Math.max(Math.round(this.stateObj.attributes.percentage), 0)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<ha-control-slider
|
<ha-control-slider
|
||||||
.value=${percentage}
|
.value=${value}
|
||||||
min="0"
|
min="0"
|
||||||
max="100"
|
max="100"
|
||||||
.step=${this.stateObj.attributes.percentage_step ?? 1}
|
.step=${this.stateObj.attributes.percentage_step ?? 1}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user