mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-20 15:56:35 +00:00
Update a few Condition Descriptions (#13404)
* Update a few Describe-conditions * Update to multiple states
This commit is contained in:
parent
c82782fa1b
commit
f5b44656cf
@ -1,20 +1,41 @@
|
|||||||
import { dump } from "js-yaml";
|
import { dump } from "js-yaml";
|
||||||
import { html, css, LitElement, TemplateResult } from "lit";
|
import { css, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import "../../../../src/components/ha-card";
|
import "../../../../src/components/ha-card";
|
||||||
import "../../../../src/components/ha-yaml-editor";
|
import "../../../../src/components/ha-yaml-editor";
|
||||||
import { Condition } from "../../../../src/data/automation";
|
import { Condition } from "../../../../src/data/automation";
|
||||||
import { describeCondition } from "../../../../src/data/automation_i18n";
|
import { describeCondition } from "../../../../src/data/automation_i18n";
|
||||||
|
import { getEntity } from "../../../../src/fake_data/entity";
|
||||||
|
import { provideHass } from "../../../../src/fake_data/provide_hass";
|
||||||
|
import { HomeAssistant } from "../../../../src/types";
|
||||||
|
|
||||||
|
const ENTITIES = [
|
||||||
|
getEntity("light", "kitchen", "on", {
|
||||||
|
friendly_name: "Kitchen Light",
|
||||||
|
}),
|
||||||
|
getEntity("device_tracker", "person", "home", {
|
||||||
|
friendly_name: "Person",
|
||||||
|
}),
|
||||||
|
getEntity("zone", "home", "", {
|
||||||
|
friendly_name: "Home",
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
const conditions = [
|
const conditions = [
|
||||||
{ condition: "and" },
|
{ condition: "and" },
|
||||||
{ condition: "not" },
|
{ condition: "not" },
|
||||||
{ condition: "or" },
|
{ condition: "or" },
|
||||||
{ condition: "state" },
|
{ condition: "state", entity_id: "light.kitchen", state: "on" },
|
||||||
{ condition: "numeric_state" },
|
{
|
||||||
|
condition: "numeric_state",
|
||||||
|
entity_id: "light.kitchen",
|
||||||
|
attribute: "brightness",
|
||||||
|
below: 80,
|
||||||
|
above: 20,
|
||||||
|
},
|
||||||
{ condition: "sun", after: "sunset" },
|
{ condition: "sun", after: "sunset" },
|
||||||
{ condition: "sun", after: "sunrise" },
|
{ condition: "sun", after: "sunrise", offset: "-01:00" },
|
||||||
{ condition: "zone" },
|
{ condition: "zone", entity_id: "device_tracker.person", zone: "zone.home" },
|
||||||
{ condition: "time" },
|
{ condition: "time" },
|
||||||
{ condition: "template" },
|
{ condition: "template" },
|
||||||
];
|
];
|
||||||
@ -27,15 +48,21 @@ const initialCondition: Condition = {
|
|||||||
|
|
||||||
@customElement("demo-automation-describe-condition")
|
@customElement("demo-automation-describe-condition")
|
||||||
export class DemoAutomationDescribeCondition extends LitElement {
|
export class DemoAutomationDescribeCondition extends LitElement {
|
||||||
|
@property({ attribute: false }) hass!: HomeAssistant;
|
||||||
|
|
||||||
@state() _condition = initialCondition;
|
@state() _condition = initialCondition;
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
if (!this.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card header="Conditions">
|
<ha-card header="Conditions">
|
||||||
<div class="condition">
|
<div class="condition">
|
||||||
<span>
|
<span>
|
||||||
${this._condition
|
${this._condition
|
||||||
? describeCondition(this._condition)
|
? describeCondition(this._condition, this.hass)
|
||||||
: "<invalid YAML>"}
|
: "<invalid YAML>"}
|
||||||
</span>
|
</span>
|
||||||
<ha-yaml-editor
|
<ha-yaml-editor
|
||||||
@ -48,7 +75,7 @@ export class DemoAutomationDescribeCondition extends LitElement {
|
|||||||
${conditions.map(
|
${conditions.map(
|
||||||
(conf) => html`
|
(conf) => html`
|
||||||
<div class="condition">
|
<div class="condition">
|
||||||
<span>${describeCondition(conf as any)}</span>
|
<span>${describeCondition(conf as any, this.hass)}</span>
|
||||||
<pre>${dump(conf)}</pre>
|
<pre>${dump(conf)}</pre>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
@ -57,6 +84,13 @@ export class DemoAutomationDescribeCondition extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected firstUpdated(changedProps) {
|
||||||
|
super.firstUpdated(changedProps);
|
||||||
|
const hass = provideHass(this);
|
||||||
|
hass.updateTranslations(null, "en");
|
||||||
|
hass.addEntities(ENTITIES);
|
||||||
|
}
|
||||||
|
|
||||||
private _dataChanged(ev: CustomEvent): void {
|
private _dataChanged(ev: CustomEvent): void {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
this._condition = ev.detail.isValid ? ev.detail.value : undefined;
|
this._condition = ev.detail.isValid ? ev.detail.value : undefined;
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import secondsToDuration from "../common/datetime/seconds_to_duration";
|
||||||
|
import { computeStateName } from "../common/entity/compute_state_name";
|
||||||
|
import type { HomeAssistant } from "../types";
|
||||||
import { Condition, Trigger } from "./automation";
|
import { Condition, Trigger } from "./automation";
|
||||||
|
|
||||||
export const describeTrigger = (trigger: Trigger) => {
|
export const describeTrigger = (trigger: Trigger) => {
|
||||||
@ -7,12 +10,176 @@ export const describeTrigger = (trigger: Trigger) => {
|
|||||||
return `${trigger.platform || "Unknown"} trigger`;
|
return `${trigger.platform || "Unknown"} trigger`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const describeCondition = (condition: Condition) => {
|
export const describeCondition = (
|
||||||
|
condition: Condition,
|
||||||
|
hass: HomeAssistant
|
||||||
|
) => {
|
||||||
if (condition.alias) {
|
if (condition.alias) {
|
||||||
return condition.alias;
|
return condition.alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (["or", "and", "not"].includes(condition.condition)) {
|
if (["or", "and", "not"].includes(condition.condition)) {
|
||||||
return `multiple conditions using "${condition.condition}"`;
|
return `multiple conditions using "${condition.condition}"`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// State Condition
|
||||||
|
if (condition.condition === "state" && condition.entity_id) {
|
||||||
|
let base = "Confirm";
|
||||||
|
const stateObj = hass.states[condition.entity_id];
|
||||||
|
const entity = stateObj ? computeStateName(stateObj) : condition.entity_id;
|
||||||
|
|
||||||
|
if ("attribute" in condition) {
|
||||||
|
base += ` ${condition.attribute} from`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let states = "";
|
||||||
|
|
||||||
|
if (Array.isArray(condition.state)) {
|
||||||
|
for (const [index, state] of condition.state.entries()) {
|
||||||
|
states += `${index > 0 ? "," : ""} ${
|
||||||
|
condition.state.length > 1 && index === condition.state.length - 1
|
||||||
|
? "or"
|
||||||
|
: ""
|
||||||
|
} ${state}`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
states = condition.state.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
base += ` ${entity} is ${states}`;
|
||||||
|
|
||||||
|
if ("for" in condition) {
|
||||||
|
let duration: string;
|
||||||
|
if (typeof condition.for === "number") {
|
||||||
|
duration = `for ${secondsToDuration(condition.for)!}`;
|
||||||
|
} else if (typeof condition.for === "string") {
|
||||||
|
duration = `for ${condition.for}`;
|
||||||
|
} else {
|
||||||
|
duration = `for ${JSON.stringify(condition.for)}`;
|
||||||
|
}
|
||||||
|
base += ` for ${duration}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Numeric State Condition
|
||||||
|
if (condition.condition === "numeric_state" && condition.entity_id) {
|
||||||
|
let base = "Confirm";
|
||||||
|
const stateObj = hass.states[condition.entity_id];
|
||||||
|
const entity = stateObj ? computeStateName(stateObj) : condition.entity_id;
|
||||||
|
|
||||||
|
if ("attribute" in condition) {
|
||||||
|
base += ` ${condition.attribute} from`;
|
||||||
|
}
|
||||||
|
|
||||||
|
base += ` ${entity} is`;
|
||||||
|
|
||||||
|
if ("above" in condition) {
|
||||||
|
base += ` above ${condition.above}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("below" in condition && "above" in condition) {
|
||||||
|
base += " and";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("below" in condition) {
|
||||||
|
base += ` below ${condition.below}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sun condition
|
||||||
|
if (
|
||||||
|
condition.condition === "sun" &&
|
||||||
|
("before" in condition || "after" in condition)
|
||||||
|
) {
|
||||||
|
let base = "Confirm";
|
||||||
|
|
||||||
|
if (!condition.after && !condition.before) {
|
||||||
|
base += " sun";
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
base += " sun";
|
||||||
|
|
||||||
|
if (condition.after) {
|
||||||
|
let duration = "";
|
||||||
|
|
||||||
|
if (condition.after_offset) {
|
||||||
|
if (typeof condition.after_offset === "number") {
|
||||||
|
duration = ` offset by ${secondsToDuration(condition.after_offset)!}`;
|
||||||
|
} else if (typeof condition.after_offset === "string") {
|
||||||
|
duration = ` offset by ${condition.after_offset}`;
|
||||||
|
} else {
|
||||||
|
duration = ` offset by ${JSON.stringify(condition.after_offset)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base += ` after ${condition.after}${duration}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condition.before) {
|
||||||
|
base += ` before ${condition.before}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zone condition
|
||||||
|
if (condition.condition === "zone" && condition.entity_id && condition.zone) {
|
||||||
|
let entities = "";
|
||||||
|
let entitiesPlural = false;
|
||||||
|
let zones = "";
|
||||||
|
let zonesPlural = false;
|
||||||
|
|
||||||
|
const states = hass.states;
|
||||||
|
|
||||||
|
if (Array.isArray(condition.entity_id)) {
|
||||||
|
if (condition.entity_id.length > 1) {
|
||||||
|
entitiesPlural = true;
|
||||||
|
}
|
||||||
|
for (const [index, entity] of condition.entity_id.entries()) {
|
||||||
|
if (states[entity]) {
|
||||||
|
entities += `${index > 0 ? "," : ""} ${
|
||||||
|
condition.entity_id.length > 1 &&
|
||||||
|
index === condition.entity_id.length - 1
|
||||||
|
? "or"
|
||||||
|
: ""
|
||||||
|
} ${computeStateName(states[entity]) || entity}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
entities = states[condition.entity_id]
|
||||||
|
? computeStateName(states[condition.entity_id])
|
||||||
|
: condition.entity_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(condition.zone)) {
|
||||||
|
if (condition.zone.length > 1) {
|
||||||
|
zonesPlural = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [index, zone] of condition.zone.entries()) {
|
||||||
|
if (states[zone]) {
|
||||||
|
zones += `${index > 0 ? "," : ""} ${
|
||||||
|
condition.zone.length > 1 && index === condition.zone.length - 1
|
||||||
|
? "or"
|
||||||
|
: ""
|
||||||
|
} ${computeStateName(states[zone]) || zone}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
zones = states[condition.zone]
|
||||||
|
? computeStateName(states[condition.zone])
|
||||||
|
: condition.zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `Confirm ${entities} ${entitiesPlural ? "are" : "is"} in ${zones} ${
|
||||||
|
zonesPlural ? "zones" : "zone"
|
||||||
|
}`;
|
||||||
|
}
|
||||||
|
|
||||||
return `${condition.condition} condition`;
|
return `${condition.condition} condition`;
|
||||||
};
|
};
|
||||||
|
@ -163,7 +163,7 @@ export const describeAction = <T extends ActionType>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "check_condition") {
|
if (actionType === "check_condition") {
|
||||||
return `Test ${describeCondition(action as Condition)}`;
|
return `Test ${describeCondition(action as Condition, hass)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "stop") {
|
if (actionType === "stop") {
|
||||||
@ -177,7 +177,7 @@ export const describeAction = <T extends ActionType>(
|
|||||||
typeof config.if === "string"
|
typeof config.if === "string"
|
||||||
? config.if
|
? config.if
|
||||||
: ensureArray(config.if)
|
: ensureArray(config.if)
|
||||||
.map((condition) => describeCondition(condition))
|
.map((condition) => describeCondition(condition, hass))
|
||||||
.join(", ")
|
.join(", ")
|
||||||
} then ${ensureArray(config.then).map((thenAction) =>
|
} then ${ensureArray(config.then).map((thenAction) =>
|
||||||
describeAction(hass, thenAction)
|
describeAction(hass, thenAction)
|
||||||
@ -200,7 +200,7 @@ export const describeAction = <T extends ActionType>(
|
|||||||
typeof chooseAction.conditions === "string"
|
typeof chooseAction.conditions === "string"
|
||||||
? chooseAction.conditions
|
? chooseAction.conditions
|
||||||
: ensureArray(chooseAction.conditions)
|
: ensureArray(chooseAction.conditions)
|
||||||
.map((condition) => describeCondition(condition))
|
.map((condition) => describeCondition(condition, hass))
|
||||||
.join(", ")
|
.join(", ")
|
||||||
} then ${ensureArray(chooseAction.sequence)
|
} then ${ensureArray(chooseAction.sequence)
|
||||||
.map((chooseSeq) => describeAction(hass, chooseSeq))
|
.map((chooseSeq) => describeAction(hass, chooseSeq))
|
||||||
@ -223,11 +223,11 @@ export const describeAction = <T extends ActionType>(
|
|||||||
)} ${"count" in config.repeat ? `${config.repeat.count} times` : ""}${
|
)} ${"count" in config.repeat ? `${config.repeat.count} times` : ""}${
|
||||||
"while" in config.repeat
|
"while" in config.repeat
|
||||||
? `while ${ensureArray(config.repeat.while)
|
? `while ${ensureArray(config.repeat.while)
|
||||||
.map((condition) => describeCondition(condition))
|
.map((condition) => describeCondition(condition, hass))
|
||||||
.join(", ")} is true`
|
.join(", ")} is true`
|
||||||
: "until" in config.repeat
|
: "until" in config.repeat
|
||||||
? `until ${ensureArray(config.repeat.until)
|
? `until ${ensureArray(config.repeat.until)
|
||||||
.map((condition) => describeCondition(condition))
|
.map((condition) => describeCondition(condition, hass))
|
||||||
.join(", ")} is true`
|
.join(", ")} is true`
|
||||||
: "for_each" in config.repeat
|
: "for_each" in config.repeat
|
||||||
? `for every item: ${ensureArray(config.repeat.for_each)
|
? `for every item: ${ensureArray(config.repeat.for_each)
|
||||||
@ -238,7 +238,7 @@ export const describeAction = <T extends ActionType>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "check_condition") {
|
if (actionType === "check_condition") {
|
||||||
return `Test ${describeCondition(action as Condition)}`;
|
return `Test ${describeCondition(action as Condition, hass)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "device_action") {
|
if (actionType === "device_action") {
|
||||||
|
@ -5,14 +5,17 @@ import { css, CSSResultGroup, html, LitElement } from "lit";
|
|||||||
import { customElement, property, state } 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 { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter";
|
||||||
import { handleStructError } from "../../../../common/structs/handle-errors";
|
import { handleStructError } from "../../../../common/structs/handle-errors";
|
||||||
import "../../../../components/ha-button-menu";
|
|
||||||
import "../../../../components/ha-card";
|
|
||||||
import "../../../../components/buttons/ha-progress-button";
|
import "../../../../components/buttons/ha-progress-button";
|
||||||
import type { HaProgressButton } from "../../../../components/buttons/ha-progress-button";
|
import type { HaProgressButton } from "../../../../components/buttons/ha-progress-button";
|
||||||
import "../../../../components/ha-icon-button";
|
import "../../../../components/ha-button-menu";
|
||||||
|
import "../../../../components/ha-card";
|
||||||
import "../../../../components/ha-expansion-panel";
|
import "../../../../components/ha-expansion-panel";
|
||||||
|
import "../../../../components/ha-icon-button";
|
||||||
import { Condition, testCondition } from "../../../../data/automation";
|
import { Condition, testCondition } from "../../../../data/automation";
|
||||||
|
import { describeCondition } from "../../../../data/automation_i18n";
|
||||||
|
import { validateConfig } from "../../../../data/config";
|
||||||
import {
|
import {
|
||||||
showAlertDialog,
|
showAlertDialog,
|
||||||
showConfirmationDialog,
|
showConfirmationDialog,
|
||||||
@ -20,9 +23,6 @@ import {
|
|||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
import "./ha-automation-condition-editor";
|
import "./ha-automation-condition-editor";
|
||||||
import { validateConfig } from "../../../../data/config";
|
|
||||||
import { describeCondition } from "../../../../data/automation_i18n";
|
|
||||||
import { capitalizeFirstLetter } from "../../../../common/string/capitalize-first-letter";
|
|
||||||
|
|
||||||
export interface ConditionElement extends LitElement {
|
export interface ConditionElement extends LitElement {
|
||||||
condition: Condition;
|
condition: Condition;
|
||||||
@ -81,7 +81,9 @@ export default class HaAutomationConditionRow extends LitElement {
|
|||||||
|
|
||||||
<ha-expansion-panel
|
<ha-expansion-panel
|
||||||
leftChevron
|
leftChevron
|
||||||
.header=${capitalizeFirstLetter(describeCondition(this.condition))}
|
.header=${capitalizeFirstLetter(
|
||||||
|
describeCondition(this.condition, this.hass)
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<ha-progress-button slot="icons" @click=${this._testCondition}>
|
<ha-progress-button slot="icons" @click=${this._testCondition}>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user