diff --git a/src/panels/lovelace/card-features/hui-bar-gauge-card-feature.ts b/src/panels/lovelace/card-features/hui-bar-gauge-card-feature.ts new file mode 100644 index 0000000000..a8f523ef67 --- /dev/null +++ b/src/panels/lovelace/card-features/hui-bar-gauge-card-feature.ts @@ -0,0 +1,85 @@ +import { css, LitElement, nothing, html } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { computeDomain } from "../../../common/entity/compute_domain"; +import type { HomeAssistant } from "../../../types"; +import type { LovelaceCardFeature } from "../types"; +import type { + LovelaceCardFeatureContext, + BarGaugeCardFeatureConfig, +} from "./types"; + +export const supportsBarGaugeCardFeature = ( + hass: HomeAssistant, + context: LovelaceCardFeatureContext +) => { + const stateObj = context.entity_id + ? hass.states[context.entity_id] + : undefined; + if (!stateObj) return false; + const domain = computeDomain(stateObj.entity_id); + return domain === "sensor" && stateObj.attributes.unit_of_measurement === "%"; +}; + +@customElement("hui-bar-gauge-card-feature") +class HuiBarGaugeCardFeature extends LitElement implements LovelaceCardFeature { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public context!: LovelaceCardFeatureContext; + + @state() private _config?: BarGaugeCardFeatureConfig; + + static getStubConfig(): BarGaugeCardFeatureConfig { + return { + type: "bar-gauge", + }; + } + + public setConfig(config: BarGaugeCardFeatureConfig): void { + if (!config) { + throw new Error("Invalid configuration"); + } + this._config = config; + } + + render() { + if ( + !this._config || + !this.hass || + !this.context || + !this.context.entity_id || + !this.hass.states[this.context.entity_id] || + !supportsBarGaugeCardFeature(this.hass, this.context) + ) { + return nothing; + } + const stateObj = this.hass.states[this.context.entity_id]; + const value = stateObj.state; + return html`
+ `; + } + + static styles = css` + :host { + display: flex; + width: 100%; + height: var(--feature-height); + border-radius: var(--feature-border-radius); + overflow: hidden; + } + :host > div { + height: 100%; + background-color: var(--feature-color); + transition: width 180ms ease-in-out; + } + .bar-gauge-background { + flex: 1; + opacity: 0.2; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "hui-bar-gauge-card-feature": HuiBarGaugeCardFeature; + } +} diff --git a/src/panels/lovelace/card-features/types.ts b/src/panels/lovelace/card-features/types.ts index 966346b813..fcb0b00190 100644 --- a/src/panels/lovelace/card-features/types.ts +++ b/src/panels/lovelace/card-features/types.ts @@ -211,6 +211,10 @@ export interface AreaControlsCardFeatureConfig { controls?: AreaControl[]; } +export interface BarGaugeCardFeatureConfig { + type: "bar-gauge"; +} + export type LovelaceCardFeaturePosition = "bottom" | "inline"; export type LovelaceCardFeatureConfig = @@ -250,7 +254,8 @@ export type LovelaceCardFeatureConfig = | ValveOpenCloseCardFeatureConfig | ValvePositionCardFeatureConfig | WaterHeaterOperationModesCardFeatureConfig - | AreaControlsCardFeatureConfig; + | AreaControlsCardFeatureConfig + | BarGaugeCardFeatureConfig; export interface LovelaceCardFeatureContext { entity_id?: string; diff --git a/src/panels/lovelace/create-element/create-card-feature-element.ts b/src/panels/lovelace/create-element/create-card-feature-element.ts index f8b3f44ac8..ebee9dded8 100644 --- a/src/panels/lovelace/create-element/create-card-feature-element.ts +++ b/src/panels/lovelace/create-element/create-card-feature-element.ts @@ -34,6 +34,7 @@ import "../card-features/hui-valve-open-close-card-feature"; import "../card-features/hui-valve-position-card-feature"; import "../card-features/hui-water-heater-operation-modes-card-feature"; import "../card-features/hui-area-controls-card-feature"; +import "../card-features/hui-bar-gauge-card-feature"; import "../card-features/hui-history-chart-card-feature"; import type { LovelaceCardFeatureConfig } from "../card-features/types"; @@ -44,8 +45,9 @@ import { const TYPES = new Set