mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-08 18:39:40 +00:00
Add valve position card feature (#26511)
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { computeCssColor } from "../../../common/color/compute-color";
|
||||
import { computeAttributeNameDisplay } from "../../../common/entity/compute_attribute_display";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { stateActive } from "../../../common/entity/state_active";
|
||||
import { stateColorCss } from "../../../common/entity/state_color";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
import "../../../components/ha-control-slider";
|
||||
import { ValveEntityFeature, type ValveEntity } from "../../../data/valve";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { DOMAIN_ATTRIBUTES_UNITS } from "../../../data/entity_attributes";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { LovelaceCardFeature } from "../types";
|
||||
import { cardFeatureStyles } from "./common/card-feature-styles";
|
||||
import type {
|
||||
ValvePositionCardFeatureConfig,
|
||||
LovelaceCardFeatureContext,
|
||||
} from "./types";
|
||||
|
||||
export const supportsValvePositionCardFeature = (
|
||||
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 === "valve" &&
|
||||
supportsFeature(stateObj, ValveEntityFeature.SET_POSITION)
|
||||
);
|
||||
};
|
||||
|
||||
@customElement("hui-valve-position-card-feature")
|
||||
class HuiValvePositionCardFeature
|
||||
extends LitElement
|
||||
implements LovelaceCardFeature
|
||||
{
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
|
||||
|
||||
@property({ attribute: false }) public color?: string;
|
||||
|
||||
@state() private _config?: ValvePositionCardFeatureConfig;
|
||||
|
||||
private get _stateObj() {
|
||||
if (!this.hass || !this.context || !this.context.entity_id) {
|
||||
return undefined;
|
||||
}
|
||||
return this.hass.states[this.context.entity_id!] as ValveEntity | undefined;
|
||||
}
|
||||
|
||||
static getStubConfig(): ValvePositionCardFeatureConfig {
|
||||
return {
|
||||
type: "valve-position",
|
||||
};
|
||||
}
|
||||
|
||||
public setConfig(config: ValvePositionCardFeatureConfig): void {
|
||||
if (!config) {
|
||||
throw new Error("Invalid configuration");
|
||||
}
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (
|
||||
!this._config ||
|
||||
!this.hass ||
|
||||
!this.context ||
|
||||
!this._stateObj ||
|
||||
!supportsValvePositionCardFeature(this.hass, this.context)
|
||||
) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const percentage = stateActive(this._stateObj)
|
||||
? (this._stateObj.attributes.current_position ?? 0)
|
||||
: 0;
|
||||
|
||||
const value = Math.max(Math.round(percentage), 0);
|
||||
|
||||
const openColor = stateColorCss(this._stateObj, "open");
|
||||
|
||||
const color = this.color
|
||||
? computeCssColor(this.color)
|
||||
: stateColorCss(this._stateObj);
|
||||
|
||||
const style = {
|
||||
"--feature-color": color,
|
||||
// Use open color for inactive state to avoid grey slider that looks disabled
|
||||
"--state-valve-inactive-color": openColor,
|
||||
};
|
||||
|
||||
return html`
|
||||
<ha-control-slider
|
||||
style=${styleMap(style)}
|
||||
.value=${value}
|
||||
min="0"
|
||||
max="100"
|
||||
step="1"
|
||||
inverted
|
||||
show-handle
|
||||
@value-changed=${this._valueChanged}
|
||||
.label=${computeAttributeNameDisplay(
|
||||
this.hass.localize,
|
||||
this._stateObj,
|
||||
this.hass.entities,
|
||||
"current_position"
|
||||
)}
|
||||
.disabled=${this._stateObj!.state === UNAVAILABLE}
|
||||
.unit=${DOMAIN_ATTRIBUTES_UNITS.valve.current_position}
|
||||
.locale=${this.hass.locale}
|
||||
></ha-control-slider>
|
||||
`;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
const value = (ev.detail as any).value;
|
||||
if (isNaN(value)) return;
|
||||
|
||||
this.hass!.callService("valve", "set_valve_position", {
|
||||
entity_id: this._stateObj!.entity_id,
|
||||
position: value,
|
||||
});
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return cardFeatureStyles;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-valve-position-card-feature": HuiValvePositionCardFeature;
|
||||
}
|
||||
}
|
||||
@@ -157,6 +157,10 @@ export interface ValveOpenCloseCardFeatureConfig {
|
||||
type: "valve-open-close";
|
||||
}
|
||||
|
||||
export interface ValvePositionCardFeatureConfig {
|
||||
type: "valve-position";
|
||||
}
|
||||
|
||||
export const LAWN_MOWER_COMMANDS = ["start_pause", "dock"] as const;
|
||||
|
||||
export type LawnMowerCommand = (typeof LAWN_MOWER_COMMANDS)[number];
|
||||
@@ -228,6 +232,7 @@ export type LovelaceCardFeatureConfig =
|
||||
| UpdateActionsCardFeatureConfig
|
||||
| VacuumCommandsCardFeatureConfig
|
||||
| ValveOpenCloseCardFeatureConfig
|
||||
| ValvePositionCardFeatureConfig
|
||||
| WaterHeaterOperationModesCardFeatureConfig
|
||||
| AreaControlsCardFeatureConfig;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import "../card-features/hui-toggle-card-feature";
|
||||
import "../card-features/hui-update-actions-card-feature";
|
||||
import "../card-features/hui-vacuum-commands-card-feature";
|
||||
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";
|
||||
|
||||
@@ -71,6 +72,7 @@ const TYPES = new Set<LovelaceCardFeatureConfig["type"]>([
|
||||
"update-actions",
|
||||
"vacuum-commands",
|
||||
"valve-open-close",
|
||||
"valve-position",
|
||||
"water-heater-operation-modes",
|
||||
]);
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import { supportsToggleCardFeature } from "../../card-features/hui-toggle-card-f
|
||||
import { supportsUpdateActionsCardFeature } from "../../card-features/hui-update-actions-card-feature";
|
||||
import { supportsVacuumCommandsCardFeature } from "../../card-features/hui-vacuum-commands-card-feature";
|
||||
import { supportsValveOpenCloseCardFeature } from "../../card-features/hui-valve-open-close-card-feature";
|
||||
import { supportsValvePositionCardFeature } from "../../card-features/hui-valve-position-card-feature";
|
||||
import { supportsWaterHeaterOperationModesCardFeature } from "../../card-features/hui-water-heater-operation-modes-card-feature";
|
||||
import type {
|
||||
LovelaceCardFeatureConfig,
|
||||
@@ -96,6 +97,7 @@ const UI_FEATURE_TYPES = [
|
||||
"update-actions",
|
||||
"vacuum-commands",
|
||||
"valve-open-close",
|
||||
"valve-position",
|
||||
"water-heater-operation-modes",
|
||||
] as const satisfies readonly FeatureType[];
|
||||
|
||||
@@ -158,6 +160,7 @@ const SUPPORTS_FEATURE_TYPES: Record<
|
||||
"update-actions": supportsUpdateActionsCardFeature,
|
||||
"vacuum-commands": supportsVacuumCommandsCardFeature,
|
||||
"valve-open-close": supportsValveOpenCloseCardFeature,
|
||||
"valve-position": supportsValvePositionCardFeature,
|
||||
"water-heater-operation-modes": supportsWaterHeaterOperationModesCardFeature,
|
||||
};
|
||||
|
||||
|
||||
@@ -7888,6 +7888,9 @@
|
||||
"valve-open-close": {
|
||||
"label": "Valve open/close"
|
||||
},
|
||||
"valve-position": {
|
||||
"label": "Valve position"
|
||||
},
|
||||
"climate-fan-modes": {
|
||||
"label": "Climate fan modes",
|
||||
"style": "[%key:ui::panel::lovelace::editor::features::types::climate-preset-modes::style%]",
|
||||
|
||||
Reference in New Issue
Block a user