From ae6e89c59f6cb55d83f61a23c7f5a3a23821875f Mon Sep 17 00:00:00 2001 From: Petar Petrov Date: Thu, 13 Nov 2025 15:29:05 +0200 Subject: [PATCH] Add min/max options to bar gauge feature --- .../hui-bar-gauge-card-feature.ts | 26 +++++- src/panels/lovelace/card-features/types.ts | 2 + .../hui-bar-gauge-card-feature-editor.ts | 91 +++++++++++++++++++ .../hui-card-features-editor.ts | 1 + src/translations/en.json | 4 +- 5 files changed, 119 insertions(+), 5 deletions(-) create mode 100644 src/panels/lovelace/editor/config-elements/hui-bar-gauge-card-feature-editor.ts 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 index a8f523ef67..c403be89cb 100644 --- a/src/panels/lovelace/card-features/hui-bar-gauge-card-feature.ts +++ b/src/panels/lovelace/card-features/hui-bar-gauge-card-feature.ts @@ -1,8 +1,9 @@ import { css, LitElement, nothing, html } from "lit"; import { customElement, property, state } from "lit/decorators"; import { computeDomain } from "../../../common/entity/compute_domain"; +import { isNumericFromAttributes } from "../../../common/number/format_number"; import type { HomeAssistant } from "../../../types"; -import type { LovelaceCardFeature } from "../types"; +import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types"; import type { LovelaceCardFeatureContext, BarGaugeCardFeatureConfig, @@ -17,7 +18,7 @@ export const supportsBarGaugeCardFeature = ( : undefined; if (!stateObj) return false; const domain = computeDomain(stateObj.entity_id); - return domain === "sensor" && stateObj.attributes.unit_of_measurement === "%"; + return domain === "sensor" && isNumericFromAttributes(stateObj.attributes); }; @customElement("hui-bar-gauge-card-feature") @@ -34,6 +35,11 @@ class HuiBarGaugeCardFeature extends LitElement implements LovelaceCardFeature { }; } + public static async getConfigElement(): Promise { + await import("../editor/config-elements/hui-bar-gauge-card-feature-editor"); + return document.createElement("hui-bar-gauge-card-feature-editor"); + } + public setConfig(config: BarGaugeCardFeatureConfig): void { if (!config) { throw new Error("Invalid configuration"); @@ -53,8 +59,20 @@ class HuiBarGaugeCardFeature extends LitElement implements LovelaceCardFeature { return nothing; } const stateObj = this.hass.states[this.context.entity_id]; - const value = stateObj.state; - return html`
+ const min = this._config.min ?? 0; + const max = this._config.max ?? 100; + const value = parseFloat(stateObj.state); + + if (isNaN(value) || min >= max) { + return nothing; + } + + const percentage = Math.max( + 0, + Math.min(100, ((value - min) / (max - min)) * 100) + ); + + return html`
`; } diff --git a/src/panels/lovelace/card-features/types.ts b/src/panels/lovelace/card-features/types.ts index 2690226af7..b61372468d 100644 --- a/src/panels/lovelace/card-features/types.ts +++ b/src/panels/lovelace/card-features/types.ts @@ -226,6 +226,8 @@ export interface AreaControlsCardFeatureConfig { export interface BarGaugeCardFeatureConfig { type: "bar-gauge"; + min?: number; + max?: number; } export type LovelaceCardFeaturePosition = "bottom" | "inline"; diff --git a/src/panels/lovelace/editor/config-elements/hui-bar-gauge-card-feature-editor.ts b/src/panels/lovelace/editor/config-elements/hui-bar-gauge-card-feature-editor.ts new file mode 100644 index 0000000000..f505d98d07 --- /dev/null +++ b/src/panels/lovelace/editor/config-elements/hui-bar-gauge-card-feature-editor.ts @@ -0,0 +1,91 @@ +import { html, LitElement, nothing } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import memoizeOne from "memoize-one"; +import { fireEvent } from "../../../../common/dom/fire_event"; +import "../../../../components/ha-form/ha-form"; +import type { SchemaUnion } from "../../../../components/ha-form/types"; +import type { HomeAssistant } from "../../../../types"; +import type { + BarGaugeCardFeatureConfig, + LovelaceCardFeatureContext, +} from "../../card-features/types"; +import type { LovelaceCardFeatureEditor } from "../../types"; + +@customElement("hui-bar-gauge-card-feature-editor") +export class HuiBarGaugeCardFeatureEditor + extends LitElement + implements LovelaceCardFeatureEditor +{ + @property({ attribute: false }) public hass?: HomeAssistant; + + @property({ attribute: false }) public context?: LovelaceCardFeatureContext; + + @state() private _config?: BarGaugeCardFeatureConfig; + + public setConfig(config: BarGaugeCardFeatureConfig): void { + this._config = config; + } + + private _schema = memoizeOne( + () => + [ + { + name: "min", + selector: { + number: { + mode: "box", + }, + }, + }, + { + name: "max", + selector: { + number: { + mode: "box", + }, + }, + }, + ] as const + ); + + protected render() { + if (!this.hass || !this._config) { + return nothing; + } + + const data: BarGaugeCardFeatureConfig = { + type: "bar-gauge", + min: this._config.min ?? 0, + max: this._config.max ?? 100, + }; + + const schema = this._schema(); + + return html` + + `; + } + + private _valueChanged(ev: CustomEvent): void { + fireEvent(this, "config-changed", { config: ev.detail.value }); + } + + private _computeLabelCallback = ( + schema: SchemaUnion> + ) => + this.hass!.localize( + `ui.panel.lovelace.editor.features.types.bar-gauge.${schema.name}` + ); +} + +declare global { + interface HTMLElementTagNameMap { + "hui-bar-gauge-card-feature-editor": HuiBarGaugeCardFeatureEditor; + } +} diff --git a/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts b/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts index 1ed004b76f..4d149bf9cb 100644 --- a/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts @@ -123,6 +123,7 @@ type UiFeatureTypes = (typeof UI_FEATURE_TYPES)[number]; const EDITABLES_FEATURE_TYPES = new Set([ "alarm-modes", "area-controls", + "bar-gauge", "button", "climate-fan-modes", "climate-hvac-modes", diff --git a/src/translations/en.json b/src/translations/en.json index 1cb1169c1e..390f7ccba1 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -8417,7 +8417,9 @@ "no_compatible_controls": "No compatible controls available for this area" }, "bar-gauge": { - "label": "Bar gauge" + "label": "Bar gauge", + "min": "Minimum value", + "max": "Maximum value" }, "trend-graph": { "label": "Trend graph"