mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add new design to humidifier card (#18711)
This commit is contained in:
parent
61717e1529
commit
9163b9c124
@ -1,4 +1,3 @@
|
|||||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
|
||||||
import { mdiMinus, mdiPlus, mdiWaterPercent } from "@mdi/js";
|
import { mdiMinus, mdiPlus, mdiWaterPercent } from "@mdi/js";
|
||||||
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit";
|
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
@ -93,7 +93,6 @@ export const moreInfoControlCircularSliderStyle = css`
|
|||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
.info {
|
.info {
|
||||||
margin-top: 12px;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
--mdc-icon-size: 14px;
|
--mdc-icon-size: 14px;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { mdiMinus, mdiPlus } from "@mdi/js";
|
import { mdiMinus, mdiPlus, mdiWaterPercent } from "@mdi/js";
|
||||||
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit";
|
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
@ -100,13 +100,9 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<p class="label">
|
<p class="label">
|
||||||
${action && ["drying", "humidifying"].includes(action)
|
${action && action !== "off" && action !== "idle"
|
||||||
? this.hass.localize("ui.card.humidifier.target_label", {
|
? actionLabel
|
||||||
action: actionLabel,
|
: this.hass.localize("ui.card.humidifier.target")}
|
||||||
})
|
|
||||||
: action && action !== "off" && action !== "idle"
|
|
||||||
? actionLabel
|
|
||||||
: this.hass.localize("ui.card.humidifier.target")}
|
|
||||||
</p>
|
</p>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -118,7 +114,7 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<p class="label">
|
<p class="label">
|
||||||
${this.hass.localize("ui.card.humidifier.currently")}
|
<ha-svg-icon .path=${mdiWaterPercent}></ha-svg-icon>
|
||||||
<span>
|
<span>
|
||||||
${this.hass.formatEntityAttributeValue(
|
${this.hass.formatEntityAttributeValue(
|
||||||
this.stateObj,
|
this.stateObj,
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { mdiDotsVertical, mdiPower, mdiWaterPercent } from "@mdi/js";
|
import { mdiDotsVertical } from "@mdi/js";
|
||||||
import "@thomasloven/round-slider";
|
|
||||||
import { HassEntity } from "home-assistant-js-websocket";
|
|
||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
LitElement,
|
LitElement,
|
||||||
@ -8,26 +6,19 @@ import {
|
|||||||
css,
|
css,
|
||||||
html,
|
html,
|
||||||
nothing,
|
nothing,
|
||||||
svg,
|
|
||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
|
||||||
import { styleMap } from "lit/directives/style-map";
|
|
||||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
import { stateColorCss } from "../../../common/entity/state_color";
|
|
||||||
import { formatNumber } from "../../../common/number/format_number";
|
|
||||||
import { computeRTLDirection } from "../../../common/util/compute_rtl";
|
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import type { HaCard } from "../../../components/ha-card";
|
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
import { UNAVAILABLE, isUnavailableState } from "../../../data/entity";
|
|
||||||
import { HumidifierEntity } from "../../../data/humidifier";
|
import { HumidifierEntity } from "../../../data/humidifier";
|
||||||
|
import "../../../dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { findEntities } from "../common/find-entities";
|
import { findEntities } from "../common/find-entities";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
|
||||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||||
|
import "../tile-features/hui-tile-features";
|
||||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||||
import { HumidifierCardConfig } from "./types";
|
import { HumidifierCardConfig } from "./types";
|
||||||
|
|
||||||
@ -53,17 +44,21 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
|||||||
includeDomains
|
includeDomains
|
||||||
);
|
);
|
||||||
|
|
||||||
return { type: "humidifier", entity: foundEntities[0] || "" };
|
return {
|
||||||
|
type: "humidifier",
|
||||||
|
entity: foundEntities[0] || "",
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
type: "humidifier-modes",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
@state() private _config?: HumidifierCardConfig;
|
@state() private _config?: HumidifierCardConfig;
|
||||||
|
|
||||||
@state() private _setHum?: number;
|
|
||||||
|
|
||||||
@query("ha-card") private _card?: HaCard;
|
|
||||||
|
|
||||||
public getCardSize(): number {
|
public getCardSize(): number {
|
||||||
return 7;
|
return 7;
|
||||||
}
|
}
|
||||||
@ -76,168 +71,10 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
|||||||
this._config = config;
|
this._config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
private _handleMoreInfo() {
|
||||||
if (!this.hass || !this._config) {
|
fireEvent(this, "hass-more-info", {
|
||||||
return nothing;
|
entityId: this._config!.entity,
|
||||||
}
|
});
|
||||||
const stateObj = this.hass.states[this._config.entity] as HumidifierEntity;
|
|
||||||
|
|
||||||
if (!stateObj) {
|
|
||||||
return html`
|
|
||||||
<hui-warning>
|
|
||||||
${createEntityNotFoundWarning(this.hass, this._config.entity)}
|
|
||||||
</hui-warning>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const name =
|
|
||||||
this._config!.name ||
|
|
||||||
computeStateName(this.hass!.states[this._config!.entity]);
|
|
||||||
|
|
||||||
const targetHumidity =
|
|
||||||
stateObj.attributes.humidity !== null &&
|
|
||||||
Number.isFinite(Number(stateObj.attributes.humidity))
|
|
||||||
? stateObj.attributes.humidity
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const setHumidity = this._setHum ? this._setHum : targetHumidity;
|
|
||||||
|
|
||||||
const rtlDirection = computeRTLDirection(this.hass);
|
|
||||||
|
|
||||||
const slider = isUnavailableState(stateObj.state)
|
|
||||||
? html` <round-slider disabled="true"></round-slider> `
|
|
||||||
: html`
|
|
||||||
<round-slider
|
|
||||||
.value=${targetHumidity}
|
|
||||||
.disabled=${targetHumidity === null}
|
|
||||||
.min=${stateObj.attributes.min_humidity}
|
|
||||||
.max=${stateObj.attributes.max_humidity}
|
|
||||||
.rtl=${rtlDirection === "rtl"}
|
|
||||||
step="1"
|
|
||||||
@value-changing=${this._dragEvent}
|
|
||||||
@value-changed=${this._setHumidity}
|
|
||||||
></round-slider>
|
|
||||||
`;
|
|
||||||
|
|
||||||
const currentHumidity = svg`
|
|
||||||
<svg viewBox="0 0 40 20">
|
|
||||||
<text
|
|
||||||
x="50%"
|
|
||||||
dx="1"
|
|
||||||
y="60%"
|
|
||||||
text-anchor="middle"
|
|
||||||
style="font-size: 13px;"
|
|
||||||
>
|
|
||||||
${
|
|
||||||
stateObj.state !== UNAVAILABLE &&
|
|
||||||
stateObj.attributes.current_humidity != null &&
|
|
||||||
!isNaN(stateObj.attributes.current_humidity)
|
|
||||||
? svg`
|
|
||||||
${formatNumber(
|
|
||||||
stateObj.attributes.current_humidity,
|
|
||||||
this.hass.locale
|
|
||||||
)}
|
|
||||||
<tspan dx="-3" dy="-6.5" style="font-size: 4px;">
|
|
||||||
%
|
|
||||||
</tspan>
|
|
||||||
`
|
|
||||||
: nothing
|
|
||||||
}
|
|
||||||
</text>
|
|
||||||
</svg>
|
|
||||||
`;
|
|
||||||
|
|
||||||
const setValues = svg`
|
|
||||||
<svg id="set-values">
|
|
||||||
<g>
|
|
||||||
<text text-anchor="middle" class="set-value">
|
|
||||||
${
|
|
||||||
stateObj.state !== UNAVAILABLE && setHumidity != null
|
|
||||||
? formatNumber(setHumidity, this.hass.locale, {
|
|
||||||
maximumFractionDigits: 0,
|
|
||||||
})
|
|
||||||
: nothing
|
|
||||||
}
|
|
||||||
</text>
|
|
||||||
<text
|
|
||||||
dy="22"
|
|
||||||
text-anchor="middle"
|
|
||||||
id="set-mode"
|
|
||||||
>
|
|
||||||
${
|
|
||||||
stateObj.attributes.action
|
|
||||||
? this.hass.formatEntityAttributeValue(stateObj, "action")
|
|
||||||
: this.hass.formatEntityState(stateObj)
|
|
||||||
}
|
|
||||||
${
|
|
||||||
stateObj.state !== UNAVAILABLE && stateObj.attributes.mode
|
|
||||||
? html`
|
|
||||||
- ${this.hass.formatEntityAttributeValue(stateObj, "mode")}
|
|
||||||
`
|
|
||||||
: nothing
|
|
||||||
}
|
|
||||||
</text>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
`;
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<ha-card
|
|
||||||
style=${styleMap({
|
|
||||||
"--mode-color": stateColorCss(stateObj),
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<ha-icon-button
|
|
||||||
.path=${mdiDotsVertical}
|
|
||||||
.label=${this.hass!.localize(
|
|
||||||
"ui.panel.lovelace.cards.show_more_info"
|
|
||||||
)}
|
|
||||||
class="more-info"
|
|
||||||
@click=${this._handleMoreInfo}
|
|
||||||
tabindex="0"
|
|
||||||
></ha-icon-button>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
<div id="controls">
|
|
||||||
<div id="slider">
|
|
||||||
${slider}
|
|
||||||
<div id="slider-center">
|
|
||||||
<div id="humidity">${currentHumidity} ${setValues}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="info" .title=${name}>
|
|
||||||
<div id="modes">
|
|
||||||
<ha-icon-button
|
|
||||||
class=${classMap({ "selected-icon": stateObj.state === "on" })}
|
|
||||||
@click=${this._turnOn}
|
|
||||||
tabindex="0"
|
|
||||||
.path=${mdiWaterPercent}
|
|
||||||
.label=${this.hass!.localize(
|
|
||||||
`component.humidifier.entity_component._.state.on`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
</ha-icon-button>
|
|
||||||
<ha-icon-button
|
|
||||||
class=${classMap({ "selected-icon": stateObj.state === "off" })}
|
|
||||||
@click=${this._turnOff}
|
|
||||||
tabindex="0"
|
|
||||||
.path=${mdiPower}
|
|
||||||
.label=${this.hass!.localize(
|
|
||||||
`component.humidifier.entity_component._.state.off`
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
</ha-icon-button>
|
|
||||||
</div>
|
|
||||||
${name}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
|
||||||
return hasConfigOrEntityChanged(this, changedProps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues): void {
|
protected updated(changedProps: PropertyValues): void {
|
||||||
@ -264,90 +101,49 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
|||||||
) {
|
) {
|
||||||
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.hass || !this._config) {
|
||||||
|
return nothing;
|
||||||
|
}
|
||||||
|
const stateObj = this.hass.states[this._config.entity] as HumidifierEntity;
|
||||||
|
|
||||||
const stateObj = this.hass.states[this._config.entity];
|
|
||||||
if (!stateObj) {
|
if (!stateObj) {
|
||||||
return;
|
return html`
|
||||||
|
<hui-warning>
|
||||||
|
${createEntityNotFoundWarning(this.hass, this._config.entity)}
|
||||||
|
</hui-warning>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!oldHass || oldHass.states[this._config.entity] !== stateObj) {
|
const name = this._config!.name || computeStateName(stateObj);
|
||||||
this._rescale_svg();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public willUpdate(changedProps: PropertyValues) {
|
return html`
|
||||||
if (!this.hass || !this._config || !changedProps.has("hass")) {
|
<ha-card>
|
||||||
return;
|
<p class="title">${name}</p>
|
||||||
}
|
<ha-more-info-humidifier-humidity
|
||||||
|
show-current
|
||||||
const stateObj = this.hass.states[this._config.entity];
|
.hass=${this.hass}
|
||||||
if (!stateObj) {
|
.stateObj=${stateObj}
|
||||||
return;
|
></ha-more-info-humidifier-humidity>
|
||||||
}
|
<ha-icon-button
|
||||||
|
class="more-info"
|
||||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.lovelace.cards.show_more_info"
|
||||||
if (!oldHass || oldHass.states[this._config.entity] !== stateObj) {
|
)}
|
||||||
this._setHum = this._getSetHum(stateObj);
|
.path=${mdiDotsVertical}
|
||||||
}
|
@click=${this._handleMoreInfo}
|
||||||
}
|
tabindex="0"
|
||||||
|
></ha-icon-button>
|
||||||
private _rescale_svg() {
|
<hui-tile-features
|
||||||
// Set the viewbox of the SVG containing the set temperature to perfectly
|
.hass=${this.hass}
|
||||||
// fit the text
|
.stateObj=${stateObj}
|
||||||
// That way it will auto-scale correctly
|
.color=${this._config.color}
|
||||||
// This is not done to the SVG containing the current temperature, because
|
.features=${this._config.features}
|
||||||
// it should not be centered on the text, but only on the value
|
></hui-tile-features>
|
||||||
const card = this._card;
|
</ha-card>
|
||||||
if (card) {
|
`;
|
||||||
card.updateComplete.then(() => {
|
|
||||||
const svgRoot = this.shadowRoot!.querySelector("#set-values")!;
|
|
||||||
const box = svgRoot.querySelector("g")!.getBBox()!;
|
|
||||||
svgRoot.setAttribute(
|
|
||||||
"viewBox",
|
|
||||||
`${box.x} ${box!.y} ${box.width} ${box.height}`
|
|
||||||
);
|
|
||||||
svgRoot.setAttribute("width", `${box.width}`);
|
|
||||||
svgRoot.setAttribute("height", `${box.height}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getSetHum(stateObj: HassEntity): undefined | number {
|
|
||||||
if (isUnavailableState(stateObj.state)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stateObj.attributes.humidity;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _dragEvent(e): void {
|
|
||||||
this._setHum = e.detail.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _setHumidity(e): void {
|
|
||||||
this.hass!.callService("humidifier", "set_humidity", {
|
|
||||||
entity_id: this._config!.entity,
|
|
||||||
humidity: e.detail.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private _turnOn(): void {
|
|
||||||
this.hass!.callService("humidifier", "turn_on", {
|
|
||||||
entity_id: this._config!.entity,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private _turnOff(): void {
|
|
||||||
this.hass!.callService("humidifier", "turn_off", {
|
|
||||||
entity_id: this._config!.entity,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleMoreInfo() {
|
|
||||||
fireEvent(this, "hass-more-info", {
|
|
||||||
entityId: this._config!.entity,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
@ -360,10 +156,27 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
--name-font-size: 1.2rem;
|
padding: 0;
|
||||||
--brightness-font-size: 1.2rem;
|
display: flex;
|
||||||
--rail-border-color: transparent;
|
flex-direction: column;
|
||||||
--mode-color: var(--state-inactive-color);
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 12px 36px 16px 36px;
|
||||||
|
margin: 0;
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-more-info-humidifier-humidity {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 344px; /* 12px + 12px + 320px */
|
||||||
|
padding: 0 12px 12px 12px;
|
||||||
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-info {
|
.more-info {
|
||||||
@ -375,93 +188,11 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
|||||||
inset-inline-start: initial;
|
inset-inline-start: initial;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
z-index: 1;
|
|
||||||
direction: var(--direction);
|
direction: var(--direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
hui-tile-features {
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#controls {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 16px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#slider {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
|
||||||
max-width: 250px;
|
|
||||||
min-width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
round-slider {
|
|
||||||
--round-slider-path-color: var(--slider-track-color);
|
|
||||||
--round-slider-bar-color: var(--mode-color);
|
|
||||||
padding-bottom: 10%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#slider-center {
|
|
||||||
position: absolute;
|
|
||||||
width: calc(100% - 40px);
|
|
||||||
height: calc(100% - 40px);
|
|
||||||
box-sizing: border-box;
|
|
||||||
border-radius: 100%;
|
|
||||||
left: 20px;
|
|
||||||
top: 20px;
|
|
||||||
text-align: center;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#humidity {
|
|
||||||
position: absolute;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
width: 100%;
|
|
||||||
height: 50%;
|
|
||||||
top: 45%;
|
|
||||||
left: 50%;
|
|
||||||
direction: ltr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#set-values {
|
|
||||||
max-width: 80%;
|
|
||||||
transform: translate(0, -50%);
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#set-mode {
|
|
||||||
fill: var(--secondary-text-color);
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#info {
|
|
||||||
display: flex-vertical;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
padding: 16px;
|
|
||||||
margin-top: -60px;
|
|
||||||
font-size: var(--name-font-size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#modes > * {
|
|
||||||
color: var(--disabled-text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#modes .selected-icon {
|
|
||||||
color: var(--mode-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
text {
|
|
||||||
fill: var(--primary-text-color);
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { mdiDotsVertical } from "@mdi/js";
|
import { mdiDotsVertical } from "@mdi/js";
|
||||||
import "@thomasloven/round-slider";
|
|
||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
LitElement,
|
LitElement,
|
||||||
|
@ -262,6 +262,7 @@ export interface HumidifierCardConfig extends LovelaceCardConfig {
|
|||||||
entity: string;
|
entity: string;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
features?: LovelaceTileFeatureConfig[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IframeCardConfig extends LovelaceCardConfig {
|
export interface IframeCardConfig extends LovelaceCardConfig {
|
||||||
|
@ -153,6 +153,11 @@ export const computeCards = (
|
|||||||
const cardConfig: HumidifierCardConfig = {
|
const cardConfig: HumidifierCardConfig = {
|
||||||
type: "humidifier",
|
type: "humidifier",
|
||||||
entity: entityId,
|
entity: entityId,
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
type: "humidifier-modes",
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
cards.push(cardConfig);
|
cards.push(cardConfig);
|
||||||
} else if (domain === "media_player") {
|
} else if (domain === "media_player") {
|
||||||
|
@ -6,14 +6,15 @@ import "../tile-features/hui-cover-position-tile-feature";
|
|||||||
import "../tile-features/hui-cover-tilt-position-tile-feature";
|
import "../tile-features/hui-cover-tilt-position-tile-feature";
|
||||||
import "../tile-features/hui-cover-tilt-tile-feature";
|
import "../tile-features/hui-cover-tilt-tile-feature";
|
||||||
import "../tile-features/hui-fan-speed-tile-feature";
|
import "../tile-features/hui-fan-speed-tile-feature";
|
||||||
|
import "../tile-features/hui-humidifier-modes-tile-feature";
|
||||||
import "../tile-features/hui-lawn-mower-commands-tile-feature";
|
import "../tile-features/hui-lawn-mower-commands-tile-feature";
|
||||||
import "../tile-features/hui-light-brightness-tile-feature";
|
import "../tile-features/hui-light-brightness-tile-feature";
|
||||||
import "../tile-features/hui-light-color-temp-tile-feature";
|
import "../tile-features/hui-light-color-temp-tile-feature";
|
||||||
|
import "../tile-features/hui-number-tile-feature";
|
||||||
import "../tile-features/hui-select-options-tile-feature";
|
import "../tile-features/hui-select-options-tile-feature";
|
||||||
import "../tile-features/hui-target-temperature-tile-feature";
|
import "../tile-features/hui-target-temperature-tile-feature";
|
||||||
import "../tile-features/hui-vacuum-commands-tile-feature";
|
import "../tile-features/hui-vacuum-commands-tile-feature";
|
||||||
import "../tile-features/hui-water-heater-operation-modes-tile-feature";
|
import "../tile-features/hui-water-heater-operation-modes-tile-feature";
|
||||||
import "../tile-features/hui-number-tile-feature";
|
|
||||||
import { LovelaceTileFeatureConfig } from "../tile-features/types";
|
import { LovelaceTileFeatureConfig } from "../tile-features/types";
|
||||||
import {
|
import {
|
||||||
createLovelaceElement,
|
createLovelaceElement,
|
||||||
@ -29,6 +30,7 @@ const TYPES: Set<LovelaceTileFeatureConfig["type"]> = new Set([
|
|||||||
"cover-tilt-position",
|
"cover-tilt-position",
|
||||||
"cover-tilt",
|
"cover-tilt",
|
||||||
"fan-speed",
|
"fan-speed",
|
||||||
|
"humidifier-modes",
|
||||||
"lawn-mower-commands",
|
"lawn-mower-commands",
|
||||||
"light-brightness",
|
"light-brightness",
|
||||||
"light-color-temp",
|
"light-color-temp",
|
||||||
|
@ -1,13 +1,28 @@
|
|||||||
import { html, LitElement, nothing } from "lit";
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { assert, assign, object, optional, string } from "superstruct";
|
import memoizeOne from "memoize-one";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import {
|
||||||
|
any,
|
||||||
|
array,
|
||||||
|
assert,
|
||||||
|
assign,
|
||||||
|
object,
|
||||||
|
optional,
|
||||||
|
string,
|
||||||
|
} from "superstruct";
|
||||||
|
import { HASSDomEvent, fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import "../../../../components/ha-form/ha-form";
|
import "../../../../components/ha-form/ha-form";
|
||||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import type { HumidifierCardConfig } from "../../cards/types";
|
import type { HumidifierCardConfig } from "../../cards/types";
|
||||||
|
import {
|
||||||
|
LovelaceTileFeatureConfig,
|
||||||
|
LovelaceTileFeatureContext,
|
||||||
|
} from "../../tile-features/types";
|
||||||
import type { LovelaceCardEditor } from "../../types";
|
import type { LovelaceCardEditor } from "../../types";
|
||||||
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
|
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
|
||||||
|
import { EditSubElementEvent, SubElementEditorConfig } from "../types";
|
||||||
|
import "./hui-tile-card-features-editor";
|
||||||
|
|
||||||
const cardConfigStruct = assign(
|
const cardConfigStruct = assign(
|
||||||
baseLovelaceCardConfig,
|
baseLovelaceCardConfig,
|
||||||
@ -15,6 +30,7 @@ const cardConfigStruct = assign(
|
|||||||
entity: optional(string()),
|
entity: optional(string()),
|
||||||
name: optional(string()),
|
name: optional(string()),
|
||||||
theme: optional(string()),
|
theme: optional(string()),
|
||||||
|
features: optional(array(any())),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -43,16 +59,39 @@ export class HuiHumidifierCardEditor
|
|||||||
|
|
||||||
@state() private _config?: HumidifierCardConfig;
|
@state() private _config?: HumidifierCardConfig;
|
||||||
|
|
||||||
|
@state() private _subElementEditorConfig?: SubElementEditorConfig;
|
||||||
|
|
||||||
public setConfig(config: HumidifierCardConfig): void {
|
public setConfig(config: HumidifierCardConfig): void {
|
||||||
assert(config, cardConfigStruct);
|
assert(config, cardConfigStruct);
|
||||||
this._config = config;
|
this._config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _context = memoizeOne(
|
||||||
|
(entity_id?: string): LovelaceTileFeatureContext => ({ entity_id })
|
||||||
|
);
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (!this.hass || !this._config) {
|
if (!this.hass || !this._config) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const stateObj = this._config.entity
|
||||||
|
? this.hass.states[this._config.entity]
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (this._subElementEditorConfig) {
|
||||||
|
return html`
|
||||||
|
<hui-sub-element-editor
|
||||||
|
.hass=${this.hass}
|
||||||
|
.config=${this._subElementEditorConfig}
|
||||||
|
.context=${this._context(this._config.entity)}
|
||||||
|
@go-back=${this._goBack}
|
||||||
|
@config-changed=${this.subElementChanged}
|
||||||
|
>
|
||||||
|
</hui-sub-element-editor>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-form
|
<ha-form
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -61,6 +100,13 @@ export class HuiHumidifierCardEditor
|
|||||||
.computeLabel=${this._computeLabelCallback}
|
.computeLabel=${this._computeLabelCallback}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
></ha-form>
|
></ha-form>
|
||||||
|
<hui-tile-card-features-editor
|
||||||
|
.hass=${this.hass}
|
||||||
|
.stateObj=${stateObj}
|
||||||
|
.features=${this._config!.features ?? []}
|
||||||
|
@features-changed=${this._featuresChanged}
|
||||||
|
@edit-detail-element=${this._editDetailElement}
|
||||||
|
></hui-tile-card-features-editor>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +114,62 @@ export class HuiHumidifierCardEditor
|
|||||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _featuresChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
if (!this._config || !this.hass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const features = ev.detail.features as LovelaceTileFeatureConfig[];
|
||||||
|
const config: HumidifierCardConfig = {
|
||||||
|
...this._config,
|
||||||
|
features,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (features.length === 0) {
|
||||||
|
delete config.features;
|
||||||
|
}
|
||||||
|
|
||||||
|
fireEvent(this, "config-changed", { config });
|
||||||
|
}
|
||||||
|
|
||||||
|
private subElementChanged(ev: CustomEvent): void {
|
||||||
|
ev.stopPropagation();
|
||||||
|
if (!this._config || !this.hass) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = ev.detail.config;
|
||||||
|
|
||||||
|
const newConfigFeatures = this._config!.features
|
||||||
|
? [...this._config!.features]
|
||||||
|
: [];
|
||||||
|
|
||||||
|
if (!value) {
|
||||||
|
newConfigFeatures.splice(this._subElementEditorConfig!.index!, 1);
|
||||||
|
this._goBack();
|
||||||
|
} else {
|
||||||
|
newConfigFeatures[this._subElementEditorConfig!.index!] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._config = { ...this._config!, features: newConfigFeatures };
|
||||||
|
|
||||||
|
this._subElementEditorConfig = {
|
||||||
|
...this._subElementEditorConfig!,
|
||||||
|
elementConfig: value,
|
||||||
|
};
|
||||||
|
|
||||||
|
fireEvent(this, "config-changed", { config: this._config });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _editDetailElement(ev: HASSDomEvent<EditSubElementEvent>): void {
|
||||||
|
this._subElementEditorConfig = ev.detail.subElementConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _goBack(): void {
|
||||||
|
this._subElementEditorConfig = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => {
|
private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => {
|
||||||
if (schema.name === "entity") {
|
if (schema.name === "entity") {
|
||||||
return this.hass!.localize(
|
return this.hass!.localize(
|
||||||
@ -87,6 +189,15 @@ export class HuiHumidifierCardEditor
|
|||||||
`ui.panel.lovelace.editor.card.generic.${schema.name}`
|
`ui.panel.lovelace.editor.card.generic.${schema.name}`
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-form {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -24,21 +24,22 @@ import { HomeAssistant } from "../../../../types";
|
|||||||
import { getTileFeatureElementClass } from "../../create-element/create-tile-feature-element";
|
import { getTileFeatureElementClass } from "../../create-element/create-tile-feature-element";
|
||||||
import { supportsAlarmModesTileFeature } from "../../tile-features/hui-alarm-modes-tile-feature";
|
import { supportsAlarmModesTileFeature } from "../../tile-features/hui-alarm-modes-tile-feature";
|
||||||
import { supportsClimateHvacModesTileFeature } from "../../tile-features/hui-climate-hvac-modes-tile-feature";
|
import { supportsClimateHvacModesTileFeature } from "../../tile-features/hui-climate-hvac-modes-tile-feature";
|
||||||
|
import { supportsClimatePresetModesTileFeature } from "../../tile-features/hui-climate-preset-modes-tile-feature";
|
||||||
import { supportsCoverOpenCloseTileFeature } from "../../tile-features/hui-cover-open-close-tile-feature";
|
import { supportsCoverOpenCloseTileFeature } from "../../tile-features/hui-cover-open-close-tile-feature";
|
||||||
import { supportsCoverPositionTileFeature } from "../../tile-features/hui-cover-position-tile-feature";
|
import { supportsCoverPositionTileFeature } from "../../tile-features/hui-cover-position-tile-feature";
|
||||||
import { supportsCoverTiltPositionTileFeature } from "../../tile-features/hui-cover-tilt-position-tile-feature";
|
import { supportsCoverTiltPositionTileFeature } from "../../tile-features/hui-cover-tilt-position-tile-feature";
|
||||||
import { supportsCoverTiltTileFeature } from "../../tile-features/hui-cover-tilt-tile-feature";
|
import { supportsCoverTiltTileFeature } from "../../tile-features/hui-cover-tilt-tile-feature";
|
||||||
import { supportsFanSpeedTileFeature } from "../../tile-features/hui-fan-speed-tile-feature";
|
import { supportsFanSpeedTileFeature } from "../../tile-features/hui-fan-speed-tile-feature";
|
||||||
|
import { supportsHumidifierModesTileFeature } from "../../tile-features/hui-humidifier-modes-tile-feature";
|
||||||
import { supportsLawnMowerCommandTileFeature } from "../../tile-features/hui-lawn-mower-commands-tile-feature";
|
import { supportsLawnMowerCommandTileFeature } from "../../tile-features/hui-lawn-mower-commands-tile-feature";
|
||||||
import { supportsLightBrightnessTileFeature } from "../../tile-features/hui-light-brightness-tile-feature";
|
import { supportsLightBrightnessTileFeature } from "../../tile-features/hui-light-brightness-tile-feature";
|
||||||
import { supportsLightColorTempTileFeature } from "../../tile-features/hui-light-color-temp-tile-feature";
|
import { supportsLightColorTempTileFeature } from "../../tile-features/hui-light-color-temp-tile-feature";
|
||||||
|
import { supportsNumberTileFeature } from "../../tile-features/hui-number-tile-feature";
|
||||||
import { supportsSelectOptionTileFeature } from "../../tile-features/hui-select-options-tile-feature";
|
import { supportsSelectOptionTileFeature } from "../../tile-features/hui-select-options-tile-feature";
|
||||||
import { supportsTargetTemperatureTileFeature } from "../../tile-features/hui-target-temperature-tile-feature";
|
import { supportsTargetTemperatureTileFeature } from "../../tile-features/hui-target-temperature-tile-feature";
|
||||||
import { supportsVacuumCommandTileFeature } from "../../tile-features/hui-vacuum-commands-tile-feature";
|
import { supportsVacuumCommandTileFeature } from "../../tile-features/hui-vacuum-commands-tile-feature";
|
||||||
import { supportsWaterHeaterOperationModesTileFeature } from "../../tile-features/hui-water-heater-operation-modes-tile-feature";
|
import { supportsWaterHeaterOperationModesTileFeature } from "../../tile-features/hui-water-heater-operation-modes-tile-feature";
|
||||||
import { LovelaceTileFeatureConfig } from "../../tile-features/types";
|
import { LovelaceTileFeatureConfig } from "../../tile-features/types";
|
||||||
import { supportsClimatePresetModesTileFeature } from "../../tile-features/hui-climate-preset-modes-tile-feature";
|
|
||||||
import { supportsNumberTileFeature } from "../../tile-features/hui-number-tile-feature";
|
|
||||||
|
|
||||||
export type FeatureType = LovelaceTileFeatureConfig["type"];
|
export type FeatureType = LovelaceTileFeatureConfig["type"];
|
||||||
type SupportsFeature = (stateObj: HassEntity) => boolean;
|
type SupportsFeature = (stateObj: HassEntity) => boolean;
|
||||||
@ -52,6 +53,7 @@ const UI_FEATURE_TYPES = [
|
|||||||
"cover-tilt-position",
|
"cover-tilt-position",
|
||||||
"cover-tilt",
|
"cover-tilt",
|
||||||
"fan-speed",
|
"fan-speed",
|
||||||
|
"humidifier-modes",
|
||||||
"lawn-mower-commands",
|
"lawn-mower-commands",
|
||||||
"light-brightness",
|
"light-brightness",
|
||||||
"light-color-temp",
|
"light-color-temp",
|
||||||
@ -86,14 +88,15 @@ const SUPPORTS_FEATURE_TYPES: Record<
|
|||||||
"cover-tilt-position": supportsCoverTiltPositionTileFeature,
|
"cover-tilt-position": supportsCoverTiltPositionTileFeature,
|
||||||
"cover-tilt": supportsCoverTiltTileFeature,
|
"cover-tilt": supportsCoverTiltTileFeature,
|
||||||
"fan-speed": supportsFanSpeedTileFeature,
|
"fan-speed": supportsFanSpeedTileFeature,
|
||||||
|
"humidifier-modes": supportsHumidifierModesTileFeature,
|
||||||
"lawn-mower-commands": supportsLawnMowerCommandTileFeature,
|
"lawn-mower-commands": supportsLawnMowerCommandTileFeature,
|
||||||
"light-brightness": supportsLightBrightnessTileFeature,
|
"light-brightness": supportsLightBrightnessTileFeature,
|
||||||
"light-color-temp": supportsLightColorTempTileFeature,
|
"light-color-temp": supportsLightColorTempTileFeature,
|
||||||
|
number: supportsNumberTileFeature,
|
||||||
"target-temperature": supportsTargetTemperatureTileFeature,
|
"target-temperature": supportsTargetTemperatureTileFeature,
|
||||||
"vacuum-commands": supportsVacuumCommandTileFeature,
|
"vacuum-commands": supportsVacuumCommandTileFeature,
|
||||||
"water-heater-operation-modes": supportsWaterHeaterOperationModesTileFeature,
|
"water-heater-operation-modes": supportsWaterHeaterOperationModesTileFeature,
|
||||||
"select-options": supportsSelectOptionTileFeature,
|
"select-options": supportsSelectOptionTileFeature,
|
||||||
number: supportsNumberTileFeature,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const CUSTOM_FEATURE_ENTRIES: Record<
|
const CUSTOM_FEATURE_ENTRIES: Record<
|
||||||
|
@ -0,0 +1,136 @@
|
|||||||
|
import { mdiPower, mdiWaterPercent } from "@mdi/js";
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { LitElement, PropertyValues, TemplateResult, css, html } from "lit";
|
||||||
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { styleMap } from "lit/directives/style-map";
|
||||||
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
|
import { stateColorCss } from "../../../common/entity/state_color";
|
||||||
|
import "../../../components/ha-control-select";
|
||||||
|
import type { ControlSelectOption } from "../../../components/ha-control-select";
|
||||||
|
import { UNAVAILABLE } from "../../../data/entity";
|
||||||
|
import { HumidifierEntity, HumidifierState } from "../../../data/humidifier";
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
|
import { LovelaceTileFeature } from "../types";
|
||||||
|
import { HumidifierModesTileFeatureConfig } from "./types";
|
||||||
|
|
||||||
|
export const supportsHumidifierModesTileFeature = (stateObj: HassEntity) => {
|
||||||
|
const domain = computeDomain(stateObj.entity_id);
|
||||||
|
return domain === "humidifier";
|
||||||
|
};
|
||||||
|
|
||||||
|
@customElement("hui-humidifier-modes-tile-feature")
|
||||||
|
class HuiHumidifierModeTileFeature
|
||||||
|
extends LitElement
|
||||||
|
implements LovelaceTileFeature
|
||||||
|
{
|
||||||
|
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public stateObj?: HumidifierEntity;
|
||||||
|
|
||||||
|
@state() private _config?: HumidifierModesTileFeatureConfig;
|
||||||
|
|
||||||
|
@state() _currentState?: HumidifierState;
|
||||||
|
|
||||||
|
static getStubConfig(): HumidifierModesTileFeatureConfig {
|
||||||
|
return {
|
||||||
|
type: "humidifier-modes",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public setConfig(config: HumidifierModesTileFeatureConfig): void {
|
||||||
|
if (!config) {
|
||||||
|
throw new Error("Invalid configuration");
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected willUpdate(changedProp: PropertyValues): void {
|
||||||
|
super.willUpdate(changedProp);
|
||||||
|
if (changedProp.has("stateObj") && this.stateObj) {
|
||||||
|
this._currentState = this.stateObj.state as HumidifierState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _valueChanged(ev: CustomEvent) {
|
||||||
|
const newState = (ev.detail as any).value as HumidifierState;
|
||||||
|
|
||||||
|
if (newState === this.stateObj!.state) return;
|
||||||
|
|
||||||
|
const oldState = this.stateObj!.state as HumidifierState;
|
||||||
|
this._currentState = newState;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this._setState(newState);
|
||||||
|
} catch (err) {
|
||||||
|
this._currentState = oldState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _setState(newState: HumidifierState) {
|
||||||
|
await this.hass!.callService(
|
||||||
|
"humidifier",
|
||||||
|
newState === "on" ? "turn_on" : "turn_off",
|
||||||
|
{
|
||||||
|
entity_id: this.stateObj!.entity_id,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult | null {
|
||||||
|
if (
|
||||||
|
!this._config ||
|
||||||
|
!this.hass ||
|
||||||
|
!this.stateObj ||
|
||||||
|
!supportsHumidifierModesTileFeature(this.stateObj)
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const color = stateColorCss(this.stateObj);
|
||||||
|
|
||||||
|
const options = ["on", "off"].map<ControlSelectOption>((entityState) => ({
|
||||||
|
value: entityState,
|
||||||
|
label: this.hass!.formatEntityState(this.stateObj!, entityState),
|
||||||
|
path: entityState === "on" ? mdiWaterPercent : mdiPower,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div class="container">
|
||||||
|
<ha-control-select
|
||||||
|
.options=${options}
|
||||||
|
.value=${this._currentState}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
hide-label
|
||||||
|
.ariaLabel=${this.hass.localize("ui.card.humidifier.state")}
|
||||||
|
style=${styleMap({
|
||||||
|
"--control-select-color": color,
|
||||||
|
})}
|
||||||
|
.disabled=${this.stateObj!.state === UNAVAILABLE}
|
||||||
|
>
|
||||||
|
</ha-control-select>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return css`
|
||||||
|
ha-control-select {
|
||||||
|
--control-select-color: var(--tile-color);
|
||||||
|
--control-select-padding: 0;
|
||||||
|
--control-select-thickness: 40px;
|
||||||
|
--control-select-border-radius: 10px;
|
||||||
|
--control-select-button-border-radius: 10px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
padding: 0 12px 12px 12px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hui-humidifier-modes-tile-feature": HuiHumidifierModeTileFeature;
|
||||||
|
}
|
||||||
|
}
|
@ -64,6 +64,10 @@ export interface WaterHeaterOperationModesTileFeatureConfig {
|
|||||||
operation_modes?: OperationMode[];
|
operation_modes?: OperationMode[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HumidifierModesTileFeatureConfig {
|
||||||
|
type: "humidifier-modes";
|
||||||
|
}
|
||||||
|
|
||||||
export const VACUUM_COMMANDS = [
|
export const VACUUM_COMMANDS = [
|
||||||
"start_pause",
|
"start_pause",
|
||||||
"stop",
|
"stop",
|
||||||
@ -97,6 +101,7 @@ export type LovelaceTileFeatureConfig =
|
|||||||
| CoverTiltPositionTileFeatureConfig
|
| CoverTiltPositionTileFeatureConfig
|
||||||
| CoverTiltTileFeatureConfig
|
| CoverTiltTileFeatureConfig
|
||||||
| FanSpeedTileFeatureConfig
|
| FanSpeedTileFeatureConfig
|
||||||
|
| HumidifierModesTileFeatureConfig
|
||||||
| LawnMowerCommandsTileFeatureConfig
|
| LawnMowerCommandsTileFeatureConfig
|
||||||
| LightBrightnessTileFeatureConfig
|
| LightBrightnessTileFeatureConfig
|
||||||
| LightColorTempTileFeatureConfig
|
| LightColorTempTileFeatureConfig
|
||||||
|
Loading…
x
Reference in New Issue
Block a user