mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-11 18:47:24 +00:00
Compare commits
1 Commits
20251201.0
...
number-ent
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d215064c6e |
@@ -1,10 +1,13 @@
|
|||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues } from "lit";
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
import type { NumberSelector } from "../../data/selector";
|
import type { NumberSelector } from "../../data/selector";
|
||||||
import type { HomeAssistant } from "../../types";
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import "../entity/ha-entity-picker";
|
||||||
|
import "../ha-button-toggle-group";
|
||||||
import "../ha-input-helper-text";
|
import "../ha-input-helper-text";
|
||||||
import "../ha-slider";
|
import "../ha-slider";
|
||||||
import "../ha-textfield";
|
import "../ha-textfield";
|
||||||
@@ -15,7 +18,7 @@ export class HaNumberSelector extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public selector!: NumberSelector;
|
@property({ attribute: false }) public selector!: NumberSelector;
|
||||||
|
|
||||||
@property({ type: Number }) public value?: number;
|
@property({ type: Number }) public value?: number | string;
|
||||||
|
|
||||||
@property({ type: Number }) public placeholder?: number;
|
@property({ type: Number }) public placeholder?: number;
|
||||||
|
|
||||||
@@ -30,13 +33,30 @@ export class HaNumberSelector extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
|
@state() private _mode: "number" | "entity" = "number";
|
||||||
|
|
||||||
private _valueStr = "";
|
private _valueStr = "";
|
||||||
|
|
||||||
protected willUpdate(changedProps: PropertyValues) {
|
protected willUpdate(changedProps: PropertyValues) {
|
||||||
|
if (!this.hasUpdated) {
|
||||||
|
if (
|
||||||
|
this.selector.number?.entity?.domains.length &&
|
||||||
|
typeof this.value === "string" &&
|
||||||
|
this.selector.number?.entity?.domains.some((domain) =>
|
||||||
|
(this.value as string).startsWith(`${domain}.`)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
this._mode = "entity";
|
||||||
|
}
|
||||||
|
}
|
||||||
if (changedProps.has("value")) {
|
if (changedProps.has("value")) {
|
||||||
if (this._valueStr === "" || this.value !== Number(this._valueStr)) {
|
if (this._valueStr === "" || this.value !== Number(this._valueStr)) {
|
||||||
this._valueStr =
|
this._valueStr =
|
||||||
this.value == null || isNaN(this.value) ? "" : this.value.toString();
|
this.value == null ||
|
||||||
|
typeof this.value === "string" ||
|
||||||
|
isNaN(this.value)
|
||||||
|
? ""
|
||||||
|
: this.value.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,6 +67,8 @@ export class HaNumberSelector extends LitElement {
|
|||||||
this.selector.number?.min === undefined ||
|
this.selector.number?.min === undefined ||
|
||||||
this.selector.number?.max === undefined;
|
this.selector.number?.max === undefined;
|
||||||
|
|
||||||
|
const multiMode = Boolean(this.selector.number?.entity?.domains.length);
|
||||||
|
|
||||||
let sliderStep;
|
let sliderStep;
|
||||||
|
|
||||||
if (!isBox) {
|
if (!isBox) {
|
||||||
@@ -72,51 +94,73 @@ export class HaNumberSelector extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${this.label && !isBox
|
${this.label && !isBox && !multiMode
|
||||||
? html`${this.label}${this.required ? "*" : ""}`
|
? html`${this.label}${this.required ? "*" : ""}`
|
||||||
: nothing}
|
: nothing}
|
||||||
|
${multiMode
|
||||||
|
? html`<div class="multi-header">
|
||||||
|
<span>${this.label}${this.required ? "*" : ""}</span>
|
||||||
|
<ha-button-toggle-group
|
||||||
|
size="small"
|
||||||
|
.buttons=${this._toggleButtons(this.hass.localize)}
|
||||||
|
.active=${this._mode}
|
||||||
|
@value-changed=${this._modeChanged}
|
||||||
|
></ha-button-toggle-group>
|
||||||
|
</div>`
|
||||||
|
: nothing}
|
||||||
<div class="input">
|
<div class="input">
|
||||||
${!isBox
|
${multiMode && this._mode === "entity"
|
||||||
? html`
|
? html`<ha-entity-picker
|
||||||
<ha-slider
|
.hass=${this.hass}
|
||||||
labeled
|
.includeDomains=${this.selector.number!.entity!.domains}
|
||||||
.min=${this.selector.number!.min}
|
.value=${this.value}
|
||||||
.max=${this.selector.number!.max}
|
.placeholder=${this.placeholder}
|
||||||
.value=${this.value}
|
.helper=${this.helper}
|
||||||
.step=${sliderStep}
|
.disabled=${this.disabled}
|
||||||
|
.required=${this.required}
|
||||||
|
></ha-entity-picker>`
|
||||||
|
: html`${!isBox
|
||||||
|
? html`
|
||||||
|
<ha-slider
|
||||||
|
labeled
|
||||||
|
.min=${this.selector.number!.min}
|
||||||
|
.max=${this.selector.number!.max}
|
||||||
|
.value=${this.value}
|
||||||
|
.step=${sliderStep}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
.required=${this.required}
|
||||||
|
@change=${this._handleSliderChange}
|
||||||
|
.withMarkers=${this.selector.number?.slider_ticks ||
|
||||||
|
false}
|
||||||
|
>
|
||||||
|
</ha-slider>
|
||||||
|
`
|
||||||
|
: nothing}
|
||||||
|
<ha-textfield
|
||||||
|
.inputMode=${this.selector.number?.step === "any" ||
|
||||||
|
(this.selector.number?.step ?? 1) % 1 !== 0
|
||||||
|
? "decimal"
|
||||||
|
: "numeric"}
|
||||||
|
.label=${!isBox ? undefined : this.label}
|
||||||
|
.placeholder=${this.placeholder}
|
||||||
|
class=${classMap({ single: isBox })}
|
||||||
|
.min=${this.selector.number?.min}
|
||||||
|
.max=${this.selector.number?.max}
|
||||||
|
.value=${this._valueStr ?? ""}
|
||||||
|
.step=${this.selector.number?.step ?? 1}
|
||||||
|
helperPersistent
|
||||||
|
.helper=${isBox ? this.helper : undefined}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
.required=${this.required}
|
.required=${this.required}
|
||||||
@change=${this._handleSliderChange}
|
.suffix=${unit}
|
||||||
.withMarkers=${this.selector.number?.slider_ticks || false}
|
type="number"
|
||||||
|
autoValidate
|
||||||
|
?no-spinner=${!isBox}
|
||||||
|
@input=${this._handleInputChange}
|
||||||
>
|
>
|
||||||
</ha-slider>
|
</ha-textfield>`}
|
||||||
`
|
|
||||||
: nothing}
|
|
||||||
<ha-textfield
|
|
||||||
.inputMode=${this.selector.number?.step === "any" ||
|
|
||||||
(this.selector.number?.step ?? 1) % 1 !== 0
|
|
||||||
? "decimal"
|
|
||||||
: "numeric"}
|
|
||||||
.label=${!isBox ? undefined : this.label}
|
|
||||||
.placeholder=${this.placeholder}
|
|
||||||
class=${classMap({ single: isBox })}
|
|
||||||
.min=${this.selector.number?.min}
|
|
||||||
.max=${this.selector.number?.max}
|
|
||||||
.value=${this._valueStr ?? ""}
|
|
||||||
.step=${this.selector.number?.step ?? 1}
|
|
||||||
helperPersistent
|
|
||||||
.helper=${isBox ? this.helper : undefined}
|
|
||||||
.disabled=${this.disabled}
|
|
||||||
.required=${this.required}
|
|
||||||
.suffix=${unit}
|
|
||||||
type="number"
|
|
||||||
autoValidate
|
|
||||||
?no-spinner=${!isBox}
|
|
||||||
@input=${this._handleInputChange}
|
|
||||||
>
|
|
||||||
</ha-textfield>
|
|
||||||
</div>
|
</div>
|
||||||
${!isBox && this.helper
|
${!isBox && !(multiMode && this._mode === "entity") && this.helper
|
||||||
? html`<ha-input-helper-text .disabled=${this.disabled}
|
? html`<ha-input-helper-text .disabled=${this.disabled}
|
||||||
>${this.helper}</ha-input-helper-text
|
>${this.helper}</ha-input-helper-text
|
||||||
>`
|
>`
|
||||||
@@ -124,6 +168,22 @@ export class HaNumberSelector extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _toggleButtons = memoizeOne((localize: HomeAssistant["localize"]) => [
|
||||||
|
{
|
||||||
|
label: localize("ui.components.selectors.number.value"),
|
||||||
|
value: "number",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: localize("ui.components.selectors.number.entity_value"),
|
||||||
|
value: "entity",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
private _modeChanged(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this._mode = ev.detail?.value || ev.target.value;
|
||||||
|
}
|
||||||
|
|
||||||
private _handleInputChange(ev) {
|
private _handleInputChange(ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this._valueStr = ev.target.value;
|
this._valueStr = ev.target.value;
|
||||||
@@ -155,17 +215,32 @@ export class HaNumberSelector extends LitElement {
|
|||||||
}
|
}
|
||||||
ha-slider {
|
ha-slider {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
margin-right: 16px;
|
margin-right: var(--ha-space-4);
|
||||||
margin-inline-end: 16px;
|
margin-inline-end: var(--ha-space-4);
|
||||||
margin-inline-start: 0;
|
margin-inline-start: 0;
|
||||||
}
|
}
|
||||||
ha-textfield {
|
ha-textfield {
|
||||||
--ha-textfield-input-width: 40px;
|
--ha-textfield-input-width: 40px;
|
||||||
}
|
}
|
||||||
|
.multi-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: var(--ha-space-2);
|
||||||
|
}
|
||||||
|
|
||||||
.single {
|
.single {
|
||||||
--ha-textfield-input-width: unset;
|
--ha-textfield-input-width: unset;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
ha-entity-picker {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
ha-button-toggle-group {
|
||||||
|
display: block;
|
||||||
|
justify-self: end;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -332,6 +332,7 @@ export interface NumberSelector {
|
|||||||
max?: number;
|
max?: number;
|
||||||
step?: number | "any";
|
step?: number | "any";
|
||||||
mode?: "box" | "slider";
|
mode?: "box" | "slider";
|
||||||
|
entity?: { domains: readonly string[] };
|
||||||
unit_of_measurement?: string;
|
unit_of_measurement?: string;
|
||||||
slider_ticks?: boolean;
|
slider_ticks?: boolean;
|
||||||
translation_key?: string;
|
translation_key?: string;
|
||||||
|
|||||||
@@ -1,16 +1,149 @@
|
|||||||
import type { PropertyValues } from "lit";
|
import type { PropertyValues } from "lit";
|
||||||
import { html, LitElement } from "lit";
|
import { html, LitElement } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { ensureArray } from "../../../../../common/array/ensure-array";
|
||||||
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
|
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import { hasTemplate } from "../../../../../common/string/has-template";
|
import { hasTemplate } from "../../../../../common/string/has-template";
|
||||||
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
|
||||||
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 { NumericStateTrigger } from "../../../../../data/automation";
|
import type { NumericStateTrigger } from "../../../../../data/automation";
|
||||||
import type { HomeAssistant } from "../../../../../types";
|
import type { HomeAssistant } from "../../../../../types";
|
||||||
import { ensureArray } from "../../../../../common/array/ensure-array";
|
|
||||||
|
const SCHEMA = [
|
||||||
|
{
|
||||||
|
name: "entity_id",
|
||||||
|
required: true,
|
||||||
|
selector: { entity: { multiple: true } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "attribute",
|
||||||
|
context: { filter_entity: "entity_id" },
|
||||||
|
selector: {
|
||||||
|
attribute: {
|
||||||
|
hide_attributes: [
|
||||||
|
"access_token",
|
||||||
|
"auto_update",
|
||||||
|
"available_modes",
|
||||||
|
"away_mode",
|
||||||
|
"changed_by",
|
||||||
|
"code_arm_required",
|
||||||
|
"code_format",
|
||||||
|
"color_mode",
|
||||||
|
"color_modes",
|
||||||
|
"current_activity",
|
||||||
|
"device_class",
|
||||||
|
"editable",
|
||||||
|
"effect_list",
|
||||||
|
"effect",
|
||||||
|
"entity_id",
|
||||||
|
"entity_picture",
|
||||||
|
"event_type",
|
||||||
|
"event_types",
|
||||||
|
"fan_mode",
|
||||||
|
"fan_modes",
|
||||||
|
"fan_speed_list",
|
||||||
|
"forecast",
|
||||||
|
"friendly_name",
|
||||||
|
"frontend_stream_type",
|
||||||
|
"has_date",
|
||||||
|
"has_time",
|
||||||
|
"hs_color",
|
||||||
|
"hvac_mode",
|
||||||
|
"hvac_modes",
|
||||||
|
"icon",
|
||||||
|
"id",
|
||||||
|
"latest_version",
|
||||||
|
"max_color_temp_kelvin",
|
||||||
|
"max_mireds",
|
||||||
|
"max_temp",
|
||||||
|
"media_album_name",
|
||||||
|
"media_artist",
|
||||||
|
"media_content_type",
|
||||||
|
"media_position_updated_at",
|
||||||
|
"media_title",
|
||||||
|
"min_color_temp_kelvin",
|
||||||
|
"min_mireds",
|
||||||
|
"min_temp",
|
||||||
|
"mode",
|
||||||
|
"next_dawn",
|
||||||
|
"next_dusk",
|
||||||
|
"next_midnight",
|
||||||
|
"next_noon",
|
||||||
|
"next_rising",
|
||||||
|
"next_setting",
|
||||||
|
"operation_list",
|
||||||
|
"operation_mode",
|
||||||
|
"options",
|
||||||
|
"percentage_step",
|
||||||
|
"precipitation_unit",
|
||||||
|
"preset_mode",
|
||||||
|
"preset_modes",
|
||||||
|
"pressure_unit",
|
||||||
|
"release_notes",
|
||||||
|
"release_summary",
|
||||||
|
"release_url",
|
||||||
|
"restored",
|
||||||
|
"rgb_color",
|
||||||
|
"rgbw_color",
|
||||||
|
"shuffle",
|
||||||
|
"skipped_version",
|
||||||
|
"sound_mode_list",
|
||||||
|
"sound_mode",
|
||||||
|
"source_list",
|
||||||
|
"source_type",
|
||||||
|
"source",
|
||||||
|
"state_class",
|
||||||
|
"step",
|
||||||
|
"supported_color_modes",
|
||||||
|
"supported_features",
|
||||||
|
"swing_mode",
|
||||||
|
"swing_modes",
|
||||||
|
"target_temp_step",
|
||||||
|
"temperature_unit",
|
||||||
|
"title",
|
||||||
|
"token",
|
||||||
|
"unit_of_measurement",
|
||||||
|
"user_id",
|
||||||
|
"uuid",
|
||||||
|
"visibility_unit",
|
||||||
|
"wind_speed_unit",
|
||||||
|
"xy_color",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "above",
|
||||||
|
selector: {
|
||||||
|
number: {
|
||||||
|
mode: "box",
|
||||||
|
min: Number.MIN_SAFE_INTEGER,
|
||||||
|
max: Number.MAX_SAFE_INTEGER,
|
||||||
|
step: 0.1,
|
||||||
|
entity: { domains: ["input_number", "number", "sensor"] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "below",
|
||||||
|
selector: {
|
||||||
|
number: {
|
||||||
|
mode: "box",
|
||||||
|
min: Number.MIN_SAFE_INTEGER,
|
||||||
|
max: Number.MAX_SAFE_INTEGER,
|
||||||
|
step: 0.1,
|
||||||
|
entity: { domains: ["input_number", "number", "sensor"] },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "value_template",
|
||||||
|
selector: { template: {} },
|
||||||
|
},
|
||||||
|
{ name: "for", selector: { duration: {} } },
|
||||||
|
] as const;
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-numeric_state")
|
@customElement("ha-automation-trigger-numeric_state")
|
||||||
export class HaNumericStateTrigger extends LitElement {
|
export class HaNumericStateTrigger extends LitElement {
|
||||||
@@ -20,224 +153,7 @@ export class HaNumericStateTrigger extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
@state() private _inputAboveIsEntity?: boolean;
|
|
||||||
|
|
||||||
@state() private _inputBelowIsEntity?: boolean;
|
|
||||||
|
|
||||||
private _schema = memoizeOne(
|
|
||||||
(
|
|
||||||
localize: LocalizeFunc,
|
|
||||||
entityId: string | string[],
|
|
||||||
inputAboveIsEntity?: boolean,
|
|
||||||
inputBelowIsEntity?: boolean
|
|
||||||
) =>
|
|
||||||
[
|
|
||||||
{
|
|
||||||
name: "entity_id",
|
|
||||||
required: true,
|
|
||||||
selector: { entity: { multiple: true } },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "attribute",
|
|
||||||
selector: {
|
|
||||||
attribute: {
|
|
||||||
entity_id: entityId ? entityId[0] : undefined,
|
|
||||||
hide_attributes: [
|
|
||||||
"access_token",
|
|
||||||
"auto_update",
|
|
||||||
"available_modes",
|
|
||||||
"away_mode",
|
|
||||||
"changed_by",
|
|
||||||
"code_arm_required",
|
|
||||||
"code_format",
|
|
||||||
"color_mode",
|
|
||||||
"color_modes",
|
|
||||||
"current_activity",
|
|
||||||
"device_class",
|
|
||||||
"editable",
|
|
||||||
"effect_list",
|
|
||||||
"effect",
|
|
||||||
"entity_id",
|
|
||||||
"entity_picture",
|
|
||||||
"event_type",
|
|
||||||
"event_types",
|
|
||||||
"fan_mode",
|
|
||||||
"fan_modes",
|
|
||||||
"fan_speed_list",
|
|
||||||
"forecast",
|
|
||||||
"friendly_name",
|
|
||||||
"frontend_stream_type",
|
|
||||||
"has_date",
|
|
||||||
"has_time",
|
|
||||||
"hs_color",
|
|
||||||
"hvac_mode",
|
|
||||||
"hvac_modes",
|
|
||||||
"icon",
|
|
||||||
"id",
|
|
||||||
"latest_version",
|
|
||||||
"max_color_temp_kelvin",
|
|
||||||
"max_mireds",
|
|
||||||
"max_temp",
|
|
||||||
"media_album_name",
|
|
||||||
"media_artist",
|
|
||||||
"media_content_type",
|
|
||||||
"media_position_updated_at",
|
|
||||||
"media_title",
|
|
||||||
"min_color_temp_kelvin",
|
|
||||||
"min_mireds",
|
|
||||||
"min_temp",
|
|
||||||
"mode",
|
|
||||||
"next_dawn",
|
|
||||||
"next_dusk",
|
|
||||||
"next_midnight",
|
|
||||||
"next_noon",
|
|
||||||
"next_rising",
|
|
||||||
"next_setting",
|
|
||||||
"operation_list",
|
|
||||||
"operation_mode",
|
|
||||||
"options",
|
|
||||||
"percentage_step",
|
|
||||||
"precipitation_unit",
|
|
||||||
"preset_mode",
|
|
||||||
"preset_modes",
|
|
||||||
"pressure_unit",
|
|
||||||
"release_notes",
|
|
||||||
"release_summary",
|
|
||||||
"release_url",
|
|
||||||
"restored",
|
|
||||||
"rgb_color",
|
|
||||||
"rgbw_color",
|
|
||||||
"shuffle",
|
|
||||||
"skipped_version",
|
|
||||||
"sound_mode_list",
|
|
||||||
"sound_mode",
|
|
||||||
"source_list",
|
|
||||||
"source_type",
|
|
||||||
"source",
|
|
||||||
"state_class",
|
|
||||||
"step",
|
|
||||||
"supported_color_modes",
|
|
||||||
"supported_features",
|
|
||||||
"swing_mode",
|
|
||||||
"swing_modes",
|
|
||||||
"target_temp_step",
|
|
||||||
"temperature_unit",
|
|
||||||
"title",
|
|
||||||
"token",
|
|
||||||
"unit_of_measurement",
|
|
||||||
"user_id",
|
|
||||||
"uuid",
|
|
||||||
"visibility_unit",
|
|
||||||
"wind_speed_unit",
|
|
||||||
"xy_color",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "lower_limit",
|
|
||||||
type: "select",
|
|
||||||
required: true,
|
|
||||||
options: [
|
|
||||||
[
|
|
||||||
"value",
|
|
||||||
localize(
|
|
||||||
"ui.panel.config.automation.editor.triggers.type.numeric_state.type_value"
|
|
||||||
),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"input",
|
|
||||||
localize(
|
|
||||||
"ui.panel.config.automation.editor.triggers.type.numeric_state.type_input"
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
...(inputAboveIsEntity
|
|
||||||
? ([
|
|
||||||
{
|
|
||||||
name: "above",
|
|
||||||
selector: {
|
|
||||||
entity: { domain: ["input_number", "number", "sensor"] },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
] as const)
|
|
||||||
: ([
|
|
||||||
{
|
|
||||||
name: "above",
|
|
||||||
selector: {
|
|
||||||
number: {
|
|
||||||
mode: "box",
|
|
||||||
min: Number.MIN_SAFE_INTEGER,
|
|
||||||
max: Number.MAX_SAFE_INTEGER,
|
|
||||||
step: 0.1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
] as const)),
|
|
||||||
{
|
|
||||||
name: "upper_limit",
|
|
||||||
type: "select",
|
|
||||||
required: true,
|
|
||||||
options: [
|
|
||||||
[
|
|
||||||
"value",
|
|
||||||
localize(
|
|
||||||
"ui.panel.config.automation.editor.triggers.type.numeric_state.type_value"
|
|
||||||
),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"input",
|
|
||||||
localize(
|
|
||||||
"ui.panel.config.automation.editor.triggers.type.numeric_state.type_input"
|
|
||||||
),
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
...(inputBelowIsEntity
|
|
||||||
? ([
|
|
||||||
{
|
|
||||||
name: "below",
|
|
||||||
selector: {
|
|
||||||
entity: { domain: ["input_number", "number", "sensor"] },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
] as const)
|
|
||||||
: ([
|
|
||||||
{
|
|
||||||
name: "below",
|
|
||||||
selector: {
|
|
||||||
number: {
|
|
||||||
mode: "box",
|
|
||||||
min: Number.MIN_SAFE_INTEGER,
|
|
||||||
max: Number.MAX_SAFE_INTEGER,
|
|
||||||
step: 0.1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
] as const)),
|
|
||||||
{
|
|
||||||
name: "value_template",
|
|
||||||
selector: { template: {} },
|
|
||||||
},
|
|
||||||
{ name: "for", selector: { duration: {} } },
|
|
||||||
] as const
|
|
||||||
);
|
|
||||||
|
|
||||||
public willUpdate(changedProperties: PropertyValues) {
|
public willUpdate(changedProperties: PropertyValues) {
|
||||||
this._inputAboveIsEntity =
|
|
||||||
this._inputAboveIsEntity ??
|
|
||||||
(typeof this.trigger.above === "string" &&
|
|
||||||
((this.trigger.above as string).startsWith("input_number.") ||
|
|
||||||
(this.trigger.above as string).startsWith("number.") ||
|
|
||||||
(this.trigger.above as string).startsWith("sensor.")));
|
|
||||||
this._inputBelowIsEntity =
|
|
||||||
this._inputBelowIsEntity ??
|
|
||||||
(typeof this.trigger.below === "string" &&
|
|
||||||
((this.trigger.below as string).startsWith("input_number.") ||
|
|
||||||
(this.trigger.below as string).startsWith("number.") ||
|
|
||||||
(this.trigger.below as string).startsWith("sensor.")));
|
|
||||||
|
|
||||||
if (!changedProperties.has("trigger")) {
|
if (!changedProperties.has("trigger")) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -258,39 +174,20 @@ export class HaNumericStateTrigger extends LitElement {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _data = memoizeOne(
|
private _data = memoizeOne((trigger: NumericStateTrigger) => ({
|
||||||
(
|
...trigger,
|
||||||
inputAboveIsEntity: boolean,
|
entity_id: ensureArray(trigger.entity_id),
|
||||||
inputBelowIsEntity: boolean,
|
for: createDurationData(trigger.for),
|
||||||
trigger: NumericStateTrigger
|
}));
|
||||||
) => ({
|
|
||||||
lower_limit: inputAboveIsEntity ? "input" : "value",
|
|
||||||
upper_limit: inputBelowIsEntity ? "input" : "value",
|
|
||||||
...trigger,
|
|
||||||
entity_id: ensureArray(trigger.entity_id),
|
|
||||||
for: createDurationData(trigger.for),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const schema = this._schema(
|
const data = this._data(this.trigger);
|
||||||
this.hass.localize,
|
|
||||||
this.trigger.entity_id,
|
|
||||||
this._inputAboveIsEntity,
|
|
||||||
this._inputBelowIsEntity
|
|
||||||
);
|
|
||||||
|
|
||||||
const data = this._data(
|
|
||||||
this._inputAboveIsEntity!,
|
|
||||||
this._inputBelowIsEntity!,
|
|
||||||
this.trigger
|
|
||||||
);
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-form
|
<ha-form
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.data=${data}
|
.data=${data}
|
||||||
.schema=${schema}
|
.schema=${SCHEMA}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
.computeLabel=${this._computeLabelCallback}
|
.computeLabel=${this._computeLabelCallback}
|
||||||
@@ -302,12 +199,6 @@ export class HaNumericStateTrigger extends LitElement {
|
|||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const newTrigger = { ...ev.detail.value };
|
const newTrigger = { ...ev.detail.value };
|
||||||
|
|
||||||
this._inputAboveIsEntity = newTrigger.lower_limit === "input";
|
|
||||||
this._inputBelowIsEntity = newTrigger.upper_limit === "input";
|
|
||||||
|
|
||||||
delete newTrigger.lower_limit;
|
|
||||||
delete newTrigger.upper_limit;
|
|
||||||
|
|
||||||
if (newTrigger.value_template === "") {
|
if (newTrigger.value_template === "") {
|
||||||
delete newTrigger.value_template;
|
delete newTrigger.value_template;
|
||||||
}
|
}
|
||||||
@@ -316,7 +207,7 @@ export class HaNumericStateTrigger extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _computeLabelCallback = (
|
private _computeLabelCallback = (
|
||||||
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
schema: SchemaUnion<typeof SCHEMA>
|
||||||
): string => {
|
): string => {
|
||||||
switch (schema.name) {
|
switch (schema.name) {
|
||||||
case "entity_id":
|
case "entity_id":
|
||||||
|
|||||||
@@ -529,6 +529,10 @@
|
|||||||
"text": {
|
"text": {
|
||||||
"show_password": "Show password",
|
"show_password": "Show password",
|
||||||
"hide_password": "Hide password"
|
"hide_password": "Hide password"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"value": "Value",
|
||||||
|
"entity_value": "Entity value"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"logbook": {
|
"logbook": {
|
||||||
@@ -4150,11 +4154,7 @@
|
|||||||
"label": "Numeric state",
|
"label": "Numeric state",
|
||||||
"above": "Above",
|
"above": "Above",
|
||||||
"below": "Below",
|
"below": "Below",
|
||||||
"lower_limit": "Lower limit",
|
|
||||||
"upper_limit": "Upper limit",
|
|
||||||
"value_template": "Value template",
|
"value_template": "Value template",
|
||||||
"type_value": "Fixed number",
|
|
||||||
"type_input": "Numeric value of another entity",
|
|
||||||
"description": {
|
"description": {
|
||||||
"picker": "When the numeric value of an entity''s state (or attribute''s value) crosses a given threshold.",
|
"picker": "When the numeric value of an entity''s state (or attribute''s value) crosses a given threshold.",
|
||||||
"above": "When {attribute, select, \n undefined {} \n other {{attribute} from }\n }{entity} {numberOfEntities, plural,\n one {is}\n other {are}\n} above {above}{duration, select, \n undefined {} \n other { for {duration}}\n }",
|
"above": "When {attribute, select, \n undefined {} \n other {{attribute} from }\n }{entity} {numberOfEntities, plural,\n one {is}\n other {are}\n} above {above}{duration, select, \n undefined {} \n other { for {duration}}\n }",
|
||||||
|
|||||||
Reference in New Issue
Block a user