Compare commits

...

1 Commits

Author SHA1 Message Date
Petar Petrov
ae6e89c59f Add min/max options to bar gauge feature 2025-11-13 15:29:05 +02:00
5 changed files with 119 additions and 5 deletions

View File

@@ -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<LovelaceCardFeatureEditor> {
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`<div style="width: ${value}%"></div>
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`<div style="width: ${percentage}%"></div>
<div class="bar-gauge-background"></div>`;
}

View File

@@ -226,6 +226,8 @@ export interface AreaControlsCardFeatureConfig {
export interface BarGaugeCardFeatureConfig {
type: "bar-gauge";
min?: number;
max?: number;
}
export type LovelaceCardFeaturePosition = "bottom" | "inline";

View File

@@ -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`
<ha-form
.hass=${this.hass}
.data=${data}
.schema=${schema}
.computeLabel=${this._computeLabelCallback}
@value-changed=${this._valueChanged}
></ha-form>
`;
}
private _valueChanged(ev: CustomEvent): void {
fireEvent(this, "config-changed", { config: ev.detail.value });
}
private _computeLabelCallback = (
schema: SchemaUnion<ReturnType<typeof this._schema>>
) =>
this.hass!.localize(
`ui.panel.lovelace.editor.features.types.bar-gauge.${schema.name}`
);
}
declare global {
interface HTMLElementTagNameMap {
"hui-bar-gauge-card-feature-editor": HuiBarGaugeCardFeatureEditor;
}
}

View File

@@ -123,6 +123,7 @@ type UiFeatureTypes = (typeof UI_FEATURE_TYPES)[number];
const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
"alarm-modes",
"area-controls",
"bar-gauge",
"button",
"climate-fan-modes",
"climate-hvac-modes",

View File

@@ -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"