mirror of
https://github.com/home-assistant/frontend.git
synced 2026-09-09 05:07:58 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dc1ec0df8 | ||
|
|
c331785cde | ||
|
|
5f3bf10a04 | ||
|
|
e6fee9fb9a | ||
|
|
ec3b85c11b | ||
|
|
ad4536d2a4 |
@@ -133,7 +133,7 @@ const numericThresholdSuffix = (config: {
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const formatNumericLimitValue = (
|
||||
export const formatNumericLimitValue = (
|
||||
hass: HomeAssistant,
|
||||
value?: number | string
|
||||
) => {
|
||||
|
||||
@@ -15,6 +15,7 @@ import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { ensureArray } from "../../../../common/array/ensure-array";
|
||||
import {
|
||||
isEntityReference,
|
||||
isLogicalCondition,
|
||||
logicalChildren,
|
||||
} from "../../../../common/condition/translate";
|
||||
@@ -24,6 +25,12 @@ import { storage } from "../../../../common/decorators/storage";
|
||||
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
||||
import { computeAttributeNameDisplay } from "../../../../common/entity/compute_attribute_display";
|
||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
||||
import {
|
||||
formatListWithAnds,
|
||||
formatListWithOrs,
|
||||
} from "../../../../common/string/format-list";
|
||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||
import "../../../../components/automation/ha-automation-row-event-chip";
|
||||
import "../../../../components/automation/ha-automation-row-live-test";
|
||||
@@ -55,6 +62,7 @@ import {
|
||||
CONDITION_ROW_CONFIG_KEYS,
|
||||
pickRowConfig,
|
||||
} from "../../../../data/automation";
|
||||
import { formatNumericLimitValue } from "../../../../data/automation_i18n";
|
||||
import { ICON_CONDITION } from "../../common/icon-condition";
|
||||
import type {
|
||||
AndCondition,
|
||||
@@ -79,6 +87,9 @@ const NO_ENTITY_CONDITIONS = ["state", "numeric_state"];
|
||||
|
||||
const CONTAINER_CONDITIONS = ["and", "or", "not"];
|
||||
|
||||
const CORE_STATE_ENTITY_ID =
|
||||
/^input_(?:select|text|number|boolean|datetime)\.(?!.+__)(?!_)[\da-z_]+(?<!_)$/;
|
||||
|
||||
const isNoEntityCondition = (condition: string, noEntity: boolean): boolean =>
|
||||
NO_ENTITY_CONDITIONS.includes(condition) && noEntity;
|
||||
|
||||
@@ -426,6 +437,132 @@ export class HaCardConditionEditor extends LitElement {
|
||||
};
|
||||
}
|
||||
|
||||
private _describeCondition(): string | undefined {
|
||||
const condition = this.condition;
|
||||
if (
|
||||
!condition ||
|
||||
typeof condition !== "object" ||
|
||||
Array.isArray(condition) ||
|
||||
("condition" in condition &&
|
||||
condition.condition !== "state" &&
|
||||
condition.condition !== "numeric_state")
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const entityIds = ensureArray(
|
||||
("entity_id" in condition
|
||||
? condition.entity_id
|
||||
: "entity" in condition
|
||||
? condition.entity
|
||||
: undefined) ||
|
||||
(this._entityContext?.mode === "current"
|
||||
? this._entityContext.entityId
|
||||
: undefined) ||
|
||||
[]
|
||||
);
|
||||
const entityNames = entityIds.map((entityId) =>
|
||||
this.hass.states[entityId]
|
||||
? computeStateName(this.hass.states[entityId])
|
||||
: entityId
|
||||
);
|
||||
const entity =
|
||||
"match" in condition && condition.match === "any"
|
||||
? formatListWithOrs(this.hass.locale, entityNames)
|
||||
: formatListWithAnds(this.hass.locale, entityNames);
|
||||
if (!entity) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const stateObj = this.hass.states[entityIds[0]];
|
||||
const attributeName =
|
||||
"attribute" in condition ? condition.attribute : undefined;
|
||||
const attribute =
|
||||
attributeName && stateObj
|
||||
? computeAttributeNameDisplay(
|
||||
this.hass.localize,
|
||||
stateObj,
|
||||
this.hass.entities,
|
||||
attributeName
|
||||
)
|
||||
: attributeName;
|
||||
|
||||
if (!("condition" in condition) || condition.condition === "state") {
|
||||
const stateValue = "state" in condition ? condition.state : undefined;
|
||||
const stateNot =
|
||||
"state_not" in condition ? condition.state_not : undefined;
|
||||
const value = stateValue ?? stateNot;
|
||||
const values = ensureArray(value ?? [])
|
||||
.filter((v) => v !== "")
|
||||
.flatMap<string | number>((v) => {
|
||||
if (!isEntityReference(v)) {
|
||||
return [v];
|
||||
}
|
||||
const referencedState = this.hass.states[v]?.state;
|
||||
if (referencedState === undefined) {
|
||||
return [v];
|
||||
}
|
||||
// Core resolves helper references; legacy conditions also match the literal.
|
||||
if ("entity_id" in condition) {
|
||||
return CORE_STATE_ENTITY_ID.test(v) ? [referencedState] : [v];
|
||||
}
|
||||
return Array.isArray(value) || referencedState
|
||||
? [v, referencedState]
|
||||
: [v];
|
||||
});
|
||||
if (!values.length) {
|
||||
return undefined;
|
||||
}
|
||||
const states = formatListWithOrs(
|
||||
this.hass.locale,
|
||||
values.map((v) =>
|
||||
stateObj
|
||||
? attributeName
|
||||
? this.hass
|
||||
.formatEntityAttributeValue(stateObj, attributeName, v)
|
||||
.toString()
|
||||
: this.hass.formatEntityState(stateObj, String(v))
|
||||
: String(v)
|
||||
)
|
||||
);
|
||||
const invert = stateValue == null && stateNot !== undefined;
|
||||
const variant = invert ? "is_not" : "is";
|
||||
return this.hass.localize(
|
||||
`ui.panel.lovelace.editor.condition-editor.condition.state.description.${
|
||||
attribute ? `${variant}_attribute` : variant
|
||||
}`,
|
||||
{ entity, state: states, attribute }
|
||||
);
|
||||
}
|
||||
|
||||
if (condition.condition === "numeric_state") {
|
||||
const above = "above" in condition ? condition.above : undefined;
|
||||
const below = "below" in condition ? condition.below : undefined;
|
||||
if (above === undefined && below === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const variant =
|
||||
above !== undefined && below !== undefined
|
||||
? "above_below"
|
||||
: above !== undefined
|
||||
? "above"
|
||||
: "below";
|
||||
return this.hass.localize(
|
||||
`ui.panel.lovelace.editor.condition-editor.condition.numeric_state.description.${
|
||||
attribute ? `${variant}_attribute` : variant
|
||||
}`,
|
||||
{
|
||||
entity,
|
||||
above: formatNumericLimitValue(this.hass, above),
|
||||
below: formatNumericLimitValue(this.hass, below),
|
||||
attribute,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
const condition = this._condition;
|
||||
|
||||
@@ -433,6 +570,8 @@ export class HaCardConditionEditor extends LitElement {
|
||||
|
||||
const hideLiveTest = this._hideLiveTest(condition);
|
||||
|
||||
const description = this._describeCondition();
|
||||
|
||||
return html`
|
||||
<div class="container">
|
||||
<ha-expansion-panel left-chevron>
|
||||
@@ -464,9 +603,11 @@ export class HaCardConditionEditor extends LitElement {
|
||||
}
|
||||
<h3 slot="header">
|
||||
${
|
||||
description ||
|
||||
this.hass.localize(
|
||||
`ui.panel.lovelace.editor.condition-editor.condition.${condition.condition}.label`
|
||||
) || condition.condition
|
||||
) ||
|
||||
condition.condition
|
||||
}
|
||||
</h3>
|
||||
<ha-automation-row-event-chip
|
||||
|
||||
@@ -9893,7 +9893,15 @@
|
||||
"label": "Entity numeric state",
|
||||
"attribute": "[%key:ui::panel::lovelace::editor::condition-editor::condition::state::attribute%]",
|
||||
"above": "Above",
|
||||
"below": "Below"
|
||||
"below": "Below",
|
||||
"description": {
|
||||
"above": "{entity} is above {above}",
|
||||
"below": "{entity} is below {below}",
|
||||
"above_below": "{entity} is above {above} and below {below}",
|
||||
"above_attribute": "{entity} {attribute} is above {above}",
|
||||
"below_attribute": "{entity} {attribute} is below {below}",
|
||||
"above_below_attribute": "{entity} {attribute} is above {above} and below {below}"
|
||||
}
|
||||
},
|
||||
"screen": {
|
||||
"label": "Screen",
|
||||
@@ -9911,7 +9919,13 @@
|
||||
"attribute": "Attribute (optional)",
|
||||
"current_entity": "Current entity",
|
||||
"state_equal": "State is equal to",
|
||||
"state_not_equal": "State is not equal to"
|
||||
"state_not_equal": "State is not equal to",
|
||||
"description": {
|
||||
"is": "{entity} is {state}",
|
||||
"is_not": "{entity} is not {state}",
|
||||
"is_attribute": "{entity} {attribute} is {state}",
|
||||
"is_not_attribute": "{entity} {attribute} is not {state}"
|
||||
}
|
||||
},
|
||||
"time": {
|
||||
"label": "Time",
|
||||
|
||||
Reference in New Issue
Block a user