From 6c7efc17c2b7dd3306b3577f615b267fd274f2ba Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 31 Aug 2023 22:37:25 +0200 Subject: [PATCH 01/16] Fix more info type test (#17758) --- test/common/entity/state_more_info_type_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/common/entity/state_more_info_type_test.ts b/test/common/entity/state_more_info_type_test.ts index c89661d88c..eb2cd4508b 100644 --- a/test/common/entity/state_more_info_type_test.ts +++ b/test/common/entity/state_more_info_type_test.ts @@ -18,9 +18,9 @@ describe("stateMoreInfoType", () => { assert.strictEqual(stateMoreInfoType(stateObj), "hidden"); }); - it("Returns default for switch states", () => { + it("Returns default for tts states", () => { const stateObj: any = { - entity_id: "switch.bla", + entity_id: "tts.bla", attributes: {}, }; assert.strictEqual(stateMoreInfoType(stateObj), "default"); From 16ed60902de7f677680f3b1dd7ddf0e9b9ea133d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 19:35:19 -0400 Subject: [PATCH 02/16] Update dependency @types/sortablejs to v1.15.2 (#17761) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 38d22cf82d..2703f43958 100644 --- a/package.json +++ b/package.json @@ -181,7 +181,7 @@ "@types/mocha": "10.0.1", "@types/qrcode": "1.5.1", "@types/serve-handler": "6.1.1", - "@types/sortablejs": "1.15.1", + "@types/sortablejs": "1.15.2", "@types/tar": "6.1.5", "@types/ua-parser-js": "0.7.36", "@types/webspeechapi": "0.0.29", diff --git a/yarn.lock b/yarn.lock index 7d662c6dbf..e22aa013f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4554,10 +4554,10 @@ __metadata: languageName: node linkType: hard -"@types/sortablejs@npm:1.15.1": - version: 1.15.1 - resolution: "@types/sortablejs@npm:1.15.1" - checksum: 242c0350f63b86541d667d5aa5d1695a9b98644a1c1f52b537f7733baf187dd2618fadde4deab01e655ebf06294cebf0a889ebebf9202ef0a8750a7afed3ecfd +"@types/sortablejs@npm:1.15.2": + version: 1.15.2 + resolution: "@types/sortablejs@npm:1.15.2" + checksum: 7e2be1a44efb0df012152f6bd1424dd40a490f90a856b6cf29ffed5fb184cb3fbf61302d0cb0a04f64fe9929ced72eb1c9a1e9b2164e269592130e9f983f54be languageName: node linkType: hard @@ -9677,7 +9677,7 @@ __metadata: "@types/mocha": 10.0.1 "@types/qrcode": 1.5.1 "@types/serve-handler": 6.1.1 - "@types/sortablejs": 1.15.1 + "@types/sortablejs": 1.15.2 "@types/tar": 6.1.5 "@types/ua-parser-js": 0.7.36 "@types/webspeechapi": 0.0.29 From e98e59a265bf1b8dd6ba1ee70e69b2e9634efdc2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 31 Aug 2023 19:40:36 -0400 Subject: [PATCH 03/16] Update typescript-eslint monorepo to v6.5.0 (#17762) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 2703f43958..d710f68019 100644 --- a/package.json +++ b/package.json @@ -185,8 +185,8 @@ "@types/tar": "6.1.5", "@types/ua-parser-js": "0.7.36", "@types/webspeechapi": "0.0.29", - "@typescript-eslint/eslint-plugin": "6.4.1", - "@typescript-eslint/parser": "6.4.1", + "@typescript-eslint/eslint-plugin": "6.5.0", + "@typescript-eslint/parser": "6.5.0", "@web/dev-server": "0.1.38", "@web/dev-server-rollup": "0.4.1", "babel-loader": "9.1.3", diff --git a/yarn.lock b/yarn.lock index e22aa013f0..da26282684 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4610,15 +4610,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.4.1": - version: 6.4.1 - resolution: "@typescript-eslint/eslint-plugin@npm:6.4.1" +"@typescript-eslint/eslint-plugin@npm:6.5.0": + version: 6.5.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.5.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.4.1 - "@typescript-eslint/type-utils": 6.4.1 - "@typescript-eslint/utils": 6.4.1 - "@typescript-eslint/visitor-keys": 6.4.1 + "@typescript-eslint/scope-manager": 6.5.0 + "@typescript-eslint/type-utils": 6.5.0 + "@typescript-eslint/utils": 6.5.0 + "@typescript-eslint/visitor-keys": 6.5.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -4631,44 +4631,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: aa5f2f516a4ea07d1a9878d347dcb915808862f41efd3c4acd4955e616d265e051c4c93d597d30e54bee10bab9b965e2ef9cea1b497bf16f23a475d7911a8078 + checksum: d81525c9a081186ec1ae7d957972065d50bae8fe4b3de111e573adc7267bb830baaec8f1ae47d3b937984ac34324bacc3951868b7986d4f9974bbe480f2261c0 languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.4.1": - version: 6.4.1 - resolution: "@typescript-eslint/parser@npm:6.4.1" +"@typescript-eslint/parser@npm:6.5.0": + version: 6.5.0 + resolution: "@typescript-eslint/parser@npm:6.5.0" dependencies: - "@typescript-eslint/scope-manager": 6.4.1 - "@typescript-eslint/types": 6.4.1 - "@typescript-eslint/typescript-estree": 6.4.1 - "@typescript-eslint/visitor-keys": 6.4.1 + "@typescript-eslint/scope-manager": 6.5.0 + "@typescript-eslint/types": 6.5.0 + "@typescript-eslint/typescript-estree": 6.5.0 + "@typescript-eslint/visitor-keys": 6.5.0 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: cb61c757963f2a7964c2f846087eadda044720da769d96600f9f0069fe796d612caef5d9bb0c785aa4fa95028b2d231e7c83847ce44f02b1fa41f2102d6f444c + checksum: e9a70886ec2660aee5c77cdff67ba11651eb855b7ecd3ad1e70837fce997d6e6db9dfe1e1eab46a9b2147cbc034ae9c109951f3bc24ce54e78cae669b6bc9c95 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.4.1": - version: 6.4.1 - resolution: "@typescript-eslint/scope-manager@npm:6.4.1" +"@typescript-eslint/scope-manager@npm:6.5.0": + version: 6.5.0 + resolution: "@typescript-eslint/scope-manager@npm:6.5.0" dependencies: - "@typescript-eslint/types": 6.4.1 - "@typescript-eslint/visitor-keys": 6.4.1 - checksum: 8f7f90aa378a19838301b31cfa58a4b0641d2b84891705c8c006c67aacb5c0d07112b714e1f0e7a159c5736779c934ec26dadef42a0711fccb635596aba391fc + "@typescript-eslint/types": 6.5.0 + "@typescript-eslint/visitor-keys": 6.5.0 + checksum: 30d78143f68e07d6bd15a147f64cc16830f8a8c8409b37aa7c7d205d7585f3648ec1c5365b3f177b7561971b407f773f6dba83b3b78fa63091045f2d6bbc6b9f languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.4.1": - version: 6.4.1 - resolution: "@typescript-eslint/type-utils@npm:6.4.1" +"@typescript-eslint/type-utils@npm:6.5.0": + version: 6.5.0 + resolution: "@typescript-eslint/type-utils@npm:6.5.0" dependencies: - "@typescript-eslint/typescript-estree": 6.4.1 - "@typescript-eslint/utils": 6.4.1 + "@typescript-eslint/typescript-estree": 6.5.0 + "@typescript-eslint/utils": 6.5.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -4676,23 +4676,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 33bcdd48bd4e07258ed1919b598d50354dd67d8f01702cd2fd46aa9250b7b7cba9caab640df01f4dc0e45dabeddbb3ca47bee88f81fe2087350ed6f70a4cbe5d + checksum: 80b9e5099f5bdb05348ea8664c0a5084efc851de43ef6c1997041e1f07e9cc34ac874cc9e8afb317c887513d657e2583ad360e3d57feaab775bde0acc1807982 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.4.1": - version: 6.4.1 - resolution: "@typescript-eslint/types@npm:6.4.1" - checksum: 16ba46140dbe426407bbb940e87fb347e7eb53b64f74e8f6a819cd662aa25ccd0c25b1e588867ce3cd36a8b4eccea7bd81f4d429595e6e86d9a24c655b1c8617 +"@typescript-eslint/types@npm:6.5.0": + version: 6.5.0 + resolution: "@typescript-eslint/types@npm:6.5.0" + checksum: 950ec16991d71494d10cb752535bbc4395295e3f03a716d53ec55bbb0aaff487aa774cc5002f775ffcc80b9f0e16ac53ecebf7cac1444ca4f7a847b0859ffbfb languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.4.1": - version: 6.4.1 - resolution: "@typescript-eslint/typescript-estree@npm:6.4.1" +"@typescript-eslint/typescript-estree@npm:6.5.0": + version: 6.5.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.5.0" dependencies: - "@typescript-eslint/types": 6.4.1 - "@typescript-eslint/visitor-keys": 6.4.1 + "@typescript-eslint/types": 6.5.0 + "@typescript-eslint/visitor-keys": 6.5.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -4701,34 +4701,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 34c289e50a6337321154efe6c20c762e94fea308f9032971e356a266f63e99b908b1a00dd8cf51eba50a6f69db01d665faf2cf13454b355767fd167eebe60f1c + checksum: 05717fa1f2609fa5669803191cf309a379c815aaf4fff6850f40560eec8749759c36b288f05cecffd5c1d0be8de1fe414ecfee6ecf99b6ae521baa48c8b58455 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.4.1": - version: 6.4.1 - resolution: "@typescript-eslint/utils@npm:6.4.1" +"@typescript-eslint/utils@npm:6.5.0": + version: 6.5.0 + resolution: "@typescript-eslint/utils@npm:6.5.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.4.1 - "@typescript-eslint/types": 6.4.1 - "@typescript-eslint/typescript-estree": 6.4.1 + "@typescript-eslint/scope-manager": 6.5.0 + "@typescript-eslint/types": 6.5.0 + "@typescript-eslint/typescript-estree": 6.5.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 54e642a345790f912393a6f2821495e2359eff0f874a94cbe6fb3ef4411702983ed54fe88ca3ea9d28f2e93800a74dee22b7888838154bc1afd57c7e119e17ec + checksum: 58a82213c8a7bac97a6538b9845c1de5c5692fbf72548f95ed5e044a222608590bcafbb9eacba92a8c4e9eb3e5d0a2fd553eae0d6694ed2d6152aed4dabf9480 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.4.1": - version: 6.4.1 - resolution: "@typescript-eslint/visitor-keys@npm:6.4.1" +"@typescript-eslint/visitor-keys@npm:6.5.0": + version: 6.5.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.5.0" dependencies: - "@typescript-eslint/types": 6.4.1 + "@typescript-eslint/types": 6.5.0 eslint-visitor-keys: ^3.4.1 - checksum: bd9cd56fc793e1d880c24193f939c4992b2653f330baece41cd461d1fb48edb2c53696987cba0e29074bbb452dd181fd009db92dd19060fdcc417ad76768f18a + checksum: 768a02dd0d8aae45708646bb0c51e67da09e71dc101bb0a0e55d7e0c8eadfea2f531acd3035d1ec34bf2380b66188f3fc47c6bef0201eae36b2dcc48d1934442 languageName: node linkType: hard @@ -9681,8 +9681,8 @@ __metadata: "@types/tar": 6.1.5 "@types/ua-parser-js": 0.7.36 "@types/webspeechapi": 0.0.29 - "@typescript-eslint/eslint-plugin": 6.4.1 - "@typescript-eslint/parser": 6.4.1 + "@typescript-eslint/eslint-plugin": 6.5.0 + "@typescript-eslint/parser": 6.5.0 "@vaadin/combo-box": 24.1.6 "@vaadin/vaadin-themable-mixin": 24.1.6 "@vibrant/color": 3.2.1-alpha.1 From 3917739ad2f8655c32aa7584bfa3ea67b684b39f Mon Sep 17 00:00:00 2001 From: karwosts <32912880+karwosts@users.noreply.github.com> Date: Fri, 1 Sep 2023 02:36:43 -0700 Subject: [PATCH 04/16] Fix chart tooltip crash for disabled entity (#17767) --- src/common/number/format_number.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/number/format_number.ts b/src/common/number/format_number.ts index dcbcd72d02..ddbe1765d4 100644 --- a/src/common/number/format_number.ts +++ b/src/common/number/format_number.ts @@ -108,7 +108,7 @@ export const formatNumber = ( * @returns An `Intl.NumberFormatOptions` object with `maximumFractionDigits` set to 0, or `undefined` */ export const getNumberFormatOptions = ( - entityState: HassEntity, + entityState?: HassEntity, entity?: EntityRegistryDisplayEntry ): Intl.NumberFormatOptions | undefined => { const precision = entity?.display_precision; @@ -119,8 +119,8 @@ export const getNumberFormatOptions = ( }; } if ( - Number.isInteger(Number(entityState.attributes?.step)) && - Number.isInteger(Number(entityState.state)) + Number.isInteger(Number(entityState?.attributes?.step)) && + Number.isInteger(Number(entityState?.state)) ) { return { maximumFractionDigits: 0 }; } From 6d63028406a8a39a2ee07df1677783833c94ec73 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 1 Sep 2023 15:18:47 +0200 Subject: [PATCH 05/16] Move tile card features logic into its own file (#17775) --- src/panels/lovelace/cards/hui-tile-card.ts | 51 ++---------- .../tile-features/hui-tile-features.ts | 82 +++++++++++++++++++ 2 files changed, 90 insertions(+), 43 deletions(-) create mode 100644 src/panels/lovelace/tile-features/hui-tile-features.ts diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index c21b8bf172..a0f7e8bcf9 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -49,14 +49,8 @@ import { actionHandler } from "../common/directives/action-handler-directive"; import { findEntities } from "../common/find-entities"; import { handleAction } from "../common/handle-action"; import "../components/hui-timestamp-display"; -import { createTileFeatureElement } from "../create-element/create-tile-feature-element"; -import type { LovelaceTileFeatureConfig } from "../tile-features/types"; -import type { - LovelaceCard, - LovelaceCardEditor, - LovelaceTileFeature, -} from "../types"; -import type { HuiErrorCard } from "./hui-error-card"; +import "../tile-features/hui-tile-features"; +import type { LovelaceCard, LovelaceCardEditor } from "../types"; import { computeTileBadge } from "./tile/badges/tile-badge"; import type { ThermostatCardConfig, TileCardConfig } from "./types"; @@ -391,45 +385,16 @@ export class HuiTileCard extends LitElement implements LovelaceCard { > -
- ${this._config.features?.map((featureConf) => - this.renderFeature(featureConf, stateObj) - )} -
+ `; } - private _featuresElements = new WeakMap< - LovelaceTileFeatureConfig, - LovelaceTileFeature | HuiErrorCard - >(); - - private _getFeatureElement(feature: LovelaceTileFeatureConfig) { - if (!this._featuresElements.has(feature)) { - const element = createTileFeatureElement(feature); - this._featuresElements.set(feature, element); - return element; - } - - return this._featuresElements.get(feature)!; - } - - private renderFeature( - featureConf: LovelaceTileFeatureConfig, - stateObj: HassEntity - ): TemplateResult { - const element = this._getFeatureElement(featureConf); - - if (this.hass) { - element.hass = this.hass; - (element as LovelaceTileFeature).stateObj = stateObj; - (element as LovelaceTileFeature).color = this._config!.color; - } - - return html`${element}`; - } - static get styles(): CSSResultGroup { return css` :host { diff --git a/src/panels/lovelace/tile-features/hui-tile-features.ts b/src/panels/lovelace/tile-features/hui-tile-features.ts new file mode 100644 index 0000000000..fea6b29d14 --- /dev/null +++ b/src/panels/lovelace/tile-features/hui-tile-features.ts @@ -0,0 +1,82 @@ +import type { HassEntity } from "home-assistant-js-websocket"; +import { + CSSResultGroup, + LitElement, + TemplateResult, + css, + html, + nothing, +} from "lit"; +import { customElement, property } from "lit/decorators"; +import { HomeAssistant } from "../../../types"; +import type { HuiErrorCard } from "../cards/hui-error-card"; +import { createTileFeatureElement } from "../create-element/create-tile-feature-element"; +import type { LovelaceTileFeature } from "../types"; +import type { LovelaceTileFeatureConfig } from "./types"; + +@customElement("hui-tile-features") +export class HuiTileFeatures extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public stateObj!: HassEntity; + + @property({ attribute: false }) public features?: LovelaceTileFeatureConfig[]; + + @property({ attribute: false }) public color?: string; + + private _featuresElements = new WeakMap< + LovelaceTileFeatureConfig, + LovelaceTileFeature | HuiErrorCard + >(); + + private _getFeatureElement(feature: LovelaceTileFeatureConfig) { + if (!this._featuresElements.has(feature)) { + const element = createTileFeatureElement(feature); + this._featuresElements.set(feature, element); + return element; + } + + return this._featuresElements.get(feature)!; + } + + private renderFeature( + featureConf: LovelaceTileFeatureConfig, + stateObj: HassEntity + ): TemplateResult { + const element = this._getFeatureElement(featureConf); + + if (this.hass) { + element.hass = this.hass; + (element as LovelaceTileFeature).stateObj = stateObj; + (element as LovelaceTileFeature).color = this.color; + } + + return html`${element}`; + } + + protected render() { + if (!this.features) { + return nothing; + } + return html` + ${this.features.map((featureConf) => + this.renderFeature(featureConf, this.stateObj) + )} + `; + } + + static get styles(): CSSResultGroup { + return css` + :host { + display: flex; + flex-direction: column; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-tile-features": HuiTileFeatures; + } +} From c291af5d97c885a5af75b612b460ff33f44f7dd7 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 1 Sep 2023 15:19:28 +0200 Subject: [PATCH 06/16] Improve disabled state for select and number button control (#17773) --- src/components/ha-control-number-buttons.ts | 8 +++++--- src/components/ha-control-select.ts | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/components/ha-control-number-buttons.ts b/src/components/ha-control-number-buttons.ts index 95c16f5fa2..324444256e 100644 --- a/src/components/ha-control-number-buttons.ts +++ b/src/components/ha-control-number-buttons.ts @@ -81,6 +81,7 @@ export class HaControlNumberButton extends LitElement { } _handleKeyDown(e: KeyboardEvent) { + if (this.disabled) return; if (!A11Y_KEY_CODES.has(e.code)) return; e.preventDefault(); switch (e.code) { @@ -116,7 +117,7 @@ export class HaControlNumberButton extends LitElement { const displayedValue = this.value != null ? formatNumber(this.value, this.locale, this.formatOptions) - : "-"; + : ""; return html`
@@ -124,12 +125,12 @@ export class HaControlNumberButton extends LitElement { id="input" class="value" role="number-button" - tabindex="0" + .tabIndex=${this.disabled ? "-1" : "0"} aria-valuenow=${this.value} aria-valuemin=${this.min} aria-valuemax=${this.max} aria-label=${ifDefined(this.label)} - .disabled=${this.disabled} + ?disabled=${this.disabled} @keydown=${this._handleKeyDown} > ${displayedValue} @@ -240,6 +241,7 @@ export class HaControlNumberButton extends LitElement { .button[disabled] { opacity: 0.4; pointer-events: none; + cursor: not-allowed; } .button.minus { left: 0; diff --git a/src/components/ha-control-select.ts b/src/components/ha-control-select.ts index 855fc338a1..04ff1f9f2c 100644 --- a/src/components/ha-control-select.ts +++ b/src/components/ha-control-select.ts @@ -217,6 +217,7 @@ export class HaControlSelect extends LitElement { transition: box-shadow 180ms ease-in-out; font-style: normal; font-weight: 500; + color: var(--primary-text-color); user-select: none; -webkit-tap-highlight-color: transparent; } @@ -267,7 +268,6 @@ export class HaControlSelect extends LitElement { justify-content: center; border-radius: var(--control-select-button-border-radius); overflow: hidden; - color: var(--primary-text-color); /* For safari border-radius overflow */ z-index: 0; } @@ -331,6 +331,7 @@ export class HaControlSelect extends LitElement { :host([disabled]) { --control-select-color: var(--disabled-color); --control-select-focused-opacity: 0; + color: var(--disabled-color); } :host([disabled]) .option { cursor: not-allowed; From fb69deb6176e76e726f11e19a8717868880375fc Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 1 Sep 2023 15:24:36 +0200 Subject: [PATCH 07/16] Fix target range temperature in tile feature (#17772) --- .../hui-target-temperature-tile-feature.ts | 193 +++++++++++------- 1 file changed, 115 insertions(+), 78 deletions(-) diff --git a/src/panels/lovelace/tile-features/hui-target-temperature-tile-feature.ts b/src/panels/lovelace/tile-features/hui-target-temperature-tile-feature.ts index 34fbf1ac83..3832dbb91a 100644 --- a/src/panels/lovelace/tile-features/hui-target-temperature-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-target-temperature-tile-feature.ts @@ -129,6 +129,33 @@ class HuiTargetTemperatureTileFeature }); } + private _supportsTarget() { + const domain = computeStateDomain(this.stateObj!); + return ( + (domain === "climate" && + supportsFeature( + this.stateObj!, + ClimateEntityFeature.TARGET_TEMPERATURE + )) || + (domain === "water_heater" && + supportsFeature( + this.stateObj!, + WaterHeaterEntityFeature.TARGET_TEMPERATURE + )) + ); + } + + private _supportsTargetRange() { + const domain = computeStateDomain(this.stateObj!); + return ( + domain === "climate" && + supportsFeature( + this.stateObj!, + ClimateEntityFeature.TARGET_TEMPERATURE_RANGE + ) + ); + } + protected render() { if ( !this._config || @@ -147,94 +174,104 @@ class HuiTargetTemperatureTileFeature minimumFractionDigits: digits, }; - const domain = computeStateDomain(this.stateObj!); - if ( - (domain === "climate" && - supportsFeature( - this.stateObj, - ClimateEntityFeature.TARGET_TEMPERATURE - )) || - (domain === "water_heater" && - supportsFeature( - this.stateObj, - WaterHeaterEntityFeature.TARGET_TEMPERATURE - )) + this._supportsTarget() && + this._targetTemperature.value != null && + this.stateObj.state !== UNAVAILABLE ) { return html` - - - - - `; + + + + + `; } if ( - domain === "climate" && - supportsFeature( - this.stateObj, - ClimateEntityFeature.TARGET_TEMPERATURE_RANGE - ) + this._supportsTargetRange() && + this._targetTemperature.low != null && + this._targetTemperature.high != null && + this.stateObj.state !== UNAVAILABLE ) { return html` - - - - - - - `; + + + + + + + `; } - return nothing; + return html` + + + + + `; } static get styles() { From 0d0fe75f4eb444587962dd9e13fa7ea5ccc94361 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 1 Sep 2023 15:25:27 +0200 Subject: [PATCH 08/16] Use slider for color temp instead of wheel (#17771) --- .../components/ha-temp-color-picker.markdown | 3 - .../pages/components/ha-temp-color-picker.ts | 117 ----- src/components/ha-hs-color-picker.ts | 6 + src/components/ha-temp-color-picker.ts | 440 ------------------ .../lights/light-color-rgb-picker.ts | 1 - .../lights/light-color-temp-picker.ts | 80 +++- .../hui-light-color-temp-tile-feature.ts | 27 +- 7 files changed, 76 insertions(+), 598 deletions(-) delete mode 100644 gallery/src/pages/components/ha-temp-color-picker.markdown delete mode 100644 gallery/src/pages/components/ha-temp-color-picker.ts delete mode 100644 src/components/ha-temp-color-picker.ts diff --git a/gallery/src/pages/components/ha-temp-color-picker.markdown b/gallery/src/pages/components/ha-temp-color-picker.markdown deleted file mode 100644 index 3221e55ee8..0000000000 --- a/gallery/src/pages/components/ha-temp-color-picker.markdown +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: Temp Color Picker ---- diff --git a/gallery/src/pages/components/ha-temp-color-picker.ts b/gallery/src/pages/components/ha-temp-color-picker.ts deleted file mode 100644 index d924e745bf..0000000000 --- a/gallery/src/pages/components/ha-temp-color-picker.ts +++ /dev/null @@ -1,117 +0,0 @@ -import "../../../../src/components/ha-temp-color-picker"; - -import { css, html, LitElement, TemplateResult } from "lit"; -import { customElement, state } from "lit/decorators"; - -import "../../../../src/components/ha-card"; -import "../../../../src/components/ha-slider"; - -@customElement("demo-components-ha-temp-color-picker") -export class DemoHaTempColorPicker extends LitElement { - @state() - min = 3000; - - @state() - max = 7000; - - @state() - value = 4000; - - @state() - liveValue?: number; - - private _minChanged(ev) { - this.min = Number(ev.target.value); - } - - private _maxChanged(ev) { - this.max = Number(ev.target.value); - } - - private _valueChanged(ev) { - this.value = Number(ev.target.value); - } - - private _tempColorCursor(ev) { - this.liveValue = ev.detail.value; - } - - private _tempColorChanged(ev) { - this.value = ev.detail.value; - } - - protected render(): TemplateResult { - return html` - -
-

${this.liveValue ?? this.value} K

- -

Min temp : ${this.min} K

- - -

Max temp : ${this.max} K

- - -

Value : ${this.value} K

- - -
-
- `; - } - - static get styles() { - return css` - ha-card { - max-width: 600px; - margin: 24px auto; - } - .card-content { - display: flex; - align-items: center; - flex-direction: column; - } - ha-temp-color-picker { - width: 400px; - } - .value { - font-size: 22px; - font-weight: bold; - margin: 0 0 12px 0; - } - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - "demo-components-ha-temp-color-picker": DemoHaTempColorPicker; - } -} diff --git a/src/components/ha-hs-color-picker.ts b/src/components/ha-hs-color-picker.ts index cef11cfc38..f492be2d7c 100644 --- a/src/components/ha-hs-color-picker.ts +++ b/src/components/ha-hs-color-picker.ts @@ -7,6 +7,12 @@ import { hsv2rgb, rgb2hex } from "../common/color/convert-color"; import { rgbw2rgb, rgbww2rgb } from "../common/color/convert-light-color"; import { fireEvent } from "../common/dom/fire_event"; +declare global { + interface HASSDomEvents { + "cursor-moved": { value?: any }; + } +} + function xy2polar(x: number, y: number) { const r = Math.sqrt(x * x + y * y); const phi = Math.atan2(y, x); diff --git a/src/components/ha-temp-color-picker.ts b/src/components/ha-temp-color-picker.ts deleted file mode 100644 index ce471c207f..0000000000 --- a/src/components/ha-temp-color-picker.ts +++ /dev/null @@ -1,440 +0,0 @@ -import { DIRECTION_ALL, Manager, Pan, Tap } from "@egjs/hammerjs"; -import { LitElement, PropertyValues, css, html, svg } from "lit"; -import { customElement, property, query, state } from "lit/decorators"; -import { classMap } from "lit/directives/class-map"; -import { styleMap } from "lit/directives/style-map"; -import { rgb2hex } from "../common/color/convert-color"; -import { - DEFAULT_MAX_KELVIN, - DEFAULT_MIN_KELVIN, - temperature2rgb, -} from "../common/color/convert-light-color"; -import { fireEvent } from "../common/dom/fire_event"; - -const SAFE_ZONE_FACTOR = 0.9; - -declare global { - interface HASSDomEvents { - "cursor-moved": { value?: any }; - } -} - -const A11Y_KEY_CODES = new Set([ - "ArrowRight", - "ArrowUp", - "ArrowLeft", - "ArrowDown", - "PageUp", - "PageDown", - "Home", - "End", -]); - -function xy2polar(x: number, y: number) { - const r = Math.sqrt(x * x + y * y); - const phi = Math.atan2(y, x); - return [r, phi]; -} - -function polar2xy(r: number, phi: number) { - const x = Math.cos(phi) * r; - const y = Math.sin(phi) * r; - return [x, y]; -} - -function drawColorWheel( - ctx: CanvasRenderingContext2D, - minTemp: number, - maxTemp: number -) { - ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); - const radius = ctx.canvas.width / 2; - - const min = Math.max(minTemp, 2000); - const max = Math.min(maxTemp, 40000); - - for (let y = -radius; y < radius; y += 1) { - const x = radius * Math.sqrt(1 - (y / radius) ** 2); - - const fraction = (y / (radius * SAFE_ZONE_FACTOR) + 1) / 2; - - const temperature = Math.max( - Math.min(min + fraction * (max - min), max), - min - ); - - const color = rgb2hex(temperature2rgb(temperature)); - - ctx.fillStyle = color; - ctx.fillRect(radius - x, radius + y - 0.5, 2 * x, 2); - ctx.fill(); - } -} - -@customElement("ha-temp-color-picker") -class HaTempColorPicker extends LitElement { - @property({ type: Boolean, reflect: true }) - public disabled = false; - - @property({ type: Number, attribute: false }) - public renderSize?: number; - - @property({ type: Number }) - public value?: number; - - @property({ type: Number }) - public min = DEFAULT_MIN_KELVIN; - - @property({ type: Number }) - public max = DEFAULT_MAX_KELVIN; - - @query("#canvas") private _canvas!: HTMLCanvasElement; - - private _mc?: HammerManager; - - @state() - private _pressed?: string; - - @state() - private _cursorPosition?: [number, number]; - - @state() - private _localValue?: number; - - protected firstUpdated(changedProps: PropertyValues): void { - super.firstUpdated(changedProps); - this._setupListeners(); - this._generateColorWheel(); - this.setAttribute("role", "slider"); - this.setAttribute("aria-orientation", "vertical"); - if (!this.hasAttribute("tabindex")) { - this.setAttribute("tabindex", "0"); - } - } - - private _generateColorWheel() { - const ctx = this._canvas.getContext("2d")!; - drawColorWheel(ctx, this.min, this.max); - } - - connectedCallback(): void { - super.connectedCallback(); - this._setupListeners(); - } - - disconnectedCallback(): void { - super.disconnectedCallback(); - this._destroyListeners(); - } - - protected updated(changedProps: PropertyValues): void { - super.updated(changedProps); - if (changedProps.has("_localValue")) { - this.setAttribute("aria-valuenow", this._localValue?.toString() ?? ""); - } - if (changedProps.has("min") || changedProps.has("max")) { - this._generateColorWheel(); - this._resetPosition(); - } - if (changedProps.has("min")) { - this.setAttribute("aria-valuemin", this.min.toString()); - } - if (changedProps.has("max")) { - this.setAttribute("aria-valuemax", this.max.toString()); - } - if (changedProps.has("value")) { - if (this._localValue !== this.value) { - this._resetPosition(); - } - } - } - - private _setupListeners() { - if (this._canvas && !this._mc) { - this._mc = new Manager(this._canvas); - this._mc.add( - new Pan({ - direction: DIRECTION_ALL, - enable: true, - threshold: 0, - }) - ); - - this._mc.add(new Tap({ event: "singletap" })); - - let savedPosition; - this._mc.on("panstart", (e) => { - if (this.disabled) return; - this._pressed = e.pointerType; - savedPosition = this._cursorPosition; - }); - this._mc.on("pancancel", () => { - if (this.disabled) return; - this._pressed = undefined; - this._cursorPosition = savedPosition; - }); - this._mc.on("panmove", (e) => { - if (this.disabled) return; - this._cursorPosition = this._getPositionFromEvent(e); - this._localValue = this._getValueFromCoord(...this._cursorPosition); - fireEvent(this, "cursor-moved", { value: this._localValue }); - }); - this._mc.on("panend", (e) => { - if (this.disabled) return; - this._pressed = undefined; - this._cursorPosition = this._getPositionFromEvent(e); - this._localValue = this._getValueFromCoord(...this._cursorPosition); - fireEvent(this, "cursor-moved", { value: undefined }); - fireEvent(this, "value-changed", { value: this._localValue }); - }); - - this._mc.on("singletap", (e) => { - if (this.disabled) return; - this._cursorPosition = this._getPositionFromEvent(e); - this._localValue = this._getValueFromCoord(...this._cursorPosition); - fireEvent(this, "value-changed", { value: this._localValue }); - }); - - this.addEventListener("keydown", this._handleKeyDown); - this.addEventListener("keyup", this._handleKeyUp); - } - } - - private _resetPosition() { - if (this.value === undefined) { - this._cursorPosition = undefined; - this._localValue = undefined; - return; - } - const [, y] = this._getCoordsFromValue(this.value); - const currentX = this._cursorPosition?.[0] ?? 0; - const x = - Math.sign(currentX) * Math.min(Math.sqrt(1 - y ** 2), Math.abs(currentX)); - this._cursorPosition = [x, y]; - this._localValue = this.value; - } - - private _getCoordsFromValue = (temperature: number): [number, number] => { - if (this.value === this.min) { - return [0, -1]; - } - if (this.value === this.max) { - return [0, 1]; - } - const fraction = (temperature - this.min) / (this.max - this.min); - const y = (2 * fraction - 1) * SAFE_ZONE_FACTOR; - return [0, y]; - }; - - private _getValueFromCoord = (_x: number, y: number): number => { - const fraction = (y / SAFE_ZONE_FACTOR + 1) / 2; - const temperature = Math.max( - Math.min(this.min + fraction * (this.max - this.min), this.max), - this.min - ); - return Math.round(temperature); - }; - - private _getPositionFromEvent = (e: HammerInput): [number, number] => { - const x = e.center.x; - const y = e.center.y; - const boundingRect = e.target.getBoundingClientRect(); - const offsetX = boundingRect.left; - const offsetY = boundingRect.top; - const maxX = e.target.clientWidth; - const maxY = e.target.clientHeight; - - const _x = (2 * (x - offsetX)) / maxX - 1; - const _y = (2 * (y - offsetY)) / maxY - 1; - - const [r, phi] = xy2polar(_x, _y); - const [__x, __y] = polar2xy(Math.min(1, r), phi); - return [__x, __y]; - }; - - private _destroyListeners() { - if (this._mc) { - this._mc.destroy(); - this._mc = undefined; - } - this.removeEventListener("keydown", this._handleKeyDown); - this.removeEventListener("keyup", this._handleKeyDown); - } - - _handleKeyDown(e: KeyboardEvent) { - if (!A11Y_KEY_CODES.has(e.code)) return; - e.preventDefault(); - - const step = 1; - const tenPercentStep = Math.max(step, (this.max - this.min) / 10); - const currentValue = - this._localValue ?? Math.round((this.max + this.min) / 2); - switch (e.code) { - case "ArrowRight": - case "ArrowUp": - this._localValue = Math.round(Math.min(currentValue + step, this.max)); - break; - case "ArrowLeft": - case "ArrowDown": - this._localValue = Math.round(Math.max(currentValue - step, this.min)); - break; - case "PageUp": - this._localValue = Math.round( - Math.min(currentValue + tenPercentStep, this.max) - ); - break; - case "PageDown": - this._localValue = Math.round( - Math.max(currentValue - tenPercentStep, this.min) - ); - break; - case "Home": - this._localValue = this.min; - break; - case "End": - this._localValue = this.max; - break; - } - if (this._localValue != null) { - const [_, y] = this._getCoordsFromValue(this._localValue); - const currentX = this._cursorPosition?.[0] ?? 0; - const x = - Math.sign(currentX) * - Math.min(Math.sqrt(1 - y ** 2), Math.abs(currentX)); - this._cursorPosition = [x, y]; - fireEvent(this, "cursor-moved", { value: this._localValue }); - } - } - - _handleKeyUp(e: KeyboardEvent) { - if (!A11Y_KEY_CODES.has(e.code)) return; - e.preventDefault(); - this.value = this._localValue; - fireEvent(this, "value-changed", { value: this._localValue }); - } - - render() { - const size = this.renderSize || 400; - const canvasSize = size * window.devicePixelRatio; - - const rgb = temperature2rgb( - this._localValue ?? Math.round((this.max + this.min) / 2) - ); - - const [x, y] = this._cursorPosition ?? [0, 0]; - - const cx = ((x + 1) * size) / 2; - const cy = ((y + 1) * size) / 2; - - const markerPosition = `${cx}px, ${cy}px`; - const markerScale = this._pressed - ? this._pressed === "touch" - ? "2.5" - : "1.5" - : "1"; - const markerOffset = - this._pressed === "touch" ? `0px, -${size / 16}px` : "0px, 0px"; - - return html` -
- - -
- `; - } - - renderSVGFilter() { - return svg` - - - - - `; - } - - static get styles() { - return css` - :host { - display: block; - outline: none; - } - .container { - position: relative; - width: 100%; - height: 100%; - display: flex; - } - canvas { - width: 100%; - height: 100%; - object-fit: contain; - border-radius: 50%; - transition: box-shadow 180ms ease-in-out; - cursor: pointer; - } - :host(:focus-visible) canvas { - box-shadow: 0 0 0 2px rgb(255, 160, 0); - } - svg { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - } - circle { - fill: black; - stroke: white; - stroke-width: 2; - filter: url(#marker-shadow); - } - .container:not(.pressed) circle { - transition: - transform 100ms ease-in-out, - fill 100ms ease-in-out; - } - .container:not(.pressed) .cursor { - transition: transform 200ms ease-in-out; - } - `; - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-temp-color-picker": HaTempColorPicker; - } -} diff --git a/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts b/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts index 90b18f4223..0a66aabcf6 100644 --- a/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts +++ b/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts @@ -26,7 +26,6 @@ import "../../../../components/ha-hs-color-picker"; import "../../../../components/ha-icon"; import "../../../../components/ha-icon-button-prev"; import "../../../../components/ha-labeled-slider"; -import "../../../../components/ha-temp-color-picker"; import { getLightCurrentModeRgbColor, LightColor, diff --git a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts index cd69b7ba7d..0331d24b31 100644 --- a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts +++ b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts @@ -1,25 +1,31 @@ import { - css, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, + css, + html, + nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { styleMap } from "lit/directives/style-map"; +import memoizeOne from "memoize-one"; +import { rgb2hex } from "../../../../common/color/convert-color"; +import { + DEFAULT_MAX_KELVIN, + DEFAULT_MIN_KELVIN, + temperature2rgb, +} from "../../../../common/color/convert-light-color"; import { fireEvent } from "../../../../common/dom/fire_event"; +import { stateColorCss } from "../../../../common/entity/state_color"; import { throttle } from "../../../../common/util/throttle"; -import "../../../../components/ha-temp-color-picker"; +import "../../../../components/ha-control-slider"; +import { UNAVAILABLE } from "../../../../data/entity"; import { LightColor, LightColorMode, LightEntity, } from "../../../../data/light"; import { HomeAssistant } from "../../../../types"; -import { - DEFAULT_MAX_KELVIN, - DEFAULT_MIN_KELVIN, -} from "../../../../common/color/convert-light-color"; declare global { interface HASSDomEvents { @@ -28,6 +34,26 @@ declare global { } } +export const generateColorTemperatureGradient = (min: number, max: number) => { + const count = 10; + + const gradient: [number, string][] = []; + + const step = (max - min) / count; + const percentageStep = 1 / count; + + for (let i = 0; i < count + 1; i++) { + const value = min + step * i; + + const hex = rgb2hex(temperature2rgb(value)); + gradient.push([percentageStep * i, hex]); + } + + return gradient + .map(([stop, color]) => `${color} ${(stop as number) * 100}%`) + .join(", "); +}; + @customElement("light-color-temp-picker") class LightColorTempPicker extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -46,18 +72,36 @@ class LightColorTempPicker extends LitElement { const maxKelvin = this.stateObj.attributes.max_color_temp_kelvin ?? DEFAULT_MAX_KELVIN; + const gradient = this._generateTemperatureGradient(minKelvin!, maxKelvin); + const color = stateColorCss(this.stateObj); + return html` - - + `; } + private _generateTemperatureGradient = memoizeOne( + (min: number, max: number) => generateColorTemperatureGradient(min, max) + ); + public _updateSliderValues() { const stateObj = this.stateObj; @@ -138,10 +182,18 @@ class LightColorTempPicker extends LitElement { flex-direction: column; } - ha-temp-color-picker { + ha-control-slider { height: 45vh; max-height: 320px; min-height: 200px; + --control-slider-thickness: 100px; + --control-slider-border-radius: 24px; + --control-slider-color: var(--primary-color); + --control-slider-background: -webkit-linear-gradient( + top, + var(--gradient) + ); + --control-slider-background-opacity: 1; } `, ]; diff --git a/src/panels/lovelace/tile-features/hui-light-color-temp-tile-feature.ts b/src/panels/lovelace/tile-features/hui-light-color-temp-tile-feature.ts index 43f16a4655..2c35e33eae 100644 --- a/src/panels/lovelace/tile-features/hui-light-color-temp-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-light-color-temp-tile-feature.ts @@ -3,17 +3,16 @@ import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import memoizeOne from "memoize-one"; -import { rgb2hex } from "../../../common/color/convert-color"; import { DEFAULT_MAX_KELVIN, DEFAULT_MIN_KELVIN, - temperature2rgb, } from "../../../common/color/convert-light-color"; import { computeDomain } from "../../../common/entity/compute_domain"; import { stateActive } from "../../../common/entity/state_active"; import "../../../components/ha-control-slider"; import { UNAVAILABLE } from "../../../data/entity"; import { LightColorMode, lightSupportsColorMode } from "../../../data/light"; +import { generateColorTemperatureGradient } from "../../../dialogs/more-info/components/lights/light-color-temp-picker"; import { HomeAssistant } from "../../../types"; import { LovelaceTileFeature } from "../types"; import { LightColorTempTileFeatureConfig } from "./types"; @@ -70,7 +69,7 @@ class HuiLightColorTempTileFeature const maxKelvin = this.stateObj.attributes.max_color_temp_kelvin ?? DEFAULT_MAX_KELVIN; - const gradient = this.generateTemperatureGradient(minKelvin!, maxKelvin); + const gradient = this._generateTemperatureGradient(minKelvin!, maxKelvin); return html`
@@ -91,26 +90,8 @@ class HuiLightColorTempTileFeature `; } - private generateTemperatureGradient = memoizeOne( - (min: number, max: number) => { - const count = 10; - - const gradient: [number, string][] = []; - - const step = (max - min) / count; - const percentageStep = 1 / count; - - for (let i = 0; i < count + 1; i++) { - const value = min + step * i; - - const hex = rgb2hex(temperature2rgb(value)); - gradient.push([percentageStep * i, hex]); - } - - return gradient - .map(([stop, color]) => `${color} ${(stop as number) * 100}%`) - .join(", "); - } + private _generateTemperatureGradient = memoizeOne( + (min: number, max: number) => generateColorTemperatureGradient(min, max) ); private _valueChanged(ev: CustomEvent) { From c8feded4f2c17bbc7abbc613b612e7fd809c12c2 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 1 Sep 2023 15:26:46 +0200 Subject: [PATCH 09/16] Use format entity state helpers everywhere (#17757) --- .../entity/ha-entity-state-picker.ts | 21 +-- src/components/entity/ha-state-label-badge.ts | 9 +- src/components/ha-climate-state.ts | 60 ++++--- src/components/ha-humidifier-state.ts | 35 ++-- src/components/ha-water_heater-state.js | 8 +- src/data/automation_i18n.ts | 158 ++++++------------ src/data/logbook.ts | 24 +-- src/data/timer.ts | 17 +- .../previews/entity-preview-row.ts | 9 +- .../ha-more-info-climate-temperature.ts | 9 +- .../components/fan/ha-more-info-fan-speed.ts | 14 +- .../components/ha-more-info-state-header.ts | 23 +-- .../ha-more-info-humidifier-humidity.ts | 9 +- .../more-info/controls/more-info-cover.ts | 15 +- .../controls/more-info-humidifier.ts | 40 +---- .../controls/more-info-lawn_mower.ts | 11 +- .../controls/more-info-media_player.ts | 35 ++-- .../more-info/controls/more-info-remote.ts | 11 +- .../more-info/controls/more-info-vacuum.ts | 31 +--- .../configurator-notification-item.ts | 13 +- src/panels/lovelace/cards/hui-entity-card.ts | 9 +- src/panels/lovelace/cards/hui-glance-card.ts | 13 +- .../lovelace/cards/hui-humidifier-card.ts | 31 +--- src/panels/lovelace/cards/hui-light-card.ts | 21 +-- .../lovelace/cards/hui-picture-entity-card.ts | 15 +- .../lovelace/cards/hui-picture-glance-card.ts | 19 +-- .../lovelace/cards/hui-thermostat-card.ts | 35 +--- src/panels/lovelace/cards/hui-tile-card.ts | 6 +- .../cards/hui-weather-forecast-card.ts | 21 +-- .../elements/hui-state-label-element.ts | 13 +- .../entity-rows/hui-event-entity-row.ts | 25 +-- .../entity-rows/hui-group-entity-row.ts | 11 +- .../hui-input-number-entity-row.ts | 16 +- .../hui-media-player-entity-row.ts | 19 +-- .../entity-rows/hui-number-entity-row.ts | 16 +- .../entity-rows/hui-select-entity-row.ts | 14 +- .../entity-rows/hui-sensor-entity-row.ts | 13 +- .../entity-rows/hui-simple-entity-row.ts | 13 +- .../entity-rows/hui-toggle-entity-row.ts | 11 +- .../hui-fan-speed-tile-feature.ts | 14 +- src/state-summary/state-card-alert.ts | 11 +- src/state-summary/state-card-display.ts | 9 +- src/state-summary/state-card-event.ts | 21 +-- src/state-summary/state-card-input_number.ts | 16 +- src/state-summary/state-card-select.ts | 12 +- 45 files changed, 240 insertions(+), 716 deletions(-) diff --git a/src/components/entity/ha-entity-state-picker.ts b/src/components/entity/ha-entity-state-picker.ts index 688b38e6db..b14cbeaa2f 100644 --- a/src/components/entity/ha-entity-state-picker.ts +++ b/src/components/entity/ha-entity-state-picker.ts @@ -1,11 +1,9 @@ import { HassEntity } from "home-assistant-js-websocket"; -import { html, LitElement, PropertyValues, nothing } from "lit"; +import { LitElement, PropertyValues, html, nothing } from "lit"; import { customElement, property, query } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; -import { computeStateDisplay } from "../../common/entity/compute_state_display"; import { getStates } from "../../common/entity/get_states"; -import { computeAttributeValueDisplay } from "../../common/entity/compute_attribute_display"; -import { ValueChangedEvent, HomeAssistant } from "../../types"; +import { HomeAssistant, ValueChangedEvent } from "../../types"; import "../ha-combo-box"; import type { HaComboBox } from "../ha-combo-box"; @@ -58,20 +56,9 @@ class HaEntityStatePicker extends LitElement { ? getStates(state, this.attribute).map((key) => ({ value: key, label: !this.attribute - ? computeStateDisplay( - this.hass.localize, + ? this.hass.formatEntityState(state, key) + : this.hass.formatEntityAttributeValue( state, - this.hass.locale, - this.hass.config, - this.hass.entities, - key - ) - : computeAttributeValueDisplay( - this.hass.localize, - state, - this.hass.locale, - this.hass.config, - this.hass.entities, this.attribute, key ), diff --git a/src/components/entity/ha-state-label-badge.ts b/src/components/entity/ha-state-label-badge.ts index 417ce42024..b340893f06 100644 --- a/src/components/entity/ha-state-label-badge.ts +++ b/src/components/entity/ha-state-label-badge.ts @@ -12,7 +12,6 @@ import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { arrayLiteralIncludes } from "../../common/array/literal-includes"; import secondsToDuration from "../../common/datetime/seconds_to_duration"; -import { computeStateDisplay } from "../../common/entity/compute_state_display"; import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { computeStateName } from "../../common/entity/compute_state_name"; import { FIXED_DOMAIN_STATES } from "../../common/entity/get_states"; @@ -192,13 +191,7 @@ export class HaStateLabelBadge extends LitElement { this.hass!.locale, getNumberFormatOptions(entityState, entry) ) - : computeStateDisplay( - this.hass!.localize, - entityState, - this.hass!.locale, - this.hass!.config, - this.hass!.entities - ); + : this.hass!.formatEntityState(entityState); } } diff --git a/src/components/ha-climate-state.ts b/src/components/ha-climate-state.ts index 047407f7d3..ca5d3a00e9 100644 --- a/src/components/ha-climate-state.ts +++ b/src/components/ha-climate-state.ts @@ -1,9 +1,14 @@ -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import { + css, + CSSResultGroup, + html, + LitElement, + nothing, + TemplateResult, +} from "lit"; import { customElement, property } from "lit/decorators"; -import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { CLIMATE_PRESET_NONE, ClimateEntity } from "../data/climate"; -import { isUnavailableState } from "../data/entity"; +import { isUnavailableState, OFF } from "../data/entity"; import type { HomeAssistant } from "../types"; @customElement("ha-climate-state") @@ -22,26 +27,24 @@ class HaClimateState extends LitElement { ${this.stateObj.attributes.preset_mode && this.stateObj.attributes.preset_mode !== CLIMATE_PRESET_NONE ? html`- - ${computeAttributeValueDisplay( - this.hass.localize, + ${this.hass.formatEntityAttributeValue( this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "preset_mode" )}` - : ""} + : nothing}
${this._computeTarget()}
` : this._localizeState()}
${currentStatus && !isUnavailableState(this.stateObj.state) - ? html`
- ${this.hass.localize("ui.card.climate.currently")}: -
${currentStatus}
-
` - : ""}`; + ? html` +
+ ${this.hass.localize("ui.card.climate.currently")}: +
${currentStatus}
+
+ ` + : nothing}`; } private _computeCurrentStatus(): string | undefined { @@ -125,24 +128,17 @@ class HaClimateState extends LitElement { return this.hass.localize(`state.default.${this.stateObj.state}`); } - const stateString = computeStateDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - ); + const stateString = this.hass.formatEntityState(this.stateObj); - return this.stateObj.attributes.hvac_action - ? `${computeAttributeValueDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "hvac_action" - )} (${stateString})` - : stateString; + if (this.stateObj.attributes.hvac_action && this.stateObj.state !== OFF) { + const actionString = this.hass.formatEntityAttributeValue( + this.stateObj, + "hvac_action" + ); + return `${actionString} (${stateString})`; + } + + return stateString; } static get styles(): CSSResultGroup { diff --git a/src/components/ha-humidifier-state.ts b/src/components/ha-humidifier-state.ts index 63fd33037c..a2d6dc740b 100644 --- a/src/components/ha-humidifier-state.ts +++ b/src/components/ha-humidifier-state.ts @@ -1,7 +1,5 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; -import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { isUnavailableState, OFF } from "../data/entity"; import { HumidifierEntity } from "../data/humidifier"; import type { HomeAssistant } from "../types"; @@ -21,12 +19,8 @@ class HaHumidifierState extends LitElement { ${this._localizeState()} ${this.stateObj.attributes.mode ? html`- - ${computeAttributeValueDisplay( - this.hass.localize, + ${this.hass.formatEntityAttributeValue( this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "mode" )}` : ""} @@ -78,24 +72,17 @@ class HaHumidifierState extends LitElement { return this.hass.localize(`state.default.${this.stateObj.state}`); } - const stateString = computeStateDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - ); + const stateString = this.hass.formatEntityState(this.stateObj); - return this.stateObj.attributes.action && this.stateObj.state !== OFF - ? `${computeAttributeValueDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "action" - )} (${stateString})` - : stateString; + if (this.stateObj.attributes.action && this.stateObj.state !== OFF) { + const actionString = this.hass.formatEntityAttributeValue( + this.stateObj, + "action" + ); + return `${actionString} (${stateString})`; + } + + return stateString; } static get styles(): CSSResultGroup { diff --git a/src/components/ha-water_heater-state.js b/src/components/ha-water_heater-state.js index 4f2220fc58..2d768acfd2 100644 --- a/src/components/ha-water_heater-state.js +++ b/src/components/ha-water_heater-state.js @@ -1,7 +1,6 @@ import { html } from "@polymer/polymer/lib/utils/html-tag"; /* eslint-plugin-disable lit */ import { PolymerElement } from "@polymer/polymer/polymer-element"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { formatNumber } from "../common/number/format_number"; import LocalizeMixin from "../mixins/localize-mixin"; @@ -84,12 +83,7 @@ class HaWaterHeaterState extends LocalizeMixin(PolymerElement) { } _localizeState(stateObj) { - return computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.entities - ); + return this.hass.formatEntityState(stateObj); } } customElements.define("ha-water_heater-state", HaWaterHeaterState); diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts index f0bf51c55c..244fad1ba3 100644 --- a/src/data/automation_i18n.ts +++ b/src/data/automation_i18n.ts @@ -6,11 +6,7 @@ import { formatTimeWithSeconds, } from "../common/datetime/format_time"; import secondsToDuration from "../common/datetime/seconds_to_duration"; -import { - computeAttributeNameDisplay, - computeAttributeValueDisplay, -} from "../common/entity/compute_attribute_display"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; +import { computeAttributeNameDisplay } from "../common/entity/compute_attribute_display"; import { computeStateName } from "../common/entity/compute_state_name"; import "../resources/intl-polyfill"; import type { HomeAssistant } from "../types"; @@ -235,23 +231,14 @@ const tryDescribeTrigger = ( for (const state of trigger.from.values()) { from.push( trigger.attribute - ? computeAttributeValueDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - trigger.attribute, - state - ).toString() - : computeStateDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - state - ) + ? hass + .formatEntityAttributeValue( + stateObj, + trigger.attribute, + state + ) + .toString() + : hass.formatEntityState(stateObj, state) ); } if (from.length !== 0) { @@ -261,23 +248,16 @@ const tryDescribeTrigger = ( } else { base += ` from ${ trigger.attribute - ? computeAttributeValueDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - trigger.attribute, - trigger.from - ).toString() - : computeStateDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - trigger.from.toString() - ).toString() + ? hass + .formatEntityAttributeValue( + stateObj, + trigger.attribute, + trigger.from + ) + .toString() + : hass + .formatEntityState(stateObj, trigger.from.toString()) + .toString() }`; } } @@ -292,23 +272,14 @@ const tryDescribeTrigger = ( for (const state of trigger.to.values()) { to.push( trigger.attribute - ? computeAttributeValueDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - trigger.attribute, - state - ).toString() - : computeStateDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - state - ).toString() + ? hass + .formatEntityAttributeValue( + stateObj, + trigger.attribute, + state + ) + .toString() + : hass.formatEntityState(stateObj, state).toString() ); } if (to.length !== 0) { @@ -318,23 +289,14 @@ const tryDescribeTrigger = ( } else { base += ` to ${ trigger.attribute - ? computeAttributeValueDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - trigger.attribute, - trigger.to - ).toString() - : computeStateDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - trigger.to.toString() - ) + ? hass + .formatEntityAttributeValue( + stateObj, + trigger.attribute, + trigger.to + ) + .toString() + : hass.formatEntityState(stateObj, trigger.to.toString()) }`; } } @@ -822,45 +784,27 @@ const tryDescribeCondition = ( for (const state of condition.state.values()) { states.push( condition.attribute - ? computeAttributeValueDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - condition.attribute, - state - ).toString() - : computeStateDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - state - ) + ? hass + .formatEntityAttributeValue( + stateObj, + condition.attribute, + state + ) + .toString() + : hass.formatEntityState(stateObj, state) ); } } else if (condition.state !== "") { states.push( condition.attribute - ? computeAttributeValueDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - condition.attribute, - condition.state - ).toString() - : computeStateDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - condition.state.toString() - ) + ? hass + .formatEntityAttributeValue( + stateObj, + condition.attribute, + condition.state + ) + .toString() + : hass.formatEntityState(stateObj, condition.state.toString()) ); } diff --git a/src/data/logbook.ts b/src/data/logbook.ts index e4990da292..8534d548ce 100644 --- a/src/data/logbook.ts +++ b/src/data/logbook.ts @@ -5,14 +5,12 @@ import { DOMAINS_WITH_DYNAMIC_PICTURE, } from "../common/const"; import { computeDomain } from "../common/entity/compute_domain"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { computeStateDomain } from "../common/entity/compute_state_domain"; import { autoCaseNoun } from "../common/translations/auto_case_noun"; import { LocalizeFunc } from "../common/translations/localize"; import { HaEntityPickerEntityFilterFunc } from "../components/entity/ha-entity-picker"; import { HomeAssistant } from "../types"; import { UNAVAILABLE, UNKNOWN } from "./entity"; -import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display"; const LOGBOOK_LOCALIZE_PATH = "ui.components.logbook.messages"; export const CONTINUOUS_DOMAINS = ["counter", "proximity", "sensor", "zone"]; @@ -339,14 +337,9 @@ export const localizeStateMessage = ( // TODO: This is not working yet, as we don't get historic attribute values - const event_type = computeAttributeValueDisplay( - hass!.localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - "event_type" - )?.toString(); + const event_type = hass + .formatEntityAttributeValue(stateObj, "event_type") + ?.toString(); if (!event_type) { return localize(`${LOGBOOK_LOCALIZE_PATH}.detected_unknown_event`); @@ -392,16 +385,7 @@ export const localizeStateMessage = ( return hass.localize( `${LOGBOOK_LOCALIZE_PATH}.changed_to_state`, "state", - stateObj - ? computeStateDisplay( - localize, - stateObj, - hass.locale, - hass.config, - hass.entities, - state - ) - : state + stateObj ? hass.formatEntityState(stateObj, state) : state ); }; diff --git a/src/data/timer.ts b/src/data/timer.ts index 5401175d41..7dc4f8e41d 100644 --- a/src/data/timer.ts +++ b/src/data/timer.ts @@ -5,7 +5,6 @@ import { } from "home-assistant-js-websocket"; import durationToSeconds from "../common/datetime/duration_to_seconds"; import secondsToDuration from "../common/datetime/seconds_to_duration"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { HomeAssistant } from "../types"; export type TimerEntity = HassEntityBase & { @@ -90,25 +89,13 @@ export const computeDisplayTimer = ( } if (stateObj.state === "idle" || timeRemaining === 0) { - return computeStateDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities - ); + return hass.formatEntityState(stateObj); } let display = secondsToDuration(timeRemaining || 0); if (stateObj.state === "paused") { - display = `${display} (${computeStateDisplay( - hass.localize, - stateObj, - hass.locale, - hass.config, - hass.entities - )})`; + display = `${display} (${hass.formatEntityState(stateObj)})`; } return display; diff --git a/src/dialogs/config-flow/previews/entity-preview-row.ts b/src/dialogs/config-flow/previews/entity-preview-row.ts index 1ca2b10c13..5d5fa811fa 100644 --- a/src/dialogs/config-flow/previews/entity-preview-row.ts +++ b/src/dialogs/config-flow/previews/entity-preview-row.ts @@ -1,7 +1,6 @@ import { HassEntity } from "home-assistant-js-websocket"; import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { isUnavailableState } from "../../../data/entity"; import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor"; @@ -35,13 +34,7 @@ class EntityPreviewRow extends LitElement { capitalize > ` - : computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + : this.hass.formatEntityState(stateObj)}
`; } diff --git a/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts b/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts index 25a18f810d..f0b1954f55 100644 --- a/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts +++ b/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts @@ -11,7 +11,6 @@ import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { styleMap } from "lit/directives/style-map"; import { UNIT_F } from "../../../../common/const"; -import { computeAttributeValueDisplay } from "../../../../common/entity/compute_attribute_display"; import { stateActive } from "../../../../common/entity/state_active"; import { stateColorCss } from "../../../../common/entity/state_color"; import { supportsFeature } from "../../../../common/entity/supports-feature"; @@ -162,14 +161,10 @@ export class HaMoreInfoClimateTemperature extends LitElement { const action = this.stateObj.attributes.hvac_action; - const actionLabel = computeAttributeValueDisplay( - this.hass.localize, + const actionLabel = this.hass.formatEntityAttributeValue( this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "hvac_action" - ) as string; + ); return html`

diff --git a/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts b/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts index 72333bd2a2..d1a641d6c5 100644 --- a/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts +++ b/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts @@ -2,7 +2,6 @@ import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import { computeAttributeNameDisplay } from "../../../../common/entity/compute_attribute_display"; -import { computeStateDisplay } from "../../../../common/entity/compute_state_display"; import { stateActive } from "../../../../common/entity/state_active"; import { stateColorCss } from "../../../../common/entity/state_color"; import "../../../../components/ha-control-select"; @@ -12,12 +11,12 @@ import { UNAVAILABLE } from "../../../../data/entity"; import { computeFanSpeedCount, computeFanSpeedIcon, + FAN_SPEED_COUNT_MAX_FOR_BUTTONS, + FAN_SPEEDS, FanEntity, fanPercentageToSpeed, FanSpeed, fanSpeedToPercentage, - FAN_SPEEDS, - FAN_SPEED_COUNT_MAX_FOR_BUTTONS, } from "../../../../data/fan"; import { HomeAssistant } from "../../../../types"; @@ -68,14 +67,7 @@ export class HaMoreInfoFanSpeed extends LitElement { private _localizeSpeed(speed: FanSpeed) { if (speed === "on" || speed === "off") { - return computeStateDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - speed - ); + return this.hass.formatEntityState(this.stateObj, speed); } return ( this.hass.localize(`ui.dialogs.more_info_control.fan.speed.${speed}`) || diff --git a/src/dialogs/more-info/components/ha-more-info-state-header.ts b/src/dialogs/more-info/components/ha-more-info-state-header.ts index 150058e89b..4697868390 100644 --- a/src/dialogs/more-info/components/ha-more-info-state-header.ts +++ b/src/dialogs/more-info/components/ha-more-info-state-header.ts @@ -1,7 +1,5 @@ -import { HassEntity } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import "../../../components/ha-absolute-time"; import "../../../components/ha-relative-time"; import { isUnavailableState } from "../../../data/entity"; @@ -20,30 +18,22 @@ export class HaMoreInfoStateHeader extends LitElement { @state() private _absoluteTime = false; - private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string { + private _localizeState(): TemplateResult | string { if ( - stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP && - !isUnavailableState(stateObj.state) + this.stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP && + !isUnavailableState(this.stateObj.state) ) { return html` `; } - const stateDisplay = computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass!.locale, - this.hass!.config, - this.hass!.entities - ); - - return stateDisplay; + return this.hass.formatEntityState(this.stateObj); } private _toggleAbsolute() { @@ -51,8 +41,7 @@ export class HaMoreInfoStateHeader extends LitElement { } protected render(): TemplateResult { - const stateDisplay = - this.stateOverride ?? this._computeStateDisplay(this.stateObj); + const stateDisplay = this.stateOverride ?? this._localizeState(); return html`

${stateDisplay}

diff --git a/src/dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity.ts b/src/dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity.ts index 1a3db1121c..d93f506f10 100644 --- a/src/dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity.ts +++ b/src/dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity.ts @@ -2,7 +2,6 @@ import { mdiMinus, mdiPlus } from "@mdi/js"; import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit"; import { customElement, property, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; -import { computeAttributeValueDisplay } from "../../../../common/entity/compute_attribute_display"; import { stateActive } from "../../../../common/entity/state_active"; import { stateColorCss } from "../../../../common/entity/state_color"; import { clamp } from "../../../../common/number/clamp"; @@ -92,14 +91,10 @@ export class HaMoreInfoHumidifierHumidity extends LitElement { const action = this.stateObj.attributes.action; - const actionLabel = computeAttributeValueDisplay( - this.hass.localize, + const actionLabel = this.hass.formatEntityAttributeValue( this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "action" - ) as string; + ); return html`

diff --git a/src/dialogs/more-info/controls/more-info-cover.ts b/src/dialogs/more-info/controls/more-info-cover.ts index d685d1bb63..02b2f2ec5a 100644 --- a/src/dialogs/more-info/controls/more-info-cover.ts +++ b/src/dialogs/more-info/controls/more-info-cover.ts @@ -1,22 +1,21 @@ import { mdiMenu, mdiSwapVertical } from "@mdi/js"; import { - css, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, + css, + html, + nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { supportsFeature } from "../../../common/entity/supports-feature"; import "../../../components/ha-attributes"; import "../../../components/ha-icon-button-group"; import "../../../components/ha-icon-button-toggle"; import { - computeCoverPositionStateDisplay, CoverEntity, CoverEntityFeature, + computeCoverPositionStateDisplay, } from "../../../data/cover"; import type { HomeAssistant } from "../../../types"; import "../components/cover/ha-more-info-cover-buttons"; @@ -83,12 +82,8 @@ class MoreInfoCover extends LitElement { const forcedState = liveValue != null ? (liveValue ? "open" : "closed") : undefined; - const stateDisplay = computeStateDisplay( - this.hass.localize, + const stateDisplay = this.hass.formatEntityState( this.stateObj!, - this.hass.locale, - this.hass.config, - this.hass.entities, forcedState ); diff --git a/src/dialogs/more-info/controls/more-info-humidifier.ts b/src/dialogs/more-info/controls/more-info-humidifier.ts index 74754e25ad..d919753c86 100644 --- a/src/dialogs/more-info/controls/more-info-humidifier.ts +++ b/src/dialogs/more-info/controls/more-info-humidifier.ts @@ -10,11 +10,6 @@ import { import { property, state } from "lit/decorators"; import { fireEvent } from "../../../common/dom/fire_event"; import { stopPropagation } from "../../../common/dom/stop_propagation"; -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 "../../../components/ha-control-select-menu"; import "../../../components/ha-list-item"; @@ -58,26 +53,21 @@ class MoreInfoHumidifier extends LitElement { HumidifierEntityFeature.MODES ); - const currentHumidity = this.stateObj.attributes.current_humidity as number; - return html`

- ${currentHumidity != null + ${this.stateObj.attributes.current_humidity != null ? html`

- ${computeAttributeNameDisplay( - this.hass.localize, + ${this.hass.formatEntityAttributeName( this.stateObj, - this.hass.entities, "current_humidity" )}

${this.hass.formatEntityAttributeValue( this.stateObj, - "current_humidity", - currentHumidity + "current_humidity" )}

@@ -104,24 +94,10 @@ class MoreInfoHumidifier extends LitElement { > - ${computeStateDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "off" - )} + ${this.hass.formatEntityState(this.stateObj, "off")} - ${computeStateDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "on" - )} + ${this.hass.formatEntityState(this.stateObj, "on")} @@ -144,12 +120,8 @@ class MoreInfoHumidifier extends LitElement { slot="graphic" .path=${computeHumidiferModeIcon(mode)} > - ${computeAttributeValueDisplay( - hass.localize, + ${this.hass.formatEntityAttributeValue( stateObj!, - hass.locale, - hass.config, - hass.entities, "mode", mode )} diff --git a/src/dialogs/more-info/controls/more-info-lawn_mower.ts b/src/dialogs/more-info/controls/more-info-lawn_mower.ts index b2437bdb45..05a92ce1ce 100644 --- a/src/dialogs/more-info/controls/more-info-lawn_mower.ts +++ b/src/dialogs/more-info/controls/more-info-lawn_mower.ts @@ -2,7 +2,6 @@ import { mdiHomeImportOutline, mdiPause, mdiPlay } from "@mdi/js"; import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; import { customElement, property } from "lit/decorators"; import memoizeOne from "memoize-one"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { supportsFeature } from "../../../common/entity/supports-feature"; import { blankBeforePercent } from "../../../common/translations/blank_before_percent"; @@ -74,15 +73,7 @@ class MoreInfoLawnMower extends LitElement { )}: - - ${computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} - + ${this.hass.formatEntityState(stateObj)}
${this._renderBattery()} diff --git a/src/dialogs/more-info/controls/more-info-media_player.ts b/src/dialogs/more-info/controls/more-info-media_player.ts index 1d9fcbe0fc..044745d78d 100644 --- a/src/dialogs/more-info/controls/more-info-media_player.ts +++ b/src/dialogs/more-info/controls/more-info-media_player.ts @@ -9,24 +9,23 @@ import { mdiVolumeOff, mdiVolumePlus, } from "@mdi/js"; -import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; +import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; import { customElement, property } from "lit/decorators"; import { stopPropagation } from "../../../common/dom/stop_propagation"; -import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; +import { stateActive } from "../../../common/entity/state_active"; import { supportsFeature } from "../../../common/entity/supports-feature"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; -import { stateActive } from "../../../common/entity/state_active"; import "../../../components/ha-icon-button"; import "../../../components/ha-select"; import "../../../components/ha-slider"; import "../../../components/ha-svg-icon"; import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog"; import { - computeMediaControls, - handleMediaControlClick, MediaPickedEvent, MediaPlayerEntity, MediaPlayerEntityFeature, + computeMediaControls, + handleMediaControlClick, mediaPlayerPlayMedia, } from "../../../data/media-player"; import { HomeAssistant } from "../../../types"; @@ -157,24 +156,20 @@ class MoreInfoMediaPlayer extends LitElement { > ${stateObj.attributes.source_list!.map( (source) => html` - ${computeAttributeValueDisplay( - this.hass.localize, + + ${this.hass.formatEntityAttributeValue( stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "source", source - )} + )} + ` )} ` - : ""} + : nothing} ${stateActive(stateObj) && supportsFeature(stateObj, MediaPlayerEntityFeature.SELECT_SOUND_MODE) && stateObj.attributes.sound_mode_list?.length @@ -191,17 +186,13 @@ class MoreInfoMediaPlayer extends LitElement { > ${stateObj.attributes.sound_mode_list.map( (mode) => html` - ${computeAttributeValueDisplay( - this.hass.localize, + + ${this.hass.formatEntityAttributeValue( stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "sound_mode", mode - )} + )} + ` )} diff --git a/src/dialogs/more-info/controls/more-info-remote.ts b/src/dialogs/more-info/controls/more-info-remote.ts index 9080897c13..918ebd3a71 100644 --- a/src/dialogs/more-info/controls/more-info-remote.ts +++ b/src/dialogs/more-info/controls/more-info-remote.ts @@ -2,11 +2,10 @@ import "@material/mwc-list/mwc-list"; import "@material/mwc-list/mwc-list-item"; import { html, LitElement, nothing } from "lit"; import { customElement, property } from "lit/decorators"; -import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; import { stopPropagation } from "../../../common/dom/stop_propagation"; import { supportsFeature } from "../../../common/entity/supports-feature"; import "../../../components/ha-attributes"; -import { RemoteEntity, REMOTE_SUPPORT_ACTIVITY } from "../../../data/remote"; +import { REMOTE_SUPPORT_ACTIVITY, RemoteEntity } from "../../../data/remote"; import { HomeAssistant } from "../../../types"; const filterExtraAttributes = "activity_list,current_activity"; @@ -40,12 +39,8 @@ class MoreInfoRemote extends LitElement { ${stateObj.attributes.activity_list!.map( (activity) => html` - ${computeAttributeValueDisplay( - this.hass.localize, + ${this.hass.formatEntityAttributeValue( stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "activity", activity )} @@ -54,7 +49,7 @@ class MoreInfoRemote extends LitElement { )} ` - : ""} + : nothing} ${supportsFeature(stateObj, VacuumEntityFeature.STATUS) && stateObj.attributes.status - ? computeAttributeValueDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "status" - ) - : computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + ? this.hass.formatEntityAttributeValue(stateObj, "status") + : this.hass.formatEntityState(stateObj)} @@ -197,12 +182,8 @@ class MoreInfoVacuum extends LitElement { ${stateObj.attributes.fan_speed_list!.map( (mode) => html` - ${computeAttributeValueDisplay( - this.hass.localize, + ${this.hass.formatEntityAttributeValue( stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "fan_speed", mode )} @@ -215,12 +196,8 @@ class MoreInfoVacuum extends LitElement { > - ${computeAttributeValueDisplay( - this.hass.localize, + ${this.hass.formatEntityAttributeValue( stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "fan_speed" )} diff --git a/src/dialogs/notifications/configurator-notification-item.ts b/src/dialogs/notifications/configurator-notification-item.ts index 96174e02a1..306b0f40be 100644 --- a/src/dialogs/notifications/configurator-notification-item.ts +++ b/src/dialogs/notifications/configurator-notification-item.ts @@ -2,7 +2,6 @@ import "@material/mwc-button"; import { html, LitElement, nothing } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../../common/dom/fire_event"; -import { computeStateDisplay } from "../../common/entity/compute_state_display"; import { domainToName } from "../../data/integration"; import { PersitentNotificationEntity } from "../../data/persistent_notification"; import { HomeAssistant } from "../../types"; @@ -33,15 +32,9 @@ export class HuiConfiguratorNotificationItem extends LitElement { )} - ${computeStateDisplay( - this.hass.localize, - this.notification, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + + ${this.hass.formatEntityState(this.notification)} + `; } diff --git a/src/panels/lovelace/cards/hui-entity-card.ts b/src/panels/lovelace/cards/hui-entity-card.ts index 7acee6c5d2..be1d5102d5 100644 --- a/src/panels/lovelace/cards/hui-entity-card.ts +++ b/src/panels/lovelace/cards/hui-entity-card.ts @@ -12,7 +12,6 @@ import { ifDefined } from "lit/directives/if-defined"; import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { @@ -176,13 +175,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard { this.hass.entities[this._config.entity] ) ) - : computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )}${showUnit ? html` ` - : computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass!.locale, - this.hass!.config, - this.hass!.entities - )} + : this.hass!.formatEntityState(stateObj)} ` : ""} diff --git a/src/panels/lovelace/cards/hui-humidifier-card.ts b/src/panels/lovelace/cards/hui-humidifier-card.ts index 3aae9d2bf5..eae7103ec3 100644 --- a/src/panels/lovelace/cards/hui-humidifier-card.ts +++ b/src/panels/lovelace/cards/hui-humidifier-card.ts @@ -11,12 +11,10 @@ import { svg, } from "lit"; import { customElement, property, query, state } from "lit/decorators"; -import { styleMap } from "lit/directives/style-map"; import { classMap } from "lit/directives/class-map"; +import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; -import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { stateColorCss } from "../../../common/entity/state_color"; import { formatNumber } from "../../../common/number/format_number"; @@ -168,34 +166,13 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard { > ${ stateObj.attributes.action - ? computeAttributeValueDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "action" - ) - : computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - ) + ? this.hass.formatEntityAttributeValue(stateObj, "action") + : this.hass.formatEntityState(stateObj) } ${ stateObj.state !== UNAVAILABLE && stateObj.attributes.mode ? html` - - - ${computeAttributeValueDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "mode" - )} + - ${this.hass.formatEntityAttributeValue(stateObj, "mode")} ` : nothing } diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index c2715b8007..308423d55a 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -1,11 +1,11 @@ import { mdiDotsVertical } from "@mdi/js"; import "@thomasloven/round-slider"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -13,12 +13,12 @@ import { classMap } from "lit/directives/class-map"; import { styleMap } from "lit/directives/style-map"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; +import { stateColorBrightness } from "../../../common/entity/state_color"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; import "../../../components/ha-state-icon"; -import { isUnavailableState, UNAVAILABLE } from "../../../data/entity"; +import { UNAVAILABLE, isUnavailableState } from "../../../data/entity"; import { LightEntity, lightSupportsBrightness } from "../../../data/light"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; @@ -30,7 +30,6 @@ import { hasConfigOrEntityChanged } from "../common/has-changed"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { LovelaceCard, LovelaceCardEditor } from "../types"; import { LightCardConfig } from "./types"; -import { stateColorBrightness } from "../../../common/entity/state_color"; @customElement("hui-light-card") export class HuiLightCard extends LitElement implements LovelaceCard { @@ -156,17 +155,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard {
${isUnavailableState(stateObj.state) - ? html` -
- ${computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} -
- ` + ? html`
${this.hass.formatEntityState(stateObj)}
` : html`
%
`} ${name}
diff --git a/src/panels/lovelace/cards/hui-picture-entity-card.ts b/src/panels/lovelace/cards/hui-picture-entity-card.ts index f1889d8f23..3f89389dad 100644 --- a/src/panels/lovelace/cards/hui-picture-entity-card.ts +++ b/src/panels/lovelace/cards/hui-picture-entity-card.ts @@ -1,20 +1,19 @@ import { - css, CSSResultGroup, - html, LitElement, PropertyValues, TemplateResult, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { computeDomain } from "../../../common/entity/compute_domain"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; import "../../../components/ha-card"; -import { computeImageUrl, ImageEntity } from "../../../data/image"; +import { ImageEntity, computeImageUrl } from "../../../data/image"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { actionHandler } from "../common/directives/action-handler-directive"; @@ -120,13 +119,7 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard { } const name = this._config.name || computeStateName(stateObj); - const entityState = computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - ); + const entityState = this.hass.formatEntityState(stateObj); let footer: TemplateResult | string = ""; if (this._config.show_name && this._config.show_state) { diff --git a/src/panels/lovelace/cards/hui-picture-glance-card.ts b/src/panels/lovelace/cards/hui-picture-glance-card.ts index d8210fe807..289df6bf33 100644 --- a/src/panels/lovelace/cards/hui-picture-glance-card.ts +++ b/src/panels/lovelace/cards/hui-picture-glance-card.ts @@ -13,7 +13,6 @@ import { ifDefined } from "lit/directives/if-defined"; import { DOMAINS_TOGGLE } from "../../../common/const"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { computeDomain } from "../../../common/entity/compute_domain"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; @@ -273,13 +272,9 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard { class=${classMap({ "state-on": !STATES_OFF.has(stateObj.state), })} - title=${`${computeStateName(stateObj)} : ${computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass!.locale, - this.hass!.config, - this.hass!.entities - )}`} + title=${`${computeStateName( + stateObj + )} : ${this.hass.formatEntityState(stateObj)}`} > `} diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index f26273f4ee..76de3ee618 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -11,12 +11,12 @@ import { import "@thomasloven/round-slider"; import { HassEntity } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, - nothing, PropertyValues, + css, + html, + nothing, svg, } from "lit"; import { customElement, property, query, state } from "lit/decorators"; @@ -25,8 +25,6 @@ import { styleMap } from "lit/directives/style-map"; import { UNIT_F } from "../../../common/const"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { fireEvent } from "../../../common/dom/fire_event"; -import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { stateColorCss } from "../../../common/entity/state_color"; import { formatNumber } from "../../../common/number/format_number"; @@ -34,10 +32,10 @@ import "../../../components/ha-card"; import type { HaCard } from "../../../components/ha-card"; import "../../../components/ha-icon-button"; import { - ClimateEntity, CLIMATE_PRESET_NONE, - compareClimateHvacModes, + ClimateEntity, HvacMode, + compareClimateHvacModes, } from "../../../data/climate"; import { UNAVAILABLE } from "../../../data/entity"; import { HomeAssistant } from "../../../types"; @@ -207,21 +205,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { > ${ stateObj.state !== UNAVAILABLE && stateObj.attributes.hvac_action - ? computeAttributeValueDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "hvac_action" - ) - : computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - ) + ? this.hass.formatEntityAttributeValue(stateObj, "hvac_action") + : this.hass.formatEntityState(stateObj) } ${ stateObj.state !== UNAVAILABLE && @@ -229,12 +214,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { stateObj.attributes.preset_mode !== CLIMATE_PRESET_NONE ? html` - - ${computeAttributeValueDisplay( - this.hass.localize, + ${this.hass.formatEntityAttributeValue( stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, "preset_mode" )} ` diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index a0f7e8bcf9..915bed56d4 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -180,7 +180,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { } ); - private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string { + private _formatState(stateObj: HassEntity): TemplateResult | string { const domain = computeDomain(stateObj.entity_id); if ( @@ -308,7 +308,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { const name = this._config.name || stateObj.attributes.friendly_name; - const stateDisplay = this._computeStateDisplay(stateObj); + const localizedState = this._formatState(stateObj); const active = stateActive(stateObj); const color = this._computeStateColor(stateObj, this._config.color); @@ -381,7 +381,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts index 2dfd3a3a88..dec8eac04c 100644 --- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts +++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts @@ -1,16 +1,16 @@ import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; +import { formatDateWeekdayShort } from "../../../common/datetime/format_date"; import { formatTime } from "../../../common/datetime/format_time"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; import { isValidEntityId } from "../../../common/entity/valid_entity_id"; import { formatNumber } from "../../../common/number/format_number"; @@ -20,28 +20,27 @@ import "../../../components/ha-svg-icon"; import { UNAVAILABLE } from "../../../data/entity"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { + ForecastEvent, + WeatherEntity, getForecast, getSecondaryWeatherAttribute, getWeatherStateIcon, getWeatherUnit, getWind, subscribeForecast, - ForecastEvent, weatherAttrIcons, - WeatherEntity, weatherSVGStyles, } from "../../../data/weather"; +import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import type { HomeAssistant } from "../../../types"; import { actionHandler } from "../common/directives/action-handler-directive"; import { findEntities } from "../common/find-entities"; import { handleAction } from "../common/handle-action"; import { hasAction } from "../common/has-action"; import { hasConfigOrEntityChanged } from "../common/has-changed"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import type { LovelaceCard, LovelaceCardEditor } from "../types"; import type { WeatherForecastCardConfig } from "./types"; -import { formatDateWeekdayShort } from "../../../common/datetime/format_date"; @customElement("hui-weather-forecast-card") class HuiWeatherForecastCard extends LitElement implements LovelaceCard { @@ -265,13 +264,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
- ${computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + ${this.hass.formatEntityState(stateObj)}
${name}
diff --git a/src/panels/lovelace/elements/hui-state-label-element.ts b/src/panels/lovelace/elements/hui-state-label-element.ts index d7f3ce9872..a0427bdbcd 100644 --- a/src/panels/lovelace/elements/hui-state-label-element.ts +++ b/src/panels/lovelace/elements/hui-state-label-element.ts @@ -1,14 +1,13 @@ import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; import { ifDefined } from "lit/directives/if-defined"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { computeTooltip } from "../common/compute-tooltip"; @@ -83,13 +82,7 @@ class HuiStateLabelElement extends LitElement implements LovelaceElement { )} > ${this._config.prefix}${!this._config.attribute - ? computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - ) + ? this.hass.formatEntityState(stateObj) : stateObj.attributes[this._config.attribute]}${this._config.suffix}
`; diff --git a/src/panels/lovelace/entity-rows/hui-event-entity-row.ts b/src/panels/lovelace/entity-rows/hui-event-entity-row.ts index f7abad2349..565d046cae 100644 --- a/src/panels/lovelace/entity-rows/hui-event-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-event-entity-row.ts @@ -1,14 +1,12 @@ import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; -import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display"; import { isUnavailableState } from "../../../data/entity"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; @@ -70,13 +68,7 @@ class HuiEventEntityRow extends LitElement implements LovelaceRow { >
${isUnavailableState(stateObj.state) - ? computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - ) + ? this.hass.formatEntityState(stateObj) : html`
${isUnavailableState(stateObj.state) - ? `` - : computeAttributeValueDisplay( - this.hass!.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "event_type" - )} + ? nothing + : this.hass.formatEntityAttributeValue(stateObj, "event_type")}
diff --git a/src/panels/lovelace/entity-rows/hui-group-entity-row.ts b/src/panels/lovelace/entity-rows/hui-group-entity-row.ts index 146943251e..a530bdeabe 100644 --- a/src/panels/lovelace/entity-rows/hui-group-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-group-entity-row.ts @@ -1,8 +1,7 @@ -import { html, LitElement, PropertyValues, nothing } from "lit"; +import { LitElement, PropertyValues, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { DOMAINS_TOGGLE } from "../../../common/const"; import { computeDomain } from "../../../common/entity/compute_domain"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import "../../../components/entity/ha-entity-toggle"; import { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; @@ -66,13 +65,7 @@ class HuiGroupEntityRow extends LitElement implements LovelaceRow { ` : html`
- ${computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + ${this.hass.formatEntityState(stateObj)}
`} diff --git a/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts b/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts index 9281d2391f..41bbd14f69 100644 --- a/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-input-number-entity-row.ts @@ -1,22 +1,21 @@ import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; import { debounce } from "../../../common/util/debounce"; import "../../../components/ha-slider"; import "../../../components/ha-textfield"; import { isUnavailableState } from "../../../data/entity"; import { setValue } from "../../../data/input_text"; +import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import "../components/hui-generic-entity-row"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { EntityConfig, LovelaceRow } from "./types"; @@ -97,14 +96,7 @@ class HuiInputNumberEntityRow extends LitElement implements LovelaceRow { ignore-bar-touch > - ${computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - stateObj.state - )} + ${this.hass.formatEntityState(stateObj)} ` diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts index daf1aa150c..36bc2bb76a 100644 --- a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts @@ -13,31 +13,30 @@ import { } from "@mdi/js"; import { HassEntity } from "home-assistant-js-websocket"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; +import { stateActive } from "../../../common/entity/state_active"; import { supportsFeature } from "../../../common/entity/supports-feature"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; -import { stateActive } from "../../../common/entity/state_active"; import { debounce } from "../../../common/util/debounce"; import "../../../components/ha-icon-button"; import "../../../components/ha-slider"; import { isUnavailableState } from "../../../data/entity"; import { - computeMediaDescription, ControlButton, MediaPlayerEntity, MediaPlayerEntityFeature, + computeMediaDescription, } from "../../../data/media-player"; +import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import type { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import "../components/hui-generic-entity-row"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import type { EntityConfig, LovelaceRow } from "./types"; @@ -191,13 +190,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow { .hass=${this.hass} .config=${this._config} .secondaryText=${mediaDescription || - computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + this.hass.formatEntityState(stateObj)} >
${supportsFeature(stateObj, MediaPlayerEntityFeature.TURN_ON) && diff --git a/src/panels/lovelace/entity-rows/hui-number-entity-row.ts b/src/panels/lovelace/entity-rows/hui-number-entity-row.ts index 7b4d2a6848..83fabc5f5b 100644 --- a/src/panels/lovelace/entity-rows/hui-number-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-number-entity-row.ts @@ -1,22 +1,21 @@ import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; import { debounce } from "../../../common/util/debounce"; import "../../../components/ha-slider"; import "../../../components/ha-textfield"; import { UNAVAILABLE } from "../../../data/entity"; import { setValue } from "../../../data/input_text"; +import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import { HomeAssistant } from "../../../types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; -import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import "../components/hui-generic-entity-row"; import { createEntityNotFoundWarning } from "../components/hui-warning"; import { EntityConfig, LovelaceRow } from "./types"; @@ -101,14 +100,7 @@ class HuiNumberEntityRow extends LitElement implements LovelaceRow { ignore-bar-touch > - ${computeStateDisplay( - this.hass.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - stateObj.state - )} + ${this.hass.formatEntityState(stateObj)}
` diff --git a/src/panels/lovelace/entity-rows/hui-select-entity-row.ts b/src/panels/lovelace/entity-rows/hui-select-entity-row.ts index 31b51927c1..f65c945004 100644 --- a/src/panels/lovelace/entity-rows/hui-select-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-select-entity-row.ts @@ -1,15 +1,14 @@ import "@material/mwc-list/mwc-list-item"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; import { stopPropagation } from "../../../common/dom/stop_propagation"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { computeStateName } from "../../../common/entity/compute_state_name"; import "../../../components/ha-select"; import { UNAVAILABLE } from "../../../data/entity"; @@ -77,14 +76,7 @@ class HuiSelectEntityRow extends LitElement implements LovelaceRow { ? stateObj.attributes.options.map( (option) => html` - ${computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass!.locale, - this.hass!.config, - this.hass!.entities, - option - )} + ${this.hass!.formatEntityState(stateObj, option)} ` ) diff --git a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts index 0d536ca9f9..5f6dec0d22 100644 --- a/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-sensor-entity-row.ts @@ -1,13 +1,12 @@ import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { isUnavailableState } from "../../../data/entity"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor"; @@ -79,13 +78,7 @@ class HuiSensorEntityRow extends LitElement implements LovelaceRow { capitalize > ` - : computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + : this.hass.formatEntityState(stateObj)} `; diff --git a/src/panels/lovelace/entity-rows/hui-simple-entity-row.ts b/src/panels/lovelace/entity-rows/hui-simple-entity-row.ts index 23b4cb8720..604c632820 100644 --- a/src/panels/lovelace/entity-rows/hui-simple-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-simple-entity-row.ts @@ -1,13 +1,12 @@ import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { HomeAssistant } from "../../../types"; import { EntitiesCardEntityConfig } from "../cards/types"; import { hasConfigOrEntityChanged } from "../common/has-changed"; @@ -49,13 +48,7 @@ class HuiSimpleEntityRow extends LitElement implements LovelaceRow { return html` - ${computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + ${this.hass.formatEntityState(stateObj)} `; } diff --git a/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts b/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts index 611fd2bdd5..376447f7a5 100644 --- a/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts +++ b/src/panels/lovelace/entity-rows/hui-toggle-entity-row.ts @@ -1,6 +1,5 @@ -import { html, LitElement, PropertyValues, nothing } from "lit"; +import { LitElement, PropertyValues, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import "../../../components/entity/ha-entity-toggle"; import { isUnavailableState } from "../../../data/entity"; import { HomeAssistant } from "../../../types"; @@ -61,13 +60,7 @@ class HuiToggleEntityRow extends LitElement implements LovelaceRow { ` : html`
- ${computeStateDisplay( - this.hass!.localize, - stateObj, - this.hass!.locale, - this.hass.config, - this.hass!.entities - )} + ${this.hass.formatEntityState(stateObj)}
`} diff --git a/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts b/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts index da69431ad0..8e6804d1f4 100644 --- a/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts +++ b/src/panels/lovelace/tile-features/hui-fan-speed-tile-feature.ts @@ -3,7 +3,6 @@ import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { computeAttributeNameDisplay } from "../../../common/entity/compute_attribute_display"; import { computeDomain } from "../../../common/entity/compute_domain"; -import { computeStateDisplay } from "../../../common/entity/compute_state_display"; import { stateActive } from "../../../common/entity/state_active"; import { supportsFeature } from "../../../common/entity/supports-feature"; import "../../../components/ha-control-select"; @@ -13,13 +12,13 @@ import { UNAVAILABLE } from "../../../data/entity"; import { computeFanSpeedCount, computeFanSpeedIcon, + FAN_SPEED_COUNT_MAX_FOR_BUTTONS, + FAN_SPEEDS, FanEntity, FanEntityFeature, fanPercentageToSpeed, FanSpeed, fanSpeedToPercentage, - FAN_SPEEDS, - FAN_SPEED_COUNT_MAX_FOR_BUTTONS, } from "../../../data/fan"; import { HomeAssistant } from "../../../types"; import { LovelaceTileFeature } from "../types"; @@ -55,14 +54,7 @@ class HuiFanSpeedTileFeature extends LitElement implements LovelaceTileFeature { private _localizeSpeed(speed: FanSpeed) { if (speed === "on" || speed === "off") { - return computeStateDisplay( - this.hass!.localize, - this.stateObj!, - this.hass!.locale, - this.hass!.config, - this.hass!.entities, - speed - ); + return this.hass!.formatEntityState(this.stateObj!, speed); } return ( this.hass!.localize(`ui.dialogs.more_info_control.fan.speed.${speed}`) || diff --git a/src/state-summary/state-card-alert.ts b/src/state-summary/state-card-alert.ts index 151637490b..70a4f1fd0a 100755 --- a/src/state-summary/state-card-alert.ts +++ b/src/state-summary/state-card-alert.ts @@ -1,11 +1,10 @@ import type { HassEntity } from "home-assistant-js-websocket"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; +import { stateActive } from "../common/entity/state_active"; import { computeRTL } from "../common/util/compute_rtl"; import "../components/entity/state-info"; import { haStyle } from "../resources/styles"; -import { stateActive } from "../common/entity/state_active"; import type { HomeAssistant } from "../types"; @customElement("state-card-alert") @@ -34,13 +33,7 @@ export class StateCardAlert extends LitElement { .hass=${this.hass} .stateObj=${this.stateObj} >` - : computeStateDisplay( - this.hass!.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + : this.hass.formatEntityState(this.stateObj)} `; diff --git a/src/state-summary/state-card-display.ts b/src/state-summary/state-card-display.ts index a168d05711..7ddc3074db 100755 --- a/src/state-summary/state-card-display.ts +++ b/src/state-summary/state-card-display.ts @@ -3,7 +3,6 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { computeDomain } from "../common/entity/compute_domain"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { computeRTL } from "../common/util/compute_rtl"; import "../components/entity/state-info"; import { isUnavailableState } from "../data/entity"; @@ -48,13 +47,7 @@ export class StateCardDisplay extends LitElement { format="datetime" capitalize >` - : computeStateDisplay( - this.hass!.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + : this.hass.formatEntityState(this.stateObj)} `; diff --git a/src/state-summary/state-card-event.ts b/src/state-summary/state-card-event.ts index 325bc88d69..7ec097a594 100644 --- a/src/state-summary/state-card-event.ts +++ b/src/state-summary/state-card-event.ts @@ -3,10 +3,8 @@ import { css, CSSResultGroup, html, LitElement } from "lit"; import { customElement, property } from "lit/decorators"; import "../components/entity/ha-entity-toggle"; import "../components/entity/state-info"; -import { HomeAssistant } from "../types"; -import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { haStyle } from "../resources/styles"; +import { HomeAssistant } from "../types"; @customElement("state-card-event") export class StateCardEvent extends LitElement { @@ -26,23 +24,10 @@ export class StateCardEvent extends LitElement { >
- ${computeStateDisplay( - this.hass!.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities - )} + ${this.hass.formatEntityState(this.stateObj)}
- ${computeAttributeValueDisplay( - this.hass!.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - "event_type" - )} + ${this.hass.formatEntityAttributeValue(this.stateObj, "event_type")}
diff --git a/src/state-summary/state-card-input_number.ts b/src/state-summary/state-card-input_number.ts index 6deb14392b..0b3d3b822f 100644 --- a/src/state-summary/state-card-input_number.ts +++ b/src/state-summary/state-card-input_number.ts @@ -1,16 +1,15 @@ -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { HassEntity } from "home-assistant-js-websocket"; +import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; import { computeRTLDirection } from "../common/util/compute_rtl"; import { debounce } from "../common/util/debounce"; +import "../components/entity/state-info"; import "../components/ha-slider"; import "../components/ha-textfield"; -import "../components/entity/state-info"; import { isUnavailableState } from "../data/entity"; import { setValue } from "../data/input_text"; -import { HomeAssistant } from "../types"; import { loadPolyfillIfNeeded } from "../resources/resize-observer.polyfill"; +import { HomeAssistant } from "../types"; @customElement("state-card-input_number") class StateCardInputNumber extends LitElement { @@ -69,14 +68,7 @@ class StateCardInputNumber extends LitElement { ignore-bar-touch > - ${computeStateDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - this.stateObj.state - )} + ${this.hass.formatEntityState(this.stateObj)} ` diff --git a/src/state-summary/state-card-select.ts b/src/state-summary/state-card-select.ts index 4e6b48c9dc..72f79d97a9 100644 --- a/src/state-summary/state-card-select.ts +++ b/src/state-summary/state-card-select.ts @@ -1,14 +1,13 @@ import "@material/mwc-list/mwc-list-item"; -import "../components/ha-select"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import { stopPropagation } from "../common/dom/stop_propagation"; import { computeStateName } from "../common/entity/compute_state_name"; import "../components/entity/state-badge"; +import "../components/ha-select"; import { UNAVAILABLE } from "../data/entity"; import { SelectEntity, setSelectOption } from "../data/select"; import type { HomeAssistant } from "../types"; -import { computeStateDisplay } from "../common/entity/compute_state_display"; @customElement("state-card-select") class StateCardSelect extends LitElement { @@ -31,14 +30,7 @@ class StateCardSelect extends LitElement { ${this.stateObj.attributes.options.map( (option) => html` - ${computeStateDisplay( - this.hass.localize, - this.stateObj, - this.hass.locale, - this.hass.config, - this.hass.entities, - option - )} + ${this.hass.formatEntityState(this.stateObj, option)} ` )} From dd8a50af31eeac69d8bccbbaa68dfb389a880629 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 1 Sep 2023 15:45:32 +0200 Subject: [PATCH 10/16] Add state color to preview row (#17778) --- src/dialogs/config-flow/previews/entity-preview-row.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dialogs/config-flow/previews/entity-preview-row.ts b/src/dialogs/config-flow/previews/entity-preview-row.ts index 5d5fa811fa..760366c61a 100644 --- a/src/dialogs/config-flow/previews/entity-preview-row.ts +++ b/src/dialogs/config-flow/previews/entity-preview-row.ts @@ -20,6 +20,7 @@ class EntityPreviewRow extends LitElement { return html`
${computeStateName(stateObj)} From cc5fffc17410af06013bc77a49172c7e021112f5 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 1 Sep 2023 15:54:19 +0200 Subject: [PATCH 11/16] Use state icon for helpers (#17777) --- src/panels/config/helpers/ha-config-helpers.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/panels/config/helpers/ha-config-helpers.ts b/src/panels/config/helpers/ha-config-helpers.ts index 55b9cb1bb7..4443b8b882 100644 --- a/src/panels/config/helpers/ha-config-helpers.ts +++ b/src/panels/config/helpers/ha-config-helpers.ts @@ -1,11 +1,10 @@ -import { mdiPencilOff, mdiPlus } from "@mdi/js"; import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; +import { mdiPencilOff, mdiPlus } from "@mdi/js"; import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket"; -import { html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { LitElement, PropertyValues, TemplateResult, html } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; -import { domainIcon } from "../../../common/entity/domain_icon"; import { navigate } from "../../../common/navigate"; import { LocalizeFunc } from "../../../common/translations/localize"; import { extractSearchParam } from "../../../common/url/search-params"; @@ -15,6 +14,7 @@ import { } from "../../../components/data-table/ha-data-table"; import "../../../components/ha-fab"; import "../../../components/ha-icon"; +import "../../../components/ha-state-icon"; import "../../../components/ha-svg-icon"; import { ConfigEntry, getConfigEntries } from "../../../data/config_entries"; import { getConfigFlowHandlers } from "../../../data/config_flow"; @@ -82,12 +82,8 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { title: "", label: localize("ui.panel.config.helpers.picker.headers.icon"), type: "icon", - template: (icon, helper: any) => - icon - ? html` ` - : html``, + template: (_, helper: any) => + html``, }, name: { title: localize("ui.panel.config.helpers.picker.headers.name"), @@ -176,6 +172,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { ? configEntry.domain : computeStateDomain(entityState), configEntry, + entity: entityState, }; }) ); From be31aecf0040ecdc00eea80ea51490345a869f74 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Fri, 1 Sep 2023 15:54:35 +0200 Subject: [PATCH 12/16] Use right supported features for tilt position in editor (#17779) --- .../editor/config-elements/hui-tile-card-features-editor.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/editor/config-elements/hui-tile-card-features-editor.ts b/src/panels/lovelace/editor/config-elements/hui-tile-card-features-editor.ts index 8f20d3afa0..773eb60f13 100644 --- a/src/panels/lovelace/editor/config-elements/hui-tile-card-features-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-tile-card-features-editor.ts @@ -29,15 +29,16 @@ import { supportsAlarmModesTileFeature } from "../../tile-features/hui-alarm-mod import { supportsClimateHvacModesTileFeature } from "../../tile-features/hui-climate-hvac-modes-tile-feature"; import { supportsCoverOpenCloseTileFeature } from "../../tile-features/hui-cover-open-close-tile-feature"; import { supportsCoverPositionTileFeature } from "../../tile-features/hui-cover-position-tile-feature"; +import { supportsCoverTiltPositionTileFeature } from "../../tile-features/hui-cover-tilt-position-tile-feature"; import { supportsCoverTiltTileFeature } from "../../tile-features/hui-cover-tilt-tile-feature"; import { supportsFanSpeedTileFeature } from "../../tile-features/hui-fan-speed-tile-feature"; import { supportsLawnMowerCommandTileFeature } from "../../tile-features/hui-lawn-mower-commands-tile-feature"; import { supportsLightBrightnessTileFeature } from "../../tile-features/hui-light-brightness-tile-feature"; import { supportsLightColorTempTileFeature } from "../../tile-features/hui-light-color-temp-tile-feature"; +import { supportsTargetTemperatureTileFeature } from "../../tile-features/hui-target-temperature-tile-feature"; import { supportsVacuumCommandTileFeature } from "../../tile-features/hui-vacuum-commands-tile-feature"; import { supportsWaterHeaterOperationModesTileFeature } from "../../tile-features/hui-water-heater-operation-modes-tile-feature"; import { LovelaceTileFeatureConfig } from "../../tile-features/types"; -import { supportsTargetTemperatureTileFeature } from "../../tile-features/hui-target-temperature-tile-feature"; type FeatureType = LovelaceTileFeatureConfig["type"]; type SupportsFeature = (stateObj: HassEntity) => boolean; @@ -72,7 +73,7 @@ const SUPPORTS_FEATURE_TYPES: Record = "climate-hvac-modes": supportsClimateHvacModesTileFeature, "cover-open-close": supportsCoverOpenCloseTileFeature, "cover-position": supportsCoverPositionTileFeature, - "cover-tilt-position": supportsCoverPositionTileFeature, + "cover-tilt-position": supportsCoverTiltPositionTileFeature, "cover-tilt": supportsCoverTiltTileFeature, "fan-speed": supportsFanSpeedTileFeature, "lawn-mower-commands": supportsLawnMowerCommandTileFeature, From 56381f9914b2bebf37122fdf8b9b4475701a12b1 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 1 Sep 2023 16:38:56 +0200 Subject: [PATCH 13/16] Show helper config entries without entities (#17780) --- .../config/helpers/ha-config-helpers.ts | 53 +++++++++++++++---- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/panels/config/helpers/ha-config-helpers.ts b/src/panels/config/helpers/ha-config-helpers.ts index 4443b8b882..4fdd7eafbb 100644 --- a/src/panels/config/helpers/ha-config-helpers.ts +++ b/src/panels/config/helpers/ha-config-helpers.ts @@ -1,5 +1,5 @@ import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; -import { mdiPencilOff, mdiPlus } from "@mdi/js"; +import { mdiAlertCircle, mdiPencilOff, mdiPlus } from "@mdi/js"; import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket"; import { LitElement, PropertyValues, TemplateResult, html } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -37,6 +37,7 @@ import { configSections } from "../ha-panel-config"; import "../integrations/ha-integration-overflow-menu"; import { HelperDomain, isHelperDomain } from "./const"; import { showHelperDetailDialog } from "./show-dialog-helper-detail"; +import { showOptionsFlowDialog } from "../../../dialogs/config-flow/show-dialog-options-flow"; // This groups items by a key but only returns last entry per key. const groupByOne = ( @@ -82,8 +83,13 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { title: "", label: localize("ui.panel.config.helpers.picker.headers.icon"), type: "icon", - template: (_, helper: any) => - html``, + template: (icon, helper: any) => + helper.entity + ? html`` + : html``, }, name: { title: localize("ui.panel.config.helpers.picker.headers.name"), @@ -95,7 +101,7 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { template: (name, item: any) => html` ${name} ${narrow - ? html`
${item.entity_id}
` + ? html`
${item.entity_id}
` : ""} `, }, @@ -153,17 +159,22 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { stateItems: HassEntity[], entityEntries: Record, configEntries: Record - ) => - stateItems.map((entityState) => { + ) => { + const configEntriesCopy = { ...configEntries }; + + const states = stateItems.map((entityState) => { const configEntry = getConfigEntry( entityEntries, configEntries, entityState.entity_id ); + if (configEntry) { + delete configEntriesCopy[configEntry!.entry_id]; + } + return { id: entityState.entity_id, - icon: entityState.attributes.icon, name: entityState.attributes.friendly_name || "", entity_id: entityState.entity_id, editable: @@ -174,7 +185,25 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { configEntry, entity: entityState, }; - }) + }); + + if (!Object.keys(configEntriesCopy).length) { + return states; + } + + const entries = Object.values(configEntriesCopy).map((configEntry) => ({ + id: configEntry.entry_id, + entity_id: "", + icon: mdiAlertCircle, + name: configEntry.title || "", + editable: true, + type: configEntry.domain, + configEntry, + entity: undefined, + })); + + return [...states, ...entries]; + } ); protected render(): TemplateResult { @@ -353,8 +382,12 @@ export class HaConfigHelpers extends SubscribeMixin(LitElement) { } private async _openEditDialog(ev: CustomEvent): Promise { - const entityId = (ev.detail as RowClickedEvent).id; - showMoreInfoDialog(this, { entityId }); + const id = (ev.detail as RowClickedEvent).id; + if (id.includes(".")) { + showMoreInfoDialog(this, { entityId: id }); + } else { + showOptionsFlowDialog(this, this._configEntries![id]); + } } private _createHelpler() { From 53ae7e5a0cde069a84e6f060e831768101855980 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 1 Sep 2023 16:42:30 +0200 Subject: [PATCH 14/16] Bumped version to 20230901.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 72d455d5d1..bdc8363051 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "home-assistant-frontend" -version = "20230831.0" +version = "20230901.0" license = {text = "Apache-2.0"} description = "The Home Assistant frontend" readme = "README.md" From 6dcb7f2273a7606509902333cd5dc0145e9a01d5 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 1 Sep 2023 16:53:14 +0200 Subject: [PATCH 15/16] Hide google translate in onboarding --- src/onboarding/onboarding-integrations.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/onboarding/onboarding-integrations.ts b/src/onboarding/onboarding-integrations.ts index 19c05b2af3..831dcfbfd2 100644 --- a/src/onboarding/onboarding-integrations.ts +++ b/src/onboarding/onboarding-integrations.ts @@ -29,6 +29,7 @@ const HIDDEN_DOMAINS = new Set([ "radio_browser", "rpi_power", "sun", + "google_translate", ]); @customElement("onboarding-integrations") From 5da4e1860ab9d120d8424a6c4269ecb689875331 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 1 Sep 2023 17:02:14 +0200 Subject: [PATCH 16/16] Rename CO2 signal -> Electricity Map --- src/translations/en.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/translations/en.json b/src/translations/en.json index 0a8d9c6ed7..a5e0f99dbc 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1750,8 +1750,8 @@ "delete_return": "Delete return", "add_return": "Add return", "grid_carbon_footprint": "Grid carbon footprint", - "remove_co2_signal": "Remove CO2 signal integration", - "add_co2_signal": "Add CO2 signal integration", + "remove_co2_signal": "Remove Electricity Maps integration", + "add_co2_signal": "Add Electricity Maps integration", "flow_dialog": { "from": { "header": "Configure grid consumption",