Support to|from null in UI for ha-automation-trigger-state (#15071)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
karwosts 2023-05-31 05:28:16 -07:00 committed by GitHub
parent aea668e754
commit 5217d427e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 70 additions and 9 deletions

View File

@ -19,6 +19,8 @@ class HaEntityStatePicker extends LitElement {
@property() public attribute?: string;
@property() public extraOptions?: any[];
@property({ type: Boolean }) public autofocus = false;
@property({ type: Boolean }) public disabled = false;
@ -43,10 +45,16 @@ class HaEntityStatePicker extends LitElement {
}
protected updated(changedProps: PropertyValues) {
if (changedProps.has("_opened") && this._opened) {
if (
(changedProps.has("_opened") && this._opened) ||
changedProps.has("entityId") ||
changedProps.has("attribute") ||
changedProps.has("extraOptions")
) {
const state = this.entityId ? this.hass.states[this.entityId] : undefined;
(this._comboBox as any).items =
this.entityId && state
(this._comboBox as any).items = [
...(this.extraOptions ?? []),
...(this.entityId && state
? getStates(state, this.attribute).map((key) => ({
value: key,
label: !this.attribute
@ -66,7 +74,8 @@ class HaEntityStatePicker extends LitElement {
key
),
}))
: [];
: []),
];
}
}

View File

@ -34,6 +34,7 @@ export class HaSelectorState extends SubscribeMixin(LitElement) {
this.context?.filter_entity}
.attribute=${this.selector.state?.attribute ||
this.context?.filter_attribute}
.extraOptions=${this.selector.state?.extra_options}
.value=${this.value}
.label=${this.label}
.helper=${this.helper}

View File

@ -301,6 +301,14 @@ export const describeTrigger = (
}
}
if (
!trigger.attribute &&
trigger.from === undefined &&
trigger.to === undefined
) {
base += " state or any attributes";
}
if (trigger.for) {
const duration = describeDuration(trigger.for);
if (duration) {

View File

@ -295,6 +295,7 @@ export interface SelectSelector {
export interface StateSelector {
state: {
extra_options?: { label: string; value: any }[];
entity_id?: string;
attribute?: string;
} | null;

View File

@ -5,6 +5,7 @@ import {
assert,
assign,
literal,
nullable,
number,
object,
optional,
@ -12,6 +13,7 @@ import {
union,
} from "superstruct";
import memoizeOne from "memoize-one";
import type { LocalizeFunc } from "../../../../../common/translations/localize";
import { ensureArray } from "../../../../../common/array/ensure-array";
import { fireEvent } from "../../../../../common/dom/fire_event";
import { hasTemplate } from "../../../../../common/string/has-template";
@ -30,12 +32,14 @@ const stateTriggerStruct = assign(
platform: literal("state"),
entity_id: optional(union([string(), array(string())])),
attribute: optional(string()),
from: optional(string()),
to: optional(string()),
from: optional(nullable(string())),
to: optional(nullable(string())),
for: optional(union([number(), string(), forDictStruct])),
})
);
const ANY_STATE_VALUE = "__ANY_STATE_IGNORE_ATTRIBUTES__";
@customElement("ha-automation-trigger-state")
export class HaStateTrigger extends LitElement implements TriggerElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -49,7 +53,7 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
}
private _schema = memoizeOne(
(entityId, attribute) =>
(localize: LocalizeFunc, entityId, attribute) =>
[
{
name: "entity_id",
@ -117,6 +121,16 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
name: "from",
selector: {
state: {
extra_options: (attribute
? []
: [
{
label: localize(
"ui.panel.config.automation.editor.triggers.type.state.any_state_ignore_attributes"
),
value: ANY_STATE_VALUE,
},
]) as any,
entity_id: entityId ? entityId[0] : undefined,
attribute: attribute,
},
@ -126,6 +140,16 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
name: "to",
selector: {
state: {
extra_options: (attribute
? []
: [
{
label: localize(
"ui.panel.config.automation.editor.triggers.type.state.any_state_ignore_attributes"
),
value: ANY_STATE_VALUE,
},
]) as any,
entity_id: entityId ? entityId[0] : undefined,
attribute: attribute,
},
@ -172,7 +196,17 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
entity_id: ensureArray(this.trigger.entity_id),
for: trgFor,
};
const schema = this._schema(this.trigger.entity_id, this.trigger.attribute);
if (!data.attribute && data.to === null) {
data.to = ANY_STATE_VALUE;
}
if (!data.attribute && data.from === null) {
data.from = ANY_STATE_VALUE;
}
const schema = this._schema(
this.hass.localize,
this.trigger.entity_id,
this.trigger.attribute
);
return html`
<ha-form
@ -190,6 +224,13 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
ev.stopPropagation();
const newTrigger = ev.detail.value;
if (newTrigger.to === ANY_STATE_VALUE) {
newTrigger.to = newTrigger.attribute ? undefined : null;
}
if (newTrigger.from === ANY_STATE_VALUE) {
newTrigger.from = newTrigger.attribute ? undefined : null;
}
Object.keys(newTrigger).forEach((key) =>
newTrigger[key] === undefined || newTrigger[key] === ""
? delete newTrigger[key]

View File

@ -2301,7 +2301,8 @@
"attribute": "Attribute (optional)",
"from": "From (optional)",
"for": "For",
"to": "To (optional)"
"to": "To (optional)",
"any_state_ignore_attributes": "Any state (ignoring attribute changes)"
},
"homeassistant": {
"label": "Home Assistant",