Add option to show current humidity on humidifier card (#19079)

This commit is contained in:
Paul Bottein 2023-12-20 14:12:59 +01:00 committed by GitHub
parent 2306234063
commit 2b18ac8d4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 122 additions and 64 deletions

View File

@ -86,6 +86,7 @@ export class HaBigNumber extends LitElement {
.value .decimal { .value .decimal {
font-size: 0.42em; font-size: 0.42em;
line-height: 1.33; line-height: 1.33;
min-height: 1.33em;
} }
.value .unit { .value .unit {
font-size: 0.33em; font-size: 0.33em;

View File

@ -128,7 +128,8 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
<p class="title">${name}</p> <p class="title">${name}</p>
<ha-state-control-humidifier-humidity <ha-state-control-humidifier-humidity
prevent-interaction-on-scroll prevent-interaction-on-scroll
show-current .showCurrentAsPrimary=${this._config.show_current_as_primary}
show-secondary
.hass=${this.hass} .hass=${this.hass}
.stateObj=${stateObj} .stateObj=${stateObj}
></ha-state-control-humidifier-humidity> ></ha-state-control-humidifier-humidity>

View File

@ -262,6 +262,7 @@ export interface HumidifierCardConfig extends LovelaceCardConfig {
entity: string; entity: string;
theme?: string; theme?: string;
name?: string; name?: string;
show_current_as_primary?: boolean;
features?: LovelaceCardFeatureConfig[]; features?: LovelaceCardFeatureConfig[];
} }

View File

@ -6,13 +6,17 @@ import {
array, array,
assert, assert,
assign, assign,
boolean,
object, object,
optional, optional,
string, string,
} from "superstruct"; } from "superstruct";
import { HASSDomEvent, fireEvent } from "../../../../common/dom/fire_event"; 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 {
HaFormSchema,
SchemaUnion,
} from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types"; import type { HomeAssistant } from "../../../../types";
import { import {
LovelaceCardFeatureConfig, LovelaceCardFeatureConfig,
@ -37,6 +41,7 @@ const cardConfigStruct = assign(
entity: optional(string()), entity: optional(string()),
name: optional(string()), name: optional(string()),
theme: optional(string()), theme: optional(string()),
show_current_as_primary: optional(boolean()),
features: optional(array(any())), features: optional(array(any())),
}) })
); );
@ -55,7 +60,13 @@ const SCHEMA = [
{ name: "theme", selector: { theme: {} } }, { name: "theme", selector: { theme: {} } },
], ],
}, },
] as const; {
name: "show_current_as_primary",
selector: {
boolean: {},
},
},
] as const satisfies readonly HaFormSchema[];
@customElement("hui-humidifier-card-editor") @customElement("hui-humidifier-card-editor")
export class HuiHumidifierCardEditor export class HuiHumidifierCardEditor
@ -179,20 +190,12 @@ export class HuiHumidifierCardEditor
} }
private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => { private _computeLabelCallback = (schema: SchemaUnion<typeof SCHEMA>) => {
if (schema.name === "entity") { if (schema.name === "show_current_as_primary") {
return this.hass!.localize( return this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.entity" "ui.panel.lovelace.editor.card.humidifier.show_current_as_primary"
); );
} }
if (schema.name === "theme") {
return `${this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.theme"
)} (${this.hass!.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})`;
}
return this.hass!.localize( return this.hass!.localize(
`ui.panel.lovelace.editor.card.generic.${schema.name}` `ui.panel.lovelace.editor.card.generic.${schema.name}`
); );

View File

@ -1,5 +1,5 @@
import { mdiMinus, mdiPlus, mdiWaterPercent } from "@mdi/js"; import { mdiMinus, mdiPlus, mdiThermostat, mdiWaterPercent } from "@mdi/js";
import { CSSResultGroup, LitElement, PropertyValues, html } from "lit"; import { CSSResultGroup, LitElement, PropertyValues, html, nothing } 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";
import { stateActive } from "../../common/entity/state_active"; import { stateActive } from "../../common/entity/state_active";
@ -11,6 +11,7 @@ import "../../components/ha-control-circular-slider";
import "../../components/ha-outlined-icon-button"; import "../../components/ha-outlined-icon-button";
import "../../components/ha-svg-icon"; import "../../components/ha-svg-icon";
import { UNAVAILABLE } from "../../data/entity"; import { UNAVAILABLE } from "../../data/entity";
import { DOMAIN_ATTRIBUTES_UNITS } from "../../data/entity_attributes";
import { import {
HUMIDIFIER_ACTION_MODE, HUMIDIFIER_ACTION_MODE,
HumidifierEntity, HumidifierEntity,
@ -28,8 +29,11 @@ export class HaStateControlHumidifierHumidity extends LitElement {
@property({ attribute: false }) public stateObj!: HumidifierEntity; @property({ attribute: false }) public stateObj!: HumidifierEntity;
@property({ attribute: "show-current", type: Boolean }) @property({ attribute: "show-secondary", type: Boolean })
public showCurrent?: boolean = false; public showSecondary?: boolean;
@property({ attribute: "use-current-as-primary", type: Boolean })
public showCurrentAsPrimary?: boolean;
@property({ type: Boolean, attribute: "prevent-interaction-on-scroll" }) @property({ type: Boolean, attribute: "prevent-interaction-on-scroll" })
public preventInteractionOnScroll?: boolean; public preventInteractionOnScroll?: boolean;
@ -101,37 +105,11 @@ export class HaStateControlHumidifierHumidity extends LitElement {
const action = this.stateObj.attributes.action; const action = this.stateObj.attributes.action;
const actionLabel = this.hass.formatEntityAttributeValue(
this.stateObj,
"action"
);
return html` return html`
<p class="label"> <p class="label">
${action && action !== "off" && action !== "idle" ${action
? actionLabel ? this.hass.formatEntityAttributeValue(this.stateObj, "action")
: this._targetHumidity : this.hass.formatEntityState(this.stateObj)}
? this.hass.localize("ui.card.humidifier.target")
: this.hass.formatEntityState(this.stateObj)}
</p>
`;
}
private _renderCurrentHumidity(humidity?: number) {
if (!this.showCurrent || humidity == null) {
return html`<p class="label">&nbsp;</p>`;
}
return html`
<p class="label">
<ha-svg-icon .path=${mdiWaterPercent}></ha-svg-icon>
<span>
${this.hass.formatEntityAttributeValue(
this.stateObj,
"current_humidity",
humidity
)}
</span>
</p> </p>
`; `;
} }
@ -155,19 +133,95 @@ export class HaStateControlHumidifierHumidity extends LitElement {
`; `;
} }
private _renderTarget(humidity: number) { private _renderPrimary() {
const formatOptions = { const currentHumidity = this.stateObj.attributes.current_humidity;
if (currentHumidity != null && this.showCurrentAsPrimary) {
return this._renderCurrent(currentHumidity, "big");
}
if (this._targetHumidity != null && !this.showCurrentAsPrimary) {
return this._renderTarget(this._targetHumidity!, "big");
}
return nothing;
}
private _renderSecondary() {
if (!this.showSecondary) {
return html`<p class="label"></p>`;
}
const currentHumidity = this.stateObj.attributes.current_humidity;
if (currentHumidity != null && !this.showCurrentAsPrimary) {
return html`
<p class="label">
<ha-svg-icon .path=${mdiWaterPercent}></ha-svg-icon>
${this._renderCurrent(currentHumidity, "normal")}
</p>
`;
}
if (this._targetHumidity != null && this.showCurrentAsPrimary) {
return html`
<p class="label">
<ha-svg-icon .path=${mdiThermostat}></ha-svg-icon>
${this._renderCurrent(this._targetHumidity, "normal")}
</p>
`;
}
return html`<p class="label"></p>`;
}
private _renderTarget(humidity: number, style: "normal" | "big") {
const formatOptions: Intl.NumberFormatOptions = {
maximumFractionDigits: 0, maximumFractionDigits: 0,
}; };
if (style === "big") {
return html`
<ha-big-number
.value=${humidity}
.unit=${DOMAIN_ATTRIBUTES_UNITS.humidifier.current_humidity}
.hass=${this.hass}
.formatOptions=${formatOptions}
unit-position="bottom"
></ha-big-number>
`;
}
return html` return html`
<ha-big-number ${this.hass.formatEntityAttributeValue(
.value=${humidity} this.stateObj,
unit="%" "humidity",
unit-position="bottom" humidity
.hass=${this.hass} )}
.formatOptions=${formatOptions} `;
></ha-big-number> }
private _renderCurrent(humidity: number, style: "normal" | "big") {
const formatOptions: Intl.NumberFormatOptions = {
maximumFractionDigits: 1,
};
if (style === "big") {
return html`
<ha-big-number
.value=${humidity}
.unit=${DOMAIN_ATTRIBUTES_UNITS.humidifier.current_humidity}
.hass=${this.hass}
.formatOptions=${formatOptions}
unit-position="bottom"
></ha-big-number>
`;
}
return html`
${this.hass.formatEntityAttributeValue(
this.stateObj,
"current_humidity",
humidity
)}
`; `;
} }
@ -219,10 +273,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
> >
</ha-control-circular-slider> </ha-control-circular-slider>
<div class="info"> <div class="info">
${this._renderLabel()} ${this._renderTarget(targetHumidity)} ${this._renderLabel()}${this._renderPrimary()}${this._renderSecondary()}
${this._renderCurrentHumidity(
this.stateObj.attributes.current_humidity
)}
</div> </div>
${this._renderButtons()} ${this._renderButtons()}
</div> </div>
@ -246,10 +297,7 @@ export class HaStateControlHumidifierHumidity extends LitElement {
> >
</ha-control-circular-slider> </ha-control-circular-slider>
<div class="info"> <div class="info">
${this._renderLabel()} ${this._renderLabel()} ${this._renderSecondary()}
${this._renderCurrentHumidity(
this.stateObj.attributes.current_humidity
)}
</div> </div>
</div> </div>
`; `;

View File

@ -41,6 +41,9 @@ export const stateControlCircularSliderStyle = css`
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
line-height: 1.5;
min-height: 1.5em;
white-space: nowrap;
} }
.label span { .label span {
white-space: nowrap; white-space: nowrap;

View File

@ -5136,7 +5136,8 @@
}, },
"humidifier": { "humidifier": {
"name": "Humidifier", "name": "Humidifier",
"description": "The Humidifier card gives control of your humidifier entity. Allowing you to change the humidity and mode of the entity." "description": "The Humidifier card gives control of your humidifier entity. Allowing you to change the humidity and mode of the entity.",
"show_current_as_primary": "Show current humidity as primary information"
}, },
"iframe": { "iframe": {
"name": "Webpage", "name": "Webpage",