From cb97918005ca0b2b4f47bd2cd77b698449d49e9f Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Tue, 29 Nov 2022 16:06:36 +0100 Subject: [PATCH] Show percentage for light, cover and fan for tile card (#14475) --- src/data/fan.ts | 28 ++++++-- .../more-info/controls/more-info-fan.js | 6 +- src/panels/lovelace/cards/hui-tile-card.ts | 68 ++++++++++++++----- 3 files changed, 80 insertions(+), 22 deletions(-) diff --git a/src/data/fan.ts b/src/data/fan.ts index 7fe1e8af52..67a4e376b3 100644 --- a/src/data/fan.ts +++ b/src/data/fan.ts @@ -1,4 +1,24 @@ -export const SUPPORT_SET_SPEED = 1; -export const SUPPORT_OSCILLATE = 2; -export const SUPPORT_DIRECTION = 4; -export const SUPPORT_PRESET_MODE = 8; +import { + HassEntityAttributeBase, + HassEntityBase, +} from "home-assistant-js-websocket"; + +export const enum FanEntityFeature { + SET_SPEED = 1, + OSCILLATE = 2, + DIRECTION = 4, + PRESET_MODE = 8, +} + +interface FanEntityAttributes extends HassEntityAttributeBase { + direction?: number; + oscillating?: boolean; + percentage?: number; + percentage_step?: number; + preset_mode?: string; + preset_modes?: string[]; +} + +export interface FanEntity extends HassEntityBase { + attributes: FanEntityAttributes; +} diff --git a/src/dialogs/more-info/controls/more-info-fan.js b/src/dialogs/more-info/controls/more-info-fan.js index 3da9229e1c..2ec3925e49 100644 --- a/src/dialogs/more-info/controls/more-info-fan.js +++ b/src/dialogs/more-info/controls/more-info-fan.js @@ -11,7 +11,7 @@ import "../../../components/ha-icon-button"; import "../../../components/ha-labeled-slider"; import "../../../components/ha-select"; import "../../../components/ha-switch"; -import { SUPPORT_SET_SPEED } from "../../../data/fan"; +import { FanEntityFeature } from "../../../data/fan"; import { EventsMixin } from "../../../mixins/events-mixin"; import LocalizeMixin from "../../../mixins/localize-mixin"; @@ -161,7 +161,9 @@ class MoreInfoFan extends LocalizeMixin(EventsMixin(PolymerElement)) { computeClassNames(stateObj) { return ( "more-info-fan " + - (supportsFeature(stateObj, SUPPORT_SET_SPEED) ? "has-percentage " : "") + + (supportsFeature(stateObj, FanEntityFeature.SET_SPEED) + ? "has-percentage " + : "") + (stateObj.attributes.preset_modes && stateObj.attributes.preset_modes.length ? "has-preset_modes " diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index 4274ee4d5b..ce8f41e531 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -18,7 +18,10 @@ import "../../../components/tile/ha-tile-icon"; import "../../../components/tile/ha-tile-image"; import "../../../components/tile/ha-tile-info"; import { cameraUrlWithWidthHeight } from "../../../data/camera"; -import { UNAVAILABLE_STATES } from "../../../data/entity"; +import { CoverEntity } from "../../../data/cover"; +import { ON, UNAVAILABLE_STATES } from "../../../data/entity"; +import { FanEntity } from "../../../data/fan"; +import { LightEntity } from "../../../data/light"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor"; import { HomeAssistant } from "../../../types"; @@ -152,6 +155,52 @@ export class HuiTileCard extends LitElement implements LovelaceCard { return stateColor; }); + private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string { + const domain = computeDomain(stateObj.entity_id); + + if ( + (stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP || + TIMESTAMP_STATE_DOMAINS.includes(domain)) && + !UNAVAILABLE_STATES.includes(stateObj.state) + ) { + return html` + + `; + } + + if (domain === "light" && stateObj.state === ON) { + const brightness = (stateObj as LightEntity).attributes.brightness; + if (brightness) { + return `${Math.round((brightness * 100) / 255)}%`; + } + } + + if (domain === "cover" && stateObj.state === "open") { + const position = (stateObj as CoverEntity).attributes.current_position; + if (position) { + return `${Math.round(position)}%`; + } + } + + if (domain === "fan" && stateObj.state === ON) { + const speed = (stateObj as FanEntity).attributes.percentage; + if (speed) { + return `${Math.round(speed)}%`; + } + } + + return computeStateDisplay( + this.hass!.localize, + stateObj, + this.hass!.locale + ); + } + protected render(): TemplateResult { if (!this._config || !this.hass) { return html``; @@ -175,25 +224,12 @@ export class HuiTileCard extends LitElement implements LovelaceCard { `; } - const domain = computeDomain(stateObj.entity_id); - const icon = this._config.icon || stateObj.attributes.icon; const iconPath = stateIconPath(stateObj); const name = this._config.name || stateObj.attributes.friendly_name; - const stateDisplay = - (stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP || - TIMESTAMP_STATE_DOMAINS.includes(domain)) && - !UNAVAILABLE_STATES.includes(stateObj.state) - ? html` - - ` - : computeStateDisplay(this.hass!.localize, stateObj, this.hass.locale); + + const stateDisplay = this._computeStateDisplay(stateObj); const color = this._computeStateColor(stateObj, this._config.color);