mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-15 14:00:38 +00:00
Add min/max options to bar gauge feature
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
import { css, LitElement, nothing, html } from "lit";
|
import { css, LitElement, nothing, html } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
|
import { isNumericFromAttributes } from "../../../common/number/format_number";
|
||||||
import type { HomeAssistant } from "../../../types";
|
import type { HomeAssistant } from "../../../types";
|
||||||
import type { LovelaceCardFeature } from "../types";
|
import type { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
|
||||||
import type {
|
import type {
|
||||||
LovelaceCardFeatureContext,
|
LovelaceCardFeatureContext,
|
||||||
BarGaugeCardFeatureConfig,
|
BarGaugeCardFeatureConfig,
|
||||||
@@ -17,7 +18,7 @@ export const supportsBarGaugeCardFeature = (
|
|||||||
: undefined;
|
: undefined;
|
||||||
if (!stateObj) return false;
|
if (!stateObj) return false;
|
||||||
const domain = computeDomain(stateObj.entity_id);
|
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")
|
@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 {
|
public setConfig(config: BarGaugeCardFeatureConfig): void {
|
||||||
if (!config) {
|
if (!config) {
|
||||||
throw new Error("Invalid configuration");
|
throw new Error("Invalid configuration");
|
||||||
@@ -53,8 +59,20 @@ class HuiBarGaugeCardFeature extends LitElement implements LovelaceCardFeature {
|
|||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
const stateObj = this.hass.states[this.context.entity_id];
|
const stateObj = this.hass.states[this.context.entity_id];
|
||||||
const value = stateObj.state;
|
const min = this._config.min ?? 0;
|
||||||
return html`<div style="width: ${value}%"></div>
|
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>`;
|
<div class="bar-gauge-background"></div>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -226,6 +226,8 @@ export interface AreaControlsCardFeatureConfig {
|
|||||||
|
|
||||||
export interface BarGaugeCardFeatureConfig {
|
export interface BarGaugeCardFeatureConfig {
|
||||||
type: "bar-gauge";
|
type: "bar-gauge";
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LovelaceCardFeaturePosition = "bottom" | "inline";
|
export type LovelaceCardFeaturePosition = "bottom" | "inline";
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -123,6 +123,7 @@ type UiFeatureTypes = (typeof UI_FEATURE_TYPES)[number];
|
|||||||
const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
|
const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
|
||||||
"alarm-modes",
|
"alarm-modes",
|
||||||
"area-controls",
|
"area-controls",
|
||||||
|
"bar-gauge",
|
||||||
"button",
|
"button",
|
||||||
"climate-fan-modes",
|
"climate-fan-modes",
|
||||||
"climate-hvac-modes",
|
"climate-hvac-modes",
|
||||||
|
|||||||
@@ -8417,7 +8417,9 @@
|
|||||||
"no_compatible_controls": "No compatible controls available for this area"
|
"no_compatible_controls": "No compatible controls available for this area"
|
||||||
},
|
},
|
||||||
"bar-gauge": {
|
"bar-gauge": {
|
||||||
"label": "Bar gauge"
|
"label": "Bar gauge",
|
||||||
|
"min": "Minimum value",
|
||||||
|
"max": "Maximum value"
|
||||||
},
|
},
|
||||||
"trend-graph": {
|
"trend-graph": {
|
||||||
"label": "Trend graph"
|
"label": "Trend graph"
|
||||||
|
|||||||
Reference in New Issue
Block a user