Skip to content

Commit 20d0548

Browse files
authored
Add min/max options to bar gauge feature (home-assistant#27933)
1 parent 04aaae2 commit 20d0548

File tree

5 files changed

+115
-5
lines changed

5 files changed

+115
-5
lines changed

src/panels/lovelace/card-features/hui-bar-gauge-card-feature.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { css, LitElement, nothing, html } from "lit";
22
import { customElement, property, state } from "lit/decorators";
33
import { computeDomain } from "../../../common/entity/compute_domain";
4+
import { isNumericFromAttributes } from "../../../common/number/format_number";
45
import type { HomeAssistant } from "../../../types";
5-
import type { LovelaceCardFeature } from "../types";
6+
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
67
import type {
78
LovelaceCardFeatureContext,
89
BarGaugeCardFeatureConfig,
@@ -17,7 +18,7 @@ export const supportsBarGaugeCardFeature = (
1718
: undefined;
1819
if (!stateObj) return false;
1920
const domain = computeDomain(stateObj.entity_id);
20-
return domain === "sensor" && stateObj.attributes.unit_of_measurement === "%";
21+
return domain === "sensor" && isNumericFromAttributes(stateObj.attributes);
2122
};
2223

2324
@customElement("hui-bar-gauge-card-feature")
@@ -34,6 +35,11 @@ class HuiBarGaugeCardFeature extends LitElement implements LovelaceCardFeature {
3435
};
3536
}
3637

38+
public static async getConfigElement(): Promise<LovelaceCardFeatureEditor> {
39+
await import("../editor/config-elements/hui-bar-gauge-card-feature-editor");
40+
return document.createElement("hui-bar-gauge-card-feature-editor");
41+
}
42+
3743
public setConfig(config: BarGaugeCardFeatureConfig): void {
3844
if (!config) {
3945
throw new Error("Invalid configuration");
@@ -53,8 +59,20 @@ class HuiBarGaugeCardFeature extends LitElement implements LovelaceCardFeature {
5359
return nothing;
5460
}
5561
const stateObj = this.hass.states[this.context.entity_id];
56-
const value = stateObj.state;
57-
return html`<div style="width: ${value}%"></div>
62+
const min = this._config.min ?? 0;
63+
const max = this._config.max ?? 100;
64+
const value = parseFloat(stateObj.state);
65+
66+
if (isNaN(value) || min >= max) {
67+
return nothing;
68+
}
69+
70+
const percentage = Math.max(
71+
0,
72+
Math.min(100, ((value - min) / (max - min)) * 100)
73+
);
74+
75+
return html`<div style="width: ${percentage}%"></div>
5876
<div class="bar-gauge-background"></div>`;
5977
}
6078

src/panels/lovelace/card-features/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ export interface AreaControlsCardFeatureConfig {
226226

227227
export interface BarGaugeCardFeatureConfig {
228228
type: "bar-gauge";
229+
min?: number;
230+
max?: number;
229231
}
230232

231233
export type LovelaceCardFeaturePosition = "bottom" | "inline";
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { html, LitElement, nothing } from "lit";
2+
import { customElement, property, state } from "lit/decorators";
3+
import memoizeOne from "memoize-one";
4+
import { fireEvent } from "../../../../common/dom/fire_event";
5+
import "../../../../components/ha-form/ha-form";
6+
import type { SchemaUnion } from "../../../../components/ha-form/types";
7+
import type { HomeAssistant } from "../../../../types";
8+
import type {
9+
BarGaugeCardFeatureConfig,
10+
LovelaceCardFeatureContext,
11+
} from "../../card-features/types";
12+
import type { LovelaceCardFeatureEditor } from "../../types";
13+
14+
@customElement("hui-bar-gauge-card-feature-editor")
15+
export class HuiBarGaugeCardFeatureEditor
16+
extends LitElement
17+
implements LovelaceCardFeatureEditor
18+
{
19+
@property({ attribute: false }) public hass?: HomeAssistant;
20+
21+
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
22+
23+
@state() private _config?: BarGaugeCardFeatureConfig;
24+
25+
public setConfig(config: BarGaugeCardFeatureConfig): void {
26+
this._config = config;
27+
}
28+
29+
private _schema = memoizeOne(
30+
() =>
31+
[
32+
{
33+
name: "min",
34+
default: 0,
35+
selector: {
36+
number: {
37+
mode: "box",
38+
},
39+
},
40+
},
41+
{
42+
name: "max",
43+
default: 100,
44+
selector: {
45+
number: {
46+
mode: "box",
47+
},
48+
},
49+
},
50+
] as const
51+
);
52+
53+
protected render() {
54+
if (!this.hass || !this._config) {
55+
return nothing;
56+
}
57+
58+
const schema = this._schema();
59+
60+
return html`
61+
<ha-form
62+
.hass=${this.hass}
63+
.data=${this._config}
64+
.schema=${schema}
65+
.computeLabel=${this._computeLabelCallback}
66+
@value-changed=${this._valueChanged}
67+
></ha-form>
68+
`;
69+
}
70+
71+
private _valueChanged(ev: CustomEvent): void {
72+
fireEvent(this, "config-changed", { config: ev.detail.value });
73+
}
74+
75+
private _computeLabelCallback = (
76+
schema: SchemaUnion<ReturnType<typeof this._schema>>
77+
) =>
78+
this.hass!.localize(
79+
`ui.panel.lovelace.editor.features.types.bar-gauge.${schema.name}`
80+
);
81+
}
82+
83+
declare global {
84+
interface HTMLElementTagNameMap {
85+
"hui-bar-gauge-card-feature-editor": HuiBarGaugeCardFeatureEditor;
86+
}
87+
}

src/panels/lovelace/editor/config-elements/hui-card-features-editor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ type UiFeatureTypes = (typeof UI_FEATURE_TYPES)[number];
123123
const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
124124
"alarm-modes",
125125
"area-controls",
126+
"bar-gauge",
126127
"button",
127128
"climate-fan-modes",
128129
"climate-hvac-modes",

src/translations/en.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8424,7 +8424,9 @@
84248424
"no_compatible_controls": "No compatible controls available for this area"
84258425
},
84268426
"bar-gauge": {
8427-
"label": "Bar gauge"
8427+
"label": "Bar gauge",
8428+
"min": "Minimum value",
8429+
"max": "Maximum value"
84288430
},
84298431
"trend-graph": {
84308432
"label": "Trend graph"

0 commit comments

Comments
 (0)