mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 11:46:42 +00:00
Convert automation conditions to Lit (#4321)
* Convert automation conditions to Lit * Split condition editor and row * Comments * Update automation.ts * Update automation.ts
This commit is contained in:
parent
e6ac0258e3
commit
073428849e
@ -4,6 +4,7 @@ import {
|
|||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import { navigate } from "../common/navigate";
|
import { navigate } from "../common/navigate";
|
||||||
|
import { DeviceCondition, DeviceTrigger } from "./device_automation";
|
||||||
|
|
||||||
export interface AutomationEntity extends HassEntityBase {
|
export interface AutomationEntity extends HassEntityBase {
|
||||||
attributes: HassEntityAttributeBase & {
|
attributes: HassEntityAttributeBase & {
|
||||||
@ -15,11 +16,162 @@ export interface AutomationEntity extends HassEntityBase {
|
|||||||
export interface AutomationConfig {
|
export interface AutomationConfig {
|
||||||
alias: string;
|
alias: string;
|
||||||
description: string;
|
description: string;
|
||||||
trigger: any[];
|
trigger: Trigger[];
|
||||||
condition?: any[];
|
condition?: Condition[];
|
||||||
action: any[];
|
action: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ForDict {
|
||||||
|
hours?: number | string;
|
||||||
|
minutes?: number | string;
|
||||||
|
seconds?: number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StateTrigger {
|
||||||
|
platform: "state";
|
||||||
|
entity_id?: string;
|
||||||
|
from?: string | number;
|
||||||
|
to?: string | number;
|
||||||
|
for?: string | number | ForDict;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MqttTrigger {
|
||||||
|
platform: "mqtt";
|
||||||
|
topic: string;
|
||||||
|
payload?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GeoLocationTrigger {
|
||||||
|
platform: "geo_location";
|
||||||
|
source: "string";
|
||||||
|
zone: "string";
|
||||||
|
event: "enter" | "leave";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface HassTrigger {
|
||||||
|
platform: "homeassistant";
|
||||||
|
event: "start" | "shutdown";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NumericStateTrigger {
|
||||||
|
platform: "numeric_state";
|
||||||
|
entity_id: string;
|
||||||
|
above?: number;
|
||||||
|
below?: number;
|
||||||
|
value_template?: string;
|
||||||
|
for?: string | number | ForDict;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SunTrigger {
|
||||||
|
platform: "sun";
|
||||||
|
offset: number;
|
||||||
|
event: "sunrise" | "sunset";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TimePatternTrigger {
|
||||||
|
platform: "time_pattern";
|
||||||
|
hours?: number | string;
|
||||||
|
minutes?: number | string;
|
||||||
|
seconds?: number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WebhookTrigger {
|
||||||
|
platform: "webhook";
|
||||||
|
webhook_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ZoneTrigger {
|
||||||
|
platform: "zone";
|
||||||
|
entity_id: string;
|
||||||
|
zone: string;
|
||||||
|
event: "enter" | "leave";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TimeTrigger {
|
||||||
|
platform: "time";
|
||||||
|
at: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TemplateTrigger {
|
||||||
|
platform: "template";
|
||||||
|
value_template: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EventTrigger {
|
||||||
|
platform: "event";
|
||||||
|
event_type: string;
|
||||||
|
event_data: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Trigger =
|
||||||
|
| StateTrigger
|
||||||
|
| MqttTrigger
|
||||||
|
| GeoLocationTrigger
|
||||||
|
| HassTrigger
|
||||||
|
| NumericStateTrigger
|
||||||
|
| SunTrigger
|
||||||
|
| TimePatternTrigger
|
||||||
|
| WebhookTrigger
|
||||||
|
| ZoneTrigger
|
||||||
|
| TimeTrigger
|
||||||
|
| TemplateTrigger
|
||||||
|
| EventTrigger
|
||||||
|
| DeviceTrigger;
|
||||||
|
|
||||||
|
export interface LogicalCondition {
|
||||||
|
condition: "and" | "or";
|
||||||
|
conditions: Condition[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StateCondition {
|
||||||
|
condition: "state";
|
||||||
|
entity_id: string;
|
||||||
|
state: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NumericStateCondition {
|
||||||
|
condition: "numeric_state";
|
||||||
|
entity_id: string;
|
||||||
|
above?: number;
|
||||||
|
below?: number;
|
||||||
|
value_template?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SunCondition {
|
||||||
|
condition: "sun";
|
||||||
|
after_offset: number;
|
||||||
|
before_offset: number;
|
||||||
|
after: "sunrise" | "sunset";
|
||||||
|
before: "sunrise" | "sunset";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ZoneCondition {
|
||||||
|
condition: "zone";
|
||||||
|
entity_id: string;
|
||||||
|
zone: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TimeCondition {
|
||||||
|
condition: "time";
|
||||||
|
after: string;
|
||||||
|
before: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TemplateCondition {
|
||||||
|
condition: "template";
|
||||||
|
value_template: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Condition =
|
||||||
|
| StateCondition
|
||||||
|
| NumericStateCondition
|
||||||
|
| SunCondition
|
||||||
|
| ZoneCondition
|
||||||
|
| TimeCondition
|
||||||
|
| TemplateCondition
|
||||||
|
| DeviceCondition
|
||||||
|
| LogicalCondition;
|
||||||
|
|
||||||
export const deleteAutomation = (hass: HomeAssistant, id: string) =>
|
export const deleteAutomation = (hass: HomeAssistant, id: string) =>
|
||||||
hass.callApi("DELETE", `config/automation/config/${id}`);
|
hass.callApi("DELETE", `config/automation/config/${id}`);
|
||||||
|
|
||||||
|
@ -0,0 +1,128 @@
|
|||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
// tslint:disable-next-line
|
||||||
|
import { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox";
|
||||||
|
import { customElement, html, LitElement, property } from "lit-element";
|
||||||
|
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-card";
|
||||||
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
|
||||||
|
import "./types/ha-automation-condition-device";
|
||||||
|
import "./types/ha-automation-condition-state";
|
||||||
|
import "./types/ha-automation-condition-numeric_state";
|
||||||
|
import "./types/ha-automation-condition-sun";
|
||||||
|
import "./types/ha-automation-condition-template";
|
||||||
|
import "./types/ha-automation-condition-time";
|
||||||
|
import "./types/ha-automation-condition-zone";
|
||||||
|
import "./types/ha-automation-condition-and";
|
||||||
|
import "./types/ha-automation-condition-or";
|
||||||
|
import { Condition } from "../../../../data/automation";
|
||||||
|
|
||||||
|
const OPTIONS = [
|
||||||
|
"device",
|
||||||
|
"and",
|
||||||
|
"or",
|
||||||
|
"state",
|
||||||
|
"numeric_state",
|
||||||
|
"sun",
|
||||||
|
"template",
|
||||||
|
"time",
|
||||||
|
"zone",
|
||||||
|
];
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-editor")
|
||||||
|
export default class HaAutomationConditionEditor extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: Condition;
|
||||||
|
@property() public yamlMode = false;
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.condition) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
const selected = OPTIONS.indexOf(this.condition.condition);
|
||||||
|
const yamlMode = this.yamlMode || selected === -1;
|
||||||
|
return html`
|
||||||
|
${yamlMode
|
||||||
|
? html`
|
||||||
|
<div style="margin-right: 24px;">
|
||||||
|
${selected === -1
|
||||||
|
? html`
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.unsupported_condition",
|
||||||
|
"condition",
|
||||||
|
this.condition.condition
|
||||||
|
)}
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
<ha-yaml-editor
|
||||||
|
.value=${this.condition}
|
||||||
|
@value-changed=${this._onYamlChange}
|
||||||
|
></ha-yaml-editor>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<paper-dropdown-menu-light
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type_select"
|
||||||
|
)}
|
||||||
|
no-animations
|
||||||
|
>
|
||||||
|
<paper-listbox
|
||||||
|
slot="dropdown-content"
|
||||||
|
.selected=${selected}
|
||||||
|
@iron-select=${this._typeChanged}
|
||||||
|
>
|
||||||
|
${OPTIONS.map(
|
||||||
|
(opt) => html`
|
||||||
|
<paper-item .condition=${opt}>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.automation.editor.conditions.type.${opt}.label`
|
||||||
|
)}
|
||||||
|
</paper-item>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu-light>
|
||||||
|
<div>
|
||||||
|
${dynamicElement(
|
||||||
|
`ha-automation-condition-${this.condition.condition}`,
|
||||||
|
{ hass: this.hass, condition: this.condition }
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
`}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _typeChanged(ev: CustomEvent) {
|
||||||
|
const type = ((ev.target as PaperListboxElement)?.selectedItem as any)
|
||||||
|
?.condition;
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const elClass = customElements.get(`ha-automation-condition-${type}`);
|
||||||
|
|
||||||
|
if (type !== this.condition.condition) {
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
condition: type,
|
||||||
|
...elClass.defaultConfig,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onYamlChange(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "value-changed", { value: ev.detail.value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition-editor": HaAutomationConditionEditor;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
import "@polymer/paper-icon-button/paper-icon-button";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
|
import "@polymer/paper-menu-button/paper-menu-button";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
} from "lit-element";
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-card";
|
||||||
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
|
||||||
|
import "./ha-automation-condition-editor";
|
||||||
|
import { Condition } from "../../../../data/automation";
|
||||||
|
|
||||||
|
export interface ConditionElement extends LitElement {
|
||||||
|
condition: Condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const handleChangeEvent = (
|
||||||
|
element: ConditionElement,
|
||||||
|
ev: CustomEvent
|
||||||
|
) => {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const name = (ev.target as any)?.name;
|
||||||
|
if (!name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const newVal = ev.detail.value;
|
||||||
|
|
||||||
|
if ((element.condition[name] || "") === newVal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let newCondition: Condition;
|
||||||
|
if (!newVal) {
|
||||||
|
newCondition = { ...element.condition };
|
||||||
|
delete newCondition[name];
|
||||||
|
} else {
|
||||||
|
newCondition = { ...element.condition, [name]: newVal };
|
||||||
|
}
|
||||||
|
fireEvent(element, "value-changed", { value: newCondition });
|
||||||
|
};
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-row")
|
||||||
|
export default class HaAutomationConditionRow extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: Condition;
|
||||||
|
@property() private _yamlMode = false;
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.condition) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
return html`
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="card-menu">
|
||||||
|
<paper-menu-button
|
||||||
|
no-animations
|
||||||
|
horizontal-align="right"
|
||||||
|
horizontal-offset="-5"
|
||||||
|
vertical-offset="-5"
|
||||||
|
close-on-activate
|
||||||
|
>
|
||||||
|
<paper-icon-button
|
||||||
|
icon="hass:dots-vertical"
|
||||||
|
slot="dropdown-trigger"
|
||||||
|
></paper-icon-button>
|
||||||
|
<paper-listbox slot="dropdown-content">
|
||||||
|
<paper-item @click=${this._switchYamlMode}>
|
||||||
|
${this._yamlMode
|
||||||
|
? this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.edit_ui"
|
||||||
|
)
|
||||||
|
: this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.edit_yaml"
|
||||||
|
)}
|
||||||
|
</paper-item>
|
||||||
|
<paper-item disabled>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.duplicate"
|
||||||
|
)}
|
||||||
|
</paper-item>
|
||||||
|
<paper-item @click=${this._onDelete}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.delete"
|
||||||
|
)}
|
||||||
|
</paper-item>
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-menu-button>
|
||||||
|
</div>
|
||||||
|
<ha-automation-condition-editor
|
||||||
|
.yamlMode=${this._yamlMode}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.condition=${this.condition}
|
||||||
|
></ha-automation-condition-editor>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _onDelete() {
|
||||||
|
if (
|
||||||
|
confirm(
|
||||||
|
this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.delete_confirm"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
fireEvent(this, "value-changed", { value: null });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _switchYamlMode() {
|
||||||
|
this._yamlMode = !this._yamlMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return css`
|
||||||
|
.card-menu {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 3;
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
}
|
||||||
|
.rtl .card-menu {
|
||||||
|
right: auto;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.card-menu paper-item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition-row": HaAutomationConditionRow;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
import {
|
||||||
|
LitElement,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
property,
|
||||||
|
CSSResult,
|
||||||
|
css,
|
||||||
|
} from "lit-element";
|
||||||
|
import "@material/mwc-button";
|
||||||
|
import "../../../../components/ha-card";
|
||||||
|
|
||||||
|
import { HaStateCondition } from "./types/ha-automation-condition-state";
|
||||||
|
|
||||||
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
|
||||||
|
import "./ha-automation-condition-row";
|
||||||
|
import { Condition } from "../../../../data/automation";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition")
|
||||||
|
export default class HaAutomationCondition extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public conditions!: Condition[];
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
return html`
|
||||||
|
${this.conditions.map(
|
||||||
|
(cond, idx) => html`
|
||||||
|
<ha-automation-condition-row
|
||||||
|
.index=${idx}
|
||||||
|
.condition=${cond}
|
||||||
|
@value-changed=${this._conditionChanged}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></ha-automation-condition-row>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-actions add-card">
|
||||||
|
<mwc-button @click=${this._addCondition}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.add"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addCondition() {
|
||||||
|
const conditions = this.conditions.concat({
|
||||||
|
condition: "state",
|
||||||
|
...HaStateCondition.defaultConfig,
|
||||||
|
});
|
||||||
|
|
||||||
|
fireEvent(this, "value-changed", { value: conditions });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _conditionChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const conditions = [...this.conditions];
|
||||||
|
const newValue = ev.detail.value;
|
||||||
|
const index = (ev.target as any).index;
|
||||||
|
|
||||||
|
if (newValue === null) {
|
||||||
|
conditions.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
conditions[index] = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fireEvent(this, "value-changed", { value: conditions });
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return css`
|
||||||
|
ha-automation-condition-row,
|
||||||
|
ha-card {
|
||||||
|
display: block;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
.add-card mwc-button {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition": HaAutomationCondition;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
import { HaLogicalCondition } from "./ha-automation-condition-logical";
|
||||||
|
import { customElement } from "lit-element";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-and")
|
||||||
|
export class HaAndCondition extends HaLogicalCondition {}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition-and": HaAndCondition;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
import "../../../../../components/device/ha-device-picker";
|
||||||
|
import "../../../../../components/device/ha-device-condition-picker";
|
||||||
|
import "../../../../../components/ha-form/ha-form";
|
||||||
|
|
||||||
|
import {
|
||||||
|
fetchDeviceConditionCapabilities,
|
||||||
|
deviceAutomationsEqual,
|
||||||
|
DeviceCondition,
|
||||||
|
} from "../../../../../data/device_automation";
|
||||||
|
import { LitElement, customElement, property, html } from "lit-element";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-device")
|
||||||
|
export class HaDeviceCondition extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: DeviceCondition;
|
||||||
|
@property() private _deviceId?: string;
|
||||||
|
@property() private _capabilities?;
|
||||||
|
private _origCondition?: DeviceCondition;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return {
|
||||||
|
device_id: "",
|
||||||
|
domain: "",
|
||||||
|
entity_id: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (this._deviceId === undefined) {
|
||||||
|
this._deviceId = this.condition.device_id;
|
||||||
|
}
|
||||||
|
const extraFieldsData =
|
||||||
|
this._capabilities && this._capabilities.extra_fields
|
||||||
|
? this._capabilities.extra_fields.map((item) => {
|
||||||
|
return { [item.name]: this.condition[item.name] };
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-device-picker
|
||||||
|
.value=${this._deviceId}
|
||||||
|
@value-changed=${this._devicePicked}
|
||||||
|
.hass=${this.hass}
|
||||||
|
label="Device"
|
||||||
|
></ha-device-picker>
|
||||||
|
<ha-device-condition-picker
|
||||||
|
.value=${this.condition}
|
||||||
|
.deviceId=${this._deviceId}
|
||||||
|
@value-changed=${this._deviceConditionPicked}
|
||||||
|
.hass=${this.hass}
|
||||||
|
label="Condition"
|
||||||
|
></ha-device-condition-picker>
|
||||||
|
${extraFieldsData
|
||||||
|
? html`
|
||||||
|
<ha-form
|
||||||
|
.data=${Object.assign({}, ...extraFieldsData)}
|
||||||
|
.schema=${this._capabilities.extra_fields}
|
||||||
|
.computeLabel=${this._extraFieldsComputeLabelCallback(
|
||||||
|
this.hass.localize
|
||||||
|
)}
|
||||||
|
@value-changed=${this._extraFieldsChanged}
|
||||||
|
></ha-form>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated() {
|
||||||
|
if (!this._capabilities) {
|
||||||
|
this._getCapabilities();
|
||||||
|
}
|
||||||
|
if (this.condition) {
|
||||||
|
this._origCondition = this.condition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedPros) {
|
||||||
|
const prevCondition = changedPros.get("condition");
|
||||||
|
if (
|
||||||
|
prevCondition &&
|
||||||
|
!deviceAutomationsEqual(prevCondition, this.condition)
|
||||||
|
) {
|
||||||
|
this._getCapabilities();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _getCapabilities() {
|
||||||
|
const condition = this.condition;
|
||||||
|
|
||||||
|
this._capabilities = condition.domain
|
||||||
|
? await fetchDeviceConditionCapabilities(this.hass, condition)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _devicePicked(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this._deviceId = ev.target.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _deviceConditionPicked(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
let condition = ev.detail.value;
|
||||||
|
if (
|
||||||
|
this._origCondition &&
|
||||||
|
deviceAutomationsEqual(this._origCondition, condition)
|
||||||
|
) {
|
||||||
|
condition = this._origCondition;
|
||||||
|
}
|
||||||
|
fireEvent(this, "value-changed", { value: condition });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _extraFieldsChanged(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
...this.condition,
|
||||||
|
...ev.detail.value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _extraFieldsComputeLabelCallback(localize) {
|
||||||
|
// Returns a callback for ha-form to calculate labels per schema object
|
||||||
|
return (schema) =>
|
||||||
|
localize(
|
||||||
|
`ui.panel.config.automation.editor.conditions.type.device.extra_fields.${schema.name}`
|
||||||
|
) || schema.name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
import { customElement, html, LitElement, property } from "lit-element";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { ConditionElement } from "../ha-automation-condition-row";
|
||||||
|
import "../ha-automation-condition";
|
||||||
|
import { LogicalCondition } from "../../../../../data/automation";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-logical")
|
||||||
|
export class HaLogicalCondition extends LitElement implements ConditionElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: LogicalCondition;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return { conditions: [{ condition: "state" }] };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
return html`
|
||||||
|
<ha-automation-condition
|
||||||
|
.conditions=${this.condition.conditions || []}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></ha-automation-condition>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.condition, conditions: ev.detail.value },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition-logical": HaLogicalCondition;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "../../../../../components/ha-textarea";
|
||||||
|
|
||||||
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
|
import { LitElement, html, customElement, property } from "lit-element";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { handleChangeEvent } from "../ha-automation-condition-row";
|
||||||
|
import { NumericStateCondition } from "../../../../../data/automation";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-numeric_state")
|
||||||
|
export default class HaNumericStateCondition extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: NumericStateCondition;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return {
|
||||||
|
entity_id: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
const { value_template, entity_id, below, above } = this.condition;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-entity-picker
|
||||||
|
.value="${entity_id}"
|
||||||
|
@value-changed="${this._entityPicked}"
|
||||||
|
.hass="${this.hass}"
|
||||||
|
allow-custom-entity
|
||||||
|
></ha-entity-picker>
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.numeric_state.above"
|
||||||
|
)}
|
||||||
|
name="above"
|
||||||
|
.value=${above}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></paper-input>
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.numeric_state.below"
|
||||||
|
)}
|
||||||
|
name="below"
|
||||||
|
.value=${below}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></paper-input>
|
||||||
|
<ha-textarea
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.numeric_state.value_template"
|
||||||
|
)}
|
||||||
|
name="value_template"
|
||||||
|
.value=${value_template}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
dir="ltr"
|
||||||
|
></ha-textarea>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
|
handleChangeEvent(this, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _entityPicked(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.condition, entity_id: ev.detail.value },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition-numeric_state": HaNumericStateCondition;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
import { HaLogicalCondition } from "./ha-automation-condition-logical";
|
||||||
|
import { customElement } from "lit-element";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-or")
|
||||||
|
export class HaOrCondition extends HaLogicalCondition {}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition-or": HaOrCondition;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import { customElement, html, LitElement, property } from "lit-element";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import {
|
||||||
|
handleChangeEvent,
|
||||||
|
ConditionElement,
|
||||||
|
} from "../ha-automation-condition-row";
|
||||||
|
import { PolymerChangedEvent } from "../../../../../polymer-types";
|
||||||
|
import { StateCondition } from "../../../../../data/automation";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-state")
|
||||||
|
export class HaStateCondition extends LitElement implements ConditionElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: StateCondition;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return { entity_id: "", state: "" };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const { entity_id, state } = this.condition;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<ha-entity-picker
|
||||||
|
.value=${entity_id}
|
||||||
|
@value-changed=${this._entityPicked}
|
||||||
|
.hass=${this.hass}
|
||||||
|
allow-custom-entity
|
||||||
|
></ha-entity-picker>
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.state.state"
|
||||||
|
)}
|
||||||
|
.name=${"state"}
|
||||||
|
.value=${state}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></paper-input>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
|
handleChangeEvent(this, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _entityPicked(ev: PolymerChangedEvent<string>) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.condition, entity_id: ev.detail.value },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition-state": HaStateCondition;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-radio-button/paper-radio-button";
|
||||||
|
import "@polymer/paper-radio-group/paper-radio-group";
|
||||||
|
// tslint:disable-next-line
|
||||||
|
import { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-group";
|
||||||
|
import { LitElement, customElement, property, html } from "lit-element";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import {
|
||||||
|
handleChangeEvent,
|
||||||
|
ConditionElement,
|
||||||
|
} from "../ha-automation-condition-row";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { SunCondition } from "../../../../../data/automation";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-sun")
|
||||||
|
export class HaSunCondition extends LitElement implements ConditionElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: SunCondition;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const { after, after_offset, before, before_offset } = this.condition;
|
||||||
|
return html`
|
||||||
|
<label id="beforelabel">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.sun.before"
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
<paper-radio-group
|
||||||
|
.selected=${before}
|
||||||
|
.name=${"before"}
|
||||||
|
aria-labelledby="beforelabel"
|
||||||
|
@paper-radio-group-changed=${this._radioGroupPicked}
|
||||||
|
>
|
||||||
|
<paper-radio-button name="sunrise">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.sun.sunrise"
|
||||||
|
)}
|
||||||
|
</paper-radio-button>
|
||||||
|
<paper-radio-button name="sunset">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.sun.sunset"
|
||||||
|
)}
|
||||||
|
</paper-radio-button>
|
||||||
|
</paper-radio-group>
|
||||||
|
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.sun.before_offset"
|
||||||
|
)}
|
||||||
|
name="before_offset"
|
||||||
|
.value=${before_offset}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></paper-input>
|
||||||
|
|
||||||
|
<label id="afterlabel">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.sun.after"
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
<paper-radio-group
|
||||||
|
.selected=${after}
|
||||||
|
.name=${"after"}
|
||||||
|
aria-labelledby="afterlabel"
|
||||||
|
@paper-radio-group-changed=${this._radioGroupPicked}
|
||||||
|
>
|
||||||
|
<paper-radio-button name="sunrise">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.sun.sunrise"
|
||||||
|
)}
|
||||||
|
</paper-radio-button>
|
||||||
|
<paper-radio-button name="sunset">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.sun.sunset"
|
||||||
|
)}
|
||||||
|
</paper-radio-button>
|
||||||
|
</paper-radio-group>
|
||||||
|
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.sun.after_offset"
|
||||||
|
)}
|
||||||
|
name="after_offset"
|
||||||
|
.value=${after_offset}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></paper-input>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
|
handleChangeEvent(this, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _radioGroupPicked(ev) {
|
||||||
|
const key = ev.target.name;
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
...this.condition,
|
||||||
|
[key]: (ev.target as PaperRadioGroupElement).selected,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
import "../../../../../components/ha-textarea";
|
||||||
|
import { LitElement, property, html, customElement } from "lit-element";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { handleChangeEvent } from "../ha-automation-condition-row";
|
||||||
|
import { TemplateCondition } from "../../../../../data/automation";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-template")
|
||||||
|
export class HaTemplateCondition extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: TemplateCondition;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return { value_template: "" };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const { value_template } = this.condition;
|
||||||
|
return html`
|
||||||
|
<ha-textarea
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.template.value_template"
|
||||||
|
)}
|
||||||
|
name="value_template"
|
||||||
|
.value=${value_template}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
dir="ltr"
|
||||||
|
></ha-textarea>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
|
handleChangeEvent(this, ev);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import { LitElement, html, property, customElement } from "lit-element";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import {
|
||||||
|
handleChangeEvent,
|
||||||
|
ConditionElement,
|
||||||
|
} from "../ha-automation-condition-row";
|
||||||
|
import { TimeCondition } from "../../../../../data/automation";
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-time")
|
||||||
|
export class HaTimeCondition extends LitElement implements ConditionElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: TimeCondition;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const { after, before } = this.condition;
|
||||||
|
return html`
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.time.after"
|
||||||
|
)}
|
||||||
|
name="after"
|
||||||
|
.value=${after}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></paper-input>
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.time.before"
|
||||||
|
)}
|
||||||
|
name="before"
|
||||||
|
.value=${before}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></paper-input>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
|
handleChangeEvent(this, ev);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
import "@polymer/paper-radio-button/paper-radio-button";
|
||||||
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
|
|
||||||
|
import { hasLocation } from "../../../../../common/entity/has_location";
|
||||||
|
import { computeStateDomain } from "../../../../../common/entity/compute_state_domain";
|
||||||
|
import { LitElement, property, html, customElement } from "lit-element";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { PolymerChangedEvent } from "../../../../../polymer-types";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { ZoneCondition } from "../../../../../data/automation";
|
||||||
|
|
||||||
|
function zoneAndLocationFilter(stateObj) {
|
||||||
|
return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone";
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement("ha-automation-condition-zone")
|
||||||
|
export class HaZoneCondition extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
@property() public condition!: ZoneCondition;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return {
|
||||||
|
entity_id: "",
|
||||||
|
zone: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const { entity_id, zone } = this.condition;
|
||||||
|
return html`
|
||||||
|
<ha-entity-picker
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.zone.entity"
|
||||||
|
)}
|
||||||
|
.value=${entity_id}
|
||||||
|
@value-changed=${this._entityPicked}
|
||||||
|
.hass=${this.hass}
|
||||||
|
allow-custom-entity
|
||||||
|
.entityFilter=${zoneAndLocationFilter}
|
||||||
|
></ha-entity-picker>
|
||||||
|
<ha-entity-picker
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.zone.zone"
|
||||||
|
)}
|
||||||
|
.value=${zone}
|
||||||
|
@value-changed=${this._zonePicked}
|
||||||
|
.hass=${this.hass}
|
||||||
|
allow-custom-entity
|
||||||
|
.includeDomains=${["zone"]}
|
||||||
|
></ha-entity-picker>
|
||||||
|
<label id="eventlabel">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.zone.event"
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _entityPicked(ev: PolymerChangedEvent<string>) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.condition, entity_id: ev.detail.value },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _zonePicked(ev: PolymerChangedEvent<string>) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.condition, zone: ev.detail.value },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-condition-zone": HaZoneCondition;
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,8 @@ import "./types/ha-automation-trigger-time";
|
|||||||
import "./types/ha-automation-trigger-time_pattern";
|
import "./types/ha-automation-trigger-time_pattern";
|
||||||
import "./types/ha-automation-trigger-webhook";
|
import "./types/ha-automation-trigger-webhook";
|
||||||
import "./types/ha-automation-trigger-zone";
|
import "./types/ha-automation-trigger-zone";
|
||||||
import { DeviceTrigger } from "../../../../data/device_automation";
|
|
||||||
|
import { Trigger } from "../../../../data/automation";
|
||||||
|
|
||||||
const OPTIONS = [
|
const OPTIONS = [
|
||||||
"device",
|
"device",
|
||||||
@ -48,103 +49,6 @@ const OPTIONS = [
|
|||||||
"zone",
|
"zone",
|
||||||
];
|
];
|
||||||
|
|
||||||
export interface ForDict {
|
|
||||||
hours?: number | string;
|
|
||||||
minutes?: number | string;
|
|
||||||
seconds?: number | string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StateTrigger {
|
|
||||||
platform: "state";
|
|
||||||
entity_id: string;
|
|
||||||
from?: string | number;
|
|
||||||
to?: string | number;
|
|
||||||
for?: string | number | ForDict;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MqttTrigger {
|
|
||||||
platform: "mqtt";
|
|
||||||
topic: string;
|
|
||||||
payload?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GeoLocationTrigger {
|
|
||||||
platform: "geo_location";
|
|
||||||
source: "string";
|
|
||||||
zone: "string";
|
|
||||||
event: "enter" | "leave";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HassTrigger {
|
|
||||||
platform: "homeassistant";
|
|
||||||
event: "start" | "shutdown";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface NumericStateTrigger {
|
|
||||||
platform: "numeric_state";
|
|
||||||
entity_id: string;
|
|
||||||
above?: number;
|
|
||||||
below?: number;
|
|
||||||
value_template?: string;
|
|
||||||
for?: string | number | ForDict;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SunTrigger {
|
|
||||||
platform: "sun";
|
|
||||||
offset: number;
|
|
||||||
event: "sunrise" | "sunset";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TimePatternTrigger {
|
|
||||||
platform: "time_pattern";
|
|
||||||
hours?: number | string;
|
|
||||||
minutes?: number | string;
|
|
||||||
seconds?: number | string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface WebhookTrigger {
|
|
||||||
platform: "webhook";
|
|
||||||
webhook_id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ZoneTrigger {
|
|
||||||
platform: "zone";
|
|
||||||
entity_id: string;
|
|
||||||
zone: string;
|
|
||||||
event: "enter" | "leave";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TimeTrigger {
|
|
||||||
platform: "time";
|
|
||||||
at: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TemplateTrigger {
|
|
||||||
platform: "template";
|
|
||||||
value_template: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EventTrigger {
|
|
||||||
platform: "event";
|
|
||||||
event_type: string;
|
|
||||||
event_data: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Trigger =
|
|
||||||
| StateTrigger
|
|
||||||
| MqttTrigger
|
|
||||||
| GeoLocationTrigger
|
|
||||||
| HassTrigger
|
|
||||||
| NumericStateTrigger
|
|
||||||
| SunTrigger
|
|
||||||
| TimePatternTrigger
|
|
||||||
| WebhookTrigger
|
|
||||||
| ZoneTrigger
|
|
||||||
| TimeTrigger
|
|
||||||
| TemplateTrigger
|
|
||||||
| EventTrigger
|
|
||||||
| DeviceTrigger;
|
|
||||||
|
|
||||||
export interface TriggerElement extends LitElement {
|
export interface TriggerElement extends LitElement {
|
||||||
trigger: Trigger;
|
trigger: Trigger;
|
||||||
}
|
}
|
||||||
@ -181,11 +85,9 @@ export default class HaAutomationTriggerRow extends LitElement {
|
|||||||
if (!this.trigger) {
|
if (!this.trigger) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
const hasEditor = OPTIONS.includes(this.trigger.platform);
|
|
||||||
if (!hasEditor) {
|
|
||||||
this._yamlMode = true;
|
|
||||||
}
|
|
||||||
const selected = OPTIONS.indexOf(this.trigger.platform);
|
const selected = OPTIONS.indexOf(this.trigger.platform);
|
||||||
|
const yamlMode = this._yamlMode || selected === -1;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card>
|
<ha-card>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
@ -202,8 +104,11 @@ export default class HaAutomationTriggerRow extends LitElement {
|
|||||||
slot="dropdown-trigger"
|
slot="dropdown-trigger"
|
||||||
></paper-icon-button>
|
></paper-icon-button>
|
||||||
<paper-listbox slot="dropdown-content">
|
<paper-listbox slot="dropdown-content">
|
||||||
<paper-item @click=${this._switchYamlMode}>
|
<paper-item
|
||||||
${this._yamlMode
|
@click=${this._switchYamlMode}
|
||||||
|
.disabled=${selected === -1}
|
||||||
|
>
|
||||||
|
${yamlMode
|
||||||
? this.hass.localize(
|
? this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.edit_ui"
|
"ui.panel.config.automation.editor.edit_ui"
|
||||||
)
|
)
|
||||||
@ -224,10 +129,10 @@ export default class HaAutomationTriggerRow extends LitElement {
|
|||||||
</paper-listbox>
|
</paper-listbox>
|
||||||
</paper-menu-button>
|
</paper-menu-button>
|
||||||
</div>
|
</div>
|
||||||
${this._yamlMode
|
${yamlMode
|
||||||
? html`
|
? html`
|
||||||
<div style="margin-right: 24px;">
|
<div style="margin-right: 24px;">
|
||||||
${!hasEditor
|
${selected === -1
|
||||||
? html`
|
? html`
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.unsupported_platform",
|
"ui.panel.config.automation.editor.triggers.unsupported_platform",
|
||||||
|
@ -13,15 +13,16 @@ import { fireEvent } from "../../../../common/dom/fire_event";
|
|||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
|
||||||
import "./ha-automation-trigger-row";
|
import "./ha-automation-trigger-row";
|
||||||
|
import { HaStateTrigger } from "./types/ha-automation-trigger-state";
|
||||||
|
import { Trigger } from "../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger")
|
@customElement("ha-automation-trigger")
|
||||||
export default class HaAutomationTrigger extends LitElement {
|
export default class HaAutomationTrigger extends LitElement {
|
||||||
@property() public hass!: HomeAssistant;
|
@property() public hass!: HomeAssistant;
|
||||||
@property() public triggers;
|
@property() public triggers!: Trigger[];
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="triggers">
|
|
||||||
${this.triggers.map(
|
${this.triggers.map(
|
||||||
(trg, idx) => html`
|
(trg, idx) => html`
|
||||||
<ha-automation-trigger-row
|
<ha-automation-trigger-row
|
||||||
@ -41,13 +42,13 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
</mwc-button>
|
</mwc-button>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addTrigger() {
|
private _addTrigger() {
|
||||||
const triggers = this.triggers.concat({
|
const triggers = this.triggers.concat({
|
||||||
platform: "state",
|
platform: "state",
|
||||||
|
...HaStateTrigger.defaultConfig,
|
||||||
});
|
});
|
||||||
|
|
||||||
fireEvent(this, "value-changed", { value: triggers });
|
fireEvent(this, "value-changed", { value: triggers });
|
||||||
@ -70,12 +71,9 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
.triggers,
|
ha-automation-trigger-row,
|
||||||
.script {
|
ha-card {
|
||||||
margin-top: -16px;
|
display: block;
|
||||||
}
|
|
||||||
.triggers ha-card,
|
|
||||||
.script ha-card {
|
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
.add-card mwc-button {
|
.add-card mwc-button {
|
||||||
|
@ -4,11 +4,11 @@ import "../../../../../components/ha-yaml-editor";
|
|||||||
import { LitElement, property, customElement } from "lit-element";
|
import { LitElement, property, customElement } from "lit-element";
|
||||||
import {
|
import {
|
||||||
TriggerElement,
|
TriggerElement,
|
||||||
EventTrigger,
|
|
||||||
handleChangeEvent,
|
handleChangeEvent,
|
||||||
} from "../ha-automation-trigger-row";
|
} from "../ha-automation-trigger-row";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import { html } from "lit-html";
|
import { html } from "lit-html";
|
||||||
|
import { EventTrigger } from "../../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-event")
|
@customElement("ha-automation-trigger-event")
|
||||||
export class HaEventTrigger extends LitElement implements TriggerElement {
|
export class HaEventTrigger extends LitElement implements TriggerElement {
|
||||||
|
@ -5,11 +5,9 @@ import { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-g
|
|||||||
import "../../../../../components/entity/ha-entity-picker";
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
import { LitElement, customElement, property, html } from "lit-element";
|
import { LitElement, customElement, property, html } from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import { handleChangeEvent } from "../ha-automation-trigger-row";
|
||||||
GeoLocationTrigger,
|
|
||||||
handleChangeEvent,
|
|
||||||
} from "../ha-automation-trigger-row";
|
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { GeoLocationTrigger } from "../../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-geo_location")
|
@customElement("ha-automation-trigger-geo_location")
|
||||||
export default class HaGeolocationTrigger extends LitElement {
|
export default class HaGeolocationTrigger extends LitElement {
|
||||||
|
@ -5,7 +5,7 @@ import { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-g
|
|||||||
import { LitElement, html, property, customElement } from "lit-element";
|
import { LitElement, html, property, customElement } from "lit-element";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import { HassTrigger } from "../ha-automation-trigger-row";
|
import { HassTrigger } from "../../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-homeassistant")
|
@customElement("ha-automation-trigger-homeassistant")
|
||||||
export default class HaHassTrigger extends LitElement {
|
export default class HaHassTrigger extends LitElement {
|
||||||
|
@ -4,8 +4,8 @@ import { HomeAssistant } from "../../../../../types";
|
|||||||
import {
|
import {
|
||||||
handleChangeEvent,
|
handleChangeEvent,
|
||||||
TriggerElement,
|
TriggerElement,
|
||||||
MqttTrigger,
|
|
||||||
} from "../ha-automation-trigger-row";
|
} from "../ha-automation-trigger-row";
|
||||||
|
import { MqttTrigger } from "../../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-mqtt")
|
@customElement("ha-automation-trigger-mqtt")
|
||||||
export class HaMQTTTrigger extends LitElement implements TriggerElement {
|
export class HaMQTTTrigger extends LitElement implements TriggerElement {
|
||||||
|
@ -5,11 +5,8 @@ import "../../../../../components/entity/ha-entity-picker";
|
|||||||
import { LitElement, html, customElement, property } from "lit-element";
|
import { LitElement, html, customElement, property } from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import {
|
import { handleChangeEvent } from "../ha-automation-trigger-row";
|
||||||
NumericStateTrigger,
|
import { NumericStateTrigger, ForDict } from "../../../../../data/automation";
|
||||||
ForDict,
|
|
||||||
handleChangeEvent,
|
|
||||||
} from "../ha-automation-trigger-row";
|
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-numeric_state")
|
@customElement("ha-automation-trigger-numeric_state")
|
||||||
export default class HaNumericStateTrigger extends LitElement {
|
export default class HaNumericStateTrigger extends LitElement {
|
||||||
|
@ -6,10 +6,9 @@ import { HomeAssistant } from "../../../../../types";
|
|||||||
import {
|
import {
|
||||||
handleChangeEvent,
|
handleChangeEvent,
|
||||||
TriggerElement,
|
TriggerElement,
|
||||||
StateTrigger,
|
|
||||||
ForDict,
|
|
||||||
} from "../ha-automation-trigger-row";
|
} from "../ha-automation-trigger-row";
|
||||||
import { PolymerChangedEvent } from "../../../../../polymer-types";
|
import { PolymerChangedEvent } from "../../../../../polymer-types";
|
||||||
|
import { StateTrigger, ForDict } from "../../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-state")
|
@customElement("ha-automation-trigger-state")
|
||||||
export class HaStateTrigger extends LitElement implements TriggerElement {
|
export class HaStateTrigger extends LitElement implements TriggerElement {
|
||||||
|
@ -6,11 +6,11 @@ import { PaperRadioGroupElement } from "@polymer/paper-radio-group/paper-radio-g
|
|||||||
import { LitElement, customElement, property, html } from "lit-element";
|
import { LitElement, customElement, property, html } from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import {
|
||||||
SunTrigger,
|
|
||||||
handleChangeEvent,
|
handleChangeEvent,
|
||||||
TriggerElement,
|
TriggerElement,
|
||||||
} from "../ha-automation-trigger-row";
|
} from "../ha-automation-trigger-row";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { SunTrigger } from "../../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-sun")
|
@customElement("ha-automation-trigger-sun")
|
||||||
export class HaSunTrigger extends LitElement implements TriggerElement {
|
export class HaSunTrigger extends LitElement implements TriggerElement {
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import "../../../../../components/ha-textarea";
|
import "../../../../../components/ha-textarea";
|
||||||
import { LitElement, property, html, customElement } from "lit-element";
|
import { LitElement, property, html, customElement } from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import { handleChangeEvent } from "../ha-automation-trigger-row";
|
||||||
TemplateTrigger,
|
import { TemplateTrigger } from "../../../../../data/automation";
|
||||||
handleChangeEvent,
|
|
||||||
} from "../ha-automation-trigger-row";
|
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-template")
|
@customElement("ha-automation-trigger-template")
|
||||||
export class HaTemplateTrigger extends LitElement {
|
export class HaTemplateTrigger extends LitElement {
|
||||||
|
@ -2,10 +2,10 @@ import "@polymer/paper-input/paper-input";
|
|||||||
import { LitElement, html, property, customElement } from "lit-element";
|
import { LitElement, html, property, customElement } from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import {
|
||||||
TimeTrigger,
|
|
||||||
handleChangeEvent,
|
handleChangeEvent,
|
||||||
TriggerElement,
|
TriggerElement,
|
||||||
} from "../ha-automation-trigger-row";
|
} from "../ha-automation-trigger-row";
|
||||||
|
import { TimeTrigger } from "../../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-time")
|
@customElement("ha-automation-trigger-time")
|
||||||
export class HaTimeTrigger extends LitElement implements TriggerElement {
|
export class HaTimeTrigger extends LitElement implements TriggerElement {
|
||||||
|
@ -3,9 +3,9 @@ import { LitElement, property, html, customElement } from "lit-element";
|
|||||||
import {
|
import {
|
||||||
TriggerElement,
|
TriggerElement,
|
||||||
handleChangeEvent,
|
handleChangeEvent,
|
||||||
TimePatternTrigger,
|
|
||||||
} from "../ha-automation-trigger-row";
|
} from "../ha-automation-trigger-row";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { TimePatternTrigger } from "../../../../../data/automation";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-time_pattern")
|
@customElement("ha-automation-trigger-time_pattern")
|
||||||
export class HaTimePatternTrigger extends LitElement implements TriggerElement {
|
export class HaTimePatternTrigger extends LitElement implements TriggerElement {
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import { LitElement, customElement, property, html } from "lit-element";
|
import { LitElement, customElement, property, html } from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import { handleChangeEvent } from "../ha-automation-trigger-row";
|
||||||
WebhookTrigger,
|
import { WebhookTrigger } from "../../../../../data/automation";
|
||||||
handleChangeEvent,
|
|
||||||
} from "../ha-automation-trigger-row";
|
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-webhook")
|
@customElement("ha-automation-trigger-webhook")
|
||||||
export class HaWebhookTrigger extends LitElement {
|
export class HaWebhookTrigger extends LitElement {
|
||||||
|
@ -8,9 +8,9 @@ import { hasLocation } from "../../../../../common/entity/has_location";
|
|||||||
import { computeStateDomain } from "../../../../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../../../../common/entity/compute_state_domain";
|
||||||
import { LitElement, property, html, customElement } from "lit-element";
|
import { LitElement, property, html, customElement } from "lit-element";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import { ZoneTrigger } from "../ha-automation-trigger-row";
|
|
||||||
import { PolymerChangedEvent } from "../../../../../polymer-types";
|
import { PolymerChangedEvent } from "../../../../../polymer-types";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import { ZoneTrigger } from "../../../../../data/automation";
|
||||||
|
|
||||||
function zoneAndLocationFilter(stateObj) {
|
function zoneAndLocationFilter(stateObj) {
|
||||||
return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone";
|
return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone";
|
||||||
|
@ -6,8 +6,8 @@ import "../../../components/ha-card";
|
|||||||
import "../../../components/ha-textarea";
|
import "../../../components/ha-textarea";
|
||||||
|
|
||||||
import "../automation/trigger/ha-automation-trigger";
|
import "../automation/trigger/ha-automation-trigger";
|
||||||
|
import "../automation/condition/ha-automation-condition";
|
||||||
|
|
||||||
import Condition from "./condition/index";
|
|
||||||
import Script from "./script/index";
|
import Script from "./script/index";
|
||||||
|
|
||||||
export default class Automation extends Component<any> {
|
export default class Automation extends Component<any> {
|
||||||
@ -31,8 +31,11 @@ export default class Automation extends Component<any> {
|
|||||||
this.props.onChange({ ...this.props.automation, trigger: ev.detail.value });
|
this.props.onChange({ ...this.props.automation, trigger: ev.detail.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
public conditionChanged(condition) {
|
public conditionChanged(ev: CustomEvent) {
|
||||||
this.props.onChange({ ...this.props.automation, condition });
|
this.props.onChange({
|
||||||
|
...this.props.automation,
|
||||||
|
condition: ev.detail.value,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public actionChanged(action) {
|
public actionChanged(action) {
|
||||||
@ -117,11 +120,10 @@ export default class Automation extends Component<any> {
|
|||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<Condition
|
<ha-automation-condition
|
||||||
condition={condition || []}
|
conditions={condition || []}
|
||||||
onChange={this.conditionChanged}
|
onvalue-changed={this.conditionChanged}
|
||||||
hass={hass}
|
hass={hass}
|
||||||
localize={localize}
|
|
||||||
/>
|
/>
|
||||||
</ha-config-section>
|
</ha-config-section>
|
||||||
|
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
import { h, Component } from "preact";
|
|
||||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
|
||||||
import "@polymer/paper-item/paper-item";
|
|
||||||
|
|
||||||
import YAMLTextArea from "../yaml_textarea";
|
|
||||||
|
|
||||||
import DeviceCondition from "./device";
|
|
||||||
import LogicalCondition from "./logical";
|
|
||||||
import NumericStateCondition from "./numeric_state";
|
|
||||||
import StateCondition from "./state";
|
|
||||||
import SunCondition from "./sun";
|
|
||||||
import TemplateCondition from "./template";
|
|
||||||
import TimeCondition from "./time";
|
|
||||||
import ZoneCondition from "./zone";
|
|
||||||
|
|
||||||
const TYPES = {
|
|
||||||
and: LogicalCondition,
|
|
||||||
device: DeviceCondition,
|
|
||||||
numeric_state: NumericStateCondition,
|
|
||||||
or: LogicalCondition,
|
|
||||||
state: StateCondition,
|
|
||||||
sun: SunCondition,
|
|
||||||
template: TemplateCondition,
|
|
||||||
time: TimeCondition,
|
|
||||||
zone: ZoneCondition,
|
|
||||||
};
|
|
||||||
|
|
||||||
const OPTIONS = Object.keys(TYPES).sort();
|
|
||||||
|
|
||||||
export default class ConditionEdit extends Component<any> {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.typeChanged = this.typeChanged.bind(this);
|
|
||||||
this.onYamlChange = this.onYamlChange.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public typeChanged(ev) {
|
|
||||||
const type = ev.target.selectedItem.attributes.condition.value;
|
|
||||||
|
|
||||||
if (type !== this.props.condition.condition) {
|
|
||||||
this.props.onChange(this.props.index, {
|
|
||||||
condition: type,
|
|
||||||
...TYPES[type].defaultConfig,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public render({ index, condition, onChange, hass, localize, yamlMode }) {
|
|
||||||
// tslint:disable-next-line: variable-name
|
|
||||||
const Comp = TYPES[condition.condition];
|
|
||||||
const selected = OPTIONS.indexOf(condition.condition);
|
|
||||||
|
|
||||||
if (yamlMode || !Comp) {
|
|
||||||
return (
|
|
||||||
<div style="margin-right: 24px;">
|
|
||||||
{!Comp && (
|
|
||||||
<div>
|
|
||||||
{localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.unsupported_condition",
|
|
||||||
"condition",
|
|
||||||
condition.condition
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<YAMLTextArea value={condition} onChange={this.onYamlChange} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<paper-dropdown-menu-light
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type_select"
|
|
||||||
)}
|
|
||||||
no-animations
|
|
||||||
>
|
|
||||||
<paper-listbox
|
|
||||||
slot="dropdown-content"
|
|
||||||
selected={selected}
|
|
||||||
oniron-select={this.typeChanged}
|
|
||||||
>
|
|
||||||
{OPTIONS.map((opt) => (
|
|
||||||
<paper-item condition={opt}>
|
|
||||||
{localize(
|
|
||||||
`ui.panel.config.automation.editor.conditions.type.${opt}.label`
|
|
||||||
)}
|
|
||||||
</paper-item>
|
|
||||||
))}
|
|
||||||
</paper-listbox>
|
|
||||||
</paper-dropdown-menu-light>
|
|
||||||
<Comp
|
|
||||||
index={index}
|
|
||||||
condition={condition}
|
|
||||||
onChange={onChange}
|
|
||||||
hass={hass}
|
|
||||||
localize={localize}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private onYamlChange(condition) {
|
|
||||||
this.props.onChange(this.props.index, condition);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
import { h, Component } from "preact";
|
|
||||||
import "@polymer/paper-menu-button/paper-menu-button";
|
|
||||||
import "@polymer/paper-icon-button/paper-icon-button";
|
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
|
||||||
import "@polymer/paper-item/paper-item";
|
|
||||||
import "../../../../components/ha-card";
|
|
||||||
|
|
||||||
import ConditionEdit from "./condition_edit";
|
|
||||||
|
|
||||||
export default class ConditionRow extends Component<any> {
|
|
||||||
public state: { yamlMode: boolean };
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
yamlMode: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
this.onDelete = this.onDelete.bind(this);
|
|
||||||
this.switchYamlMode = this.switchYamlMode.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public onDelete() {
|
|
||||||
// eslint-disable-next-line
|
|
||||||
if (
|
|
||||||
confirm(
|
|
||||||
this.props.localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.delete_confirm"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
this.props.onChange(this.props.index, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(props, { yamlMode }) {
|
|
||||||
return (
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-content">
|
|
||||||
<div class="card-menu" style="z-index: 3">
|
|
||||||
<paper-menu-button
|
|
||||||
no-animations
|
|
||||||
horizontal-align="right"
|
|
||||||
horizontal-offset="-5"
|
|
||||||
vertical-offset="-5"
|
|
||||||
close-on-activate
|
|
||||||
>
|
|
||||||
<paper-icon-button
|
|
||||||
icon="hass:dots-vertical"
|
|
||||||
slot="dropdown-trigger"
|
|
||||||
/>
|
|
||||||
<paper-listbox slot="dropdown-content">
|
|
||||||
<paper-item onTap={this.switchYamlMode}>
|
|
||||||
{yamlMode
|
|
||||||
? props.localize(
|
|
||||||
"ui.panel.config.automation.editor.edit_ui"
|
|
||||||
)
|
|
||||||
: props.localize(
|
|
||||||
"ui.panel.config.automation.editor.edit_yaml"
|
|
||||||
)}
|
|
||||||
</paper-item>
|
|
||||||
<paper-item disabled>
|
|
||||||
{props.localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.duplicate"
|
|
||||||
)}
|
|
||||||
</paper-item>
|
|
||||||
<paper-item onTap={this.onDelete}>
|
|
||||||
{props.localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.delete"
|
|
||||||
)}
|
|
||||||
</paper-item>
|
|
||||||
</paper-listbox>
|
|
||||||
</paper-menu-button>
|
|
||||||
</div>
|
|
||||||
<ConditionEdit {...props} yamlMode={yamlMode} />
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private switchYamlMode() {
|
|
||||||
this.setState({
|
|
||||||
yamlMode: !this.state.yamlMode,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,133 +0,0 @@
|
|||||||
import { h } from "preact";
|
|
||||||
|
|
||||||
import "../../../../components/device/ha-device-picker";
|
|
||||||
import "../../../../components/device/ha-device-condition-picker";
|
|
||||||
import "../../../../components/ha-form/ha-form";
|
|
||||||
|
|
||||||
import {
|
|
||||||
fetchDeviceConditionCapabilities,
|
|
||||||
deviceAutomationsEqual,
|
|
||||||
} from "../../../../data/device_automation";
|
|
||||||
|
|
||||||
import { AutomationComponent } from "../automation-component";
|
|
||||||
|
|
||||||
export default class DeviceCondition extends AutomationComponent<any, any> {
|
|
||||||
private _origCondition;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.devicePicked = this.devicePicked.bind(this);
|
|
||||||
this.deviceConditionPicked = this.deviceConditionPicked.bind(this);
|
|
||||||
this._extraFieldsChanged = this._extraFieldsChanged.bind(this);
|
|
||||||
this.state = { device_id: undefined, capabilities: undefined };
|
|
||||||
}
|
|
||||||
|
|
||||||
public devicePicked(ev) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.setState({ ...this.state, device_id: ev.target.value });
|
|
||||||
}
|
|
||||||
|
|
||||||
public deviceConditionPicked(ev) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let condition = ev.target.value;
|
|
||||||
if (
|
|
||||||
this._origCondition &&
|
|
||||||
deviceAutomationsEqual(this._origCondition, condition)
|
|
||||||
) {
|
|
||||||
condition = this._origCondition;
|
|
||||||
}
|
|
||||||
this.props.onChange(this.props.index, condition);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
public render({ condition, hass }, { device_id, capabilities }) {
|
|
||||||
if (device_id === undefined) {
|
|
||||||
device_id = condition.device_id;
|
|
||||||
}
|
|
||||||
const extraFieldsData =
|
|
||||||
capabilities && capabilities.extra_fields
|
|
||||||
? capabilities.extra_fields.map((item) => {
|
|
||||||
return { [item.name]: this.props.condition[item.name] };
|
|
||||||
})
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<ha-device-picker
|
|
||||||
value={device_id}
|
|
||||||
onChange={this.devicePicked}
|
|
||||||
hass={hass}
|
|
||||||
label="Device"
|
|
||||||
/>
|
|
||||||
<ha-device-condition-picker
|
|
||||||
value={condition}
|
|
||||||
deviceId={device_id}
|
|
||||||
onChange={this.deviceConditionPicked}
|
|
||||||
hass={hass}
|
|
||||||
label="Condition"
|
|
||||||
/>
|
|
||||||
{extraFieldsData && (
|
|
||||||
<ha-form
|
|
||||||
data={Object.assign({}, ...extraFieldsData)}
|
|
||||||
schema={this.state.capabilities.extra_fields}
|
|
||||||
computeLabel={this._extraFieldsComputeLabelCallback(hass.localize)}
|
|
||||||
onvalue-changed={this._extraFieldsChanged}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentDidMount() {
|
|
||||||
this.initialized = true;
|
|
||||||
if (!this.state.capabilities) {
|
|
||||||
this._getCapabilities();
|
|
||||||
}
|
|
||||||
if (this.props.condition) {
|
|
||||||
this._origCondition = this.props.condition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentDidUpdate(prevProps) {
|
|
||||||
if (!deviceAutomationsEqual(prevProps.condition, this.props.condition)) {
|
|
||||||
this._getCapabilities();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async _getCapabilities() {
|
|
||||||
const condition = this.props.condition;
|
|
||||||
|
|
||||||
const capabilities = condition.domain
|
|
||||||
? await fetchDeviceConditionCapabilities(this.props.hass, condition)
|
|
||||||
: null;
|
|
||||||
this.setState({ ...this.state, capabilities });
|
|
||||||
}
|
|
||||||
|
|
||||||
private _extraFieldsChanged(ev) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.props.onChange(this.props.index, {
|
|
||||||
...this.props.condition,
|
|
||||||
...ev.detail.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private _extraFieldsComputeLabelCallback(localize) {
|
|
||||||
// Returns a callback for ha-form to calculate labels per schema object
|
|
||||||
return (schema) =>
|
|
||||||
localize(
|
|
||||||
`ui.panel.config.automation.editor.condition.type.device.extra_fields.${schema.name}`
|
|
||||||
) || schema.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(DeviceCondition as any).defaultConfig = {
|
|
||||||
device_id: "",
|
|
||||||
domain: "",
|
|
||||||
entity_id: "",
|
|
||||||
};
|
|
@ -1,57 +0,0 @@
|
|||||||
import { h, Component } from "preact";
|
|
||||||
import "@material/mwc-button";
|
|
||||||
import "../../../../components/ha-card";
|
|
||||||
|
|
||||||
import ConditionRow from "./condition_row";
|
|
||||||
|
|
||||||
export default class Condition extends Component<any> {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.addCondition = this.addCondition.bind(this);
|
|
||||||
this.conditionChanged = this.conditionChanged.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public addCondition() {
|
|
||||||
const condition = this.props.condition.concat({
|
|
||||||
condition: "state",
|
|
||||||
});
|
|
||||||
|
|
||||||
this.props.onChange(condition);
|
|
||||||
}
|
|
||||||
|
|
||||||
public conditionChanged(index, newValue) {
|
|
||||||
const condition = this.props.condition.concat();
|
|
||||||
|
|
||||||
if (newValue === null) {
|
|
||||||
condition.splice(index, 1);
|
|
||||||
} else {
|
|
||||||
condition[index] = newValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.onChange(condition);
|
|
||||||
}
|
|
||||||
|
|
||||||
public render({ condition, hass, localize }) {
|
|
||||||
return (
|
|
||||||
<div class="triggers">
|
|
||||||
{condition.map((cnd, idx) => (
|
|
||||||
<ConditionRow
|
|
||||||
index={idx}
|
|
||||||
condition={cnd}
|
|
||||||
onChange={this.conditionChanged}
|
|
||||||
hass={hass}
|
|
||||||
localize={localize}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
<ha-card>
|
|
||||||
<div class="card-actions add-card">
|
|
||||||
<mwc-button onTap={this.addCondition}>
|
|
||||||
{localize("ui.panel.config.automation.editor.conditions.add")}
|
|
||||||
</mwc-button>
|
|
||||||
</div>
|
|
||||||
</ha-card>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
import { h } from "preact";
|
|
||||||
|
|
||||||
import Condition from "./index";
|
|
||||||
import { AutomationComponent } from "../automation-component";
|
|
||||||
|
|
||||||
export default class LogicalCondition extends AutomationComponent<any> {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.conditionChanged = this.conditionChanged.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public conditionChanged(conditions) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.props.onChange(this.props.index, {
|
|
||||||
...this.props.condition,
|
|
||||||
conditions,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
public render({ condition, hass, localize }) {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Condition
|
|
||||||
condition={condition.conditions || []}
|
|
||||||
onChange={this.conditionChanged}
|
|
||||||
hass={hass}
|
|
||||||
localize={localize}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(LogicalCondition as any).defaultConfig = {
|
|
||||||
conditions: [{ condition: "state" }],
|
|
||||||
};
|
|
@ -1,71 +0,0 @@
|
|||||||
import { h } from "preact";
|
|
||||||
import "@polymer/paper-input/paper-input";
|
|
||||||
import "../../../../components/ha-textarea";
|
|
||||||
import "../../../../components/entity/ha-entity-picker";
|
|
||||||
|
|
||||||
import { onChangeEvent } from "../../../../common/preact/event";
|
|
||||||
import { AutomationComponent } from "../automation-component";
|
|
||||||
|
|
||||||
export default class NumericStateCondition extends AutomationComponent<any> {
|
|
||||||
private onChange: (obj: any) => void;
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.onChange = onChangeEvent.bind(this, "condition");
|
|
||||||
this.entityPicked = this.entityPicked.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public entityPicked(ev) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.props.onChange(this.props.index, {
|
|
||||||
...this.props.condition,
|
|
||||||
entity_id: ev.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
public render({ condition, hass, localize }) {
|
|
||||||
const { value_template, entity_id, below, above } = condition;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<ha-entity-picker
|
|
||||||
value={entity_id}
|
|
||||||
onChange={this.entityPicked}
|
|
||||||
hass={hass}
|
|
||||||
allowCustomEntity
|
|
||||||
/>
|
|
||||||
<paper-input
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.numeric_state.above"
|
|
||||||
)}
|
|
||||||
name="above"
|
|
||||||
value={above}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
/>
|
|
||||||
<paper-input
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.numeric_state.below"
|
|
||||||
)}
|
|
||||||
name="below"
|
|
||||||
value={below}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
/>
|
|
||||||
<ha-textarea
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.numeric_state.value_template"
|
|
||||||
)}
|
|
||||||
name="value_template"
|
|
||||||
value={value_template}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
dir="ltr"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(NumericStateCondition as any).defaultConfig = {
|
|
||||||
entity_id: "",
|
|
||||||
};
|
|
@ -1,56 +0,0 @@
|
|||||||
import { h } from "preact";
|
|
||||||
import "@polymer/paper-input/paper-input";
|
|
||||||
import "../../../../components/entity/ha-entity-picker";
|
|
||||||
|
|
||||||
import { onChangeEvent } from "../../../../common/preact/event";
|
|
||||||
import { AutomationComponent } from "../automation-component";
|
|
||||||
|
|
||||||
export default class StateCondition extends AutomationComponent<any> {
|
|
||||||
private onChange: (obj: any) => void;
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.onChange = onChangeEvent.bind(this, "condition");
|
|
||||||
this.entityPicked = this.entityPicked.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public entityPicked(ev) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.props.onChange(this.props.index, {
|
|
||||||
...this.props.condition,
|
|
||||||
entity_id: ev.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
public render({ condition, hass, localize }) {
|
|
||||||
const { entity_id, state } = condition;
|
|
||||||
const cndFor = condition.for;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<ha-entity-picker
|
|
||||||
value={entity_id}
|
|
||||||
onChange={this.entityPicked}
|
|
||||||
hass={hass}
|
|
||||||
allowCustomEntity
|
|
||||||
/>
|
|
||||||
<paper-input
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.state.state"
|
|
||||||
)}
|
|
||||||
name="state"
|
|
||||||
value={state}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
/>
|
|
||||||
{cndFor && <pre>For: {JSON.stringify(cndFor, null, 2)}</pre>}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(StateCondition as any).defaultConfig = {
|
|
||||||
entity_id: "",
|
|
||||||
state: "",
|
|
||||||
};
|
|
@ -1,112 +0,0 @@
|
|||||||
import { h } from "preact";
|
|
||||||
import "@polymer/paper-input/paper-input";
|
|
||||||
import "@polymer/paper-radio-button/paper-radio-button";
|
|
||||||
import "@polymer/paper-radio-group/paper-radio-group";
|
|
||||||
|
|
||||||
import { onChangeEvent } from "../../../../common/preact/event";
|
|
||||||
import { AutomationComponent } from "../automation-component";
|
|
||||||
|
|
||||||
export default class SunCondition extends AutomationComponent<any> {
|
|
||||||
private onChange: (obj: any) => void;
|
|
||||||
private afterPicked: (obj: any) => void;
|
|
||||||
private beforePicked: (obj: any) => void;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.onChange = onChangeEvent.bind(this, "condition");
|
|
||||||
this.afterPicked = this.radioGroupPicked.bind(this, "after");
|
|
||||||
this.beforePicked = this.radioGroupPicked.bind(this, "before");
|
|
||||||
}
|
|
||||||
|
|
||||||
public radioGroupPicked(key, ev) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const condition = { ...this.props.condition };
|
|
||||||
|
|
||||||
if (ev.target.selected) {
|
|
||||||
condition[key] = ev.target.selected;
|
|
||||||
} else {
|
|
||||||
delete condition[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.props.onChange(this.props.index, condition);
|
|
||||||
}
|
|
||||||
|
|
||||||
public render({ condition, localize }) {
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
const { after, after_offset, before, before_offset } = condition;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<label id="beforelabel">
|
|
||||||
{localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.sun.before"
|
|
||||||
)}
|
|
||||||
</label>
|
|
||||||
<paper-radio-group
|
|
||||||
allow-empty-selection
|
|
||||||
selected={before}
|
|
||||||
aria-labelledby="beforelabel"
|
|
||||||
onpaper-radio-group-changed={this.beforePicked}
|
|
||||||
>
|
|
||||||
<paper-radio-button name="sunrise">
|
|
||||||
{localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.sun.sunrise"
|
|
||||||
)}
|
|
||||||
</paper-radio-button>
|
|
||||||
<paper-radio-button name="sunset">
|
|
||||||
{localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.sun.sunset"
|
|
||||||
)}
|
|
||||||
</paper-radio-button>
|
|
||||||
</paper-radio-group>
|
|
||||||
|
|
||||||
<paper-input
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.sun.before_offset"
|
|
||||||
)}
|
|
||||||
name="before_offset"
|
|
||||||
value={before_offset}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
disabled={before === undefined}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<label id="afterlabel">
|
|
||||||
{localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.sun.after"
|
|
||||||
)}
|
|
||||||
</label>
|
|
||||||
<paper-radio-group
|
|
||||||
allow-empty-selection
|
|
||||||
selected={after}
|
|
||||||
aria-labelledby="afterlabel"
|
|
||||||
onpaper-radio-group-changed={this.afterPicked}
|
|
||||||
>
|
|
||||||
<paper-radio-button name="sunrise">
|
|
||||||
{localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.sun.sunrise"
|
|
||||||
)}
|
|
||||||
</paper-radio-button>
|
|
||||||
<paper-radio-button name="sunset">
|
|
||||||
{localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.sun.sunset"
|
|
||||||
)}
|
|
||||||
</paper-radio-button>
|
|
||||||
</paper-radio-group>
|
|
||||||
|
|
||||||
<paper-input
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.sun.after_offset"
|
|
||||||
)}
|
|
||||||
name="after_offset"
|
|
||||||
value={after_offset}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
disabled={after === undefined}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(SunCondition as any).defaultConfig = {};
|
|
@ -1,36 +0,0 @@
|
|||||||
import { h } from "preact";
|
|
||||||
import "../../../../components/ha-textarea";
|
|
||||||
|
|
||||||
import { onChangeEvent } from "../../../../common/preact/event";
|
|
||||||
import { AutomationComponent } from "../automation-component";
|
|
||||||
|
|
||||||
export default class TemplateCondition extends AutomationComponent<any> {
|
|
||||||
private onChange: (obj: any) => void;
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.onChange = onChangeEvent.bind(this, "condition");
|
|
||||||
}
|
|
||||||
|
|
||||||
public render({ condition, localize }) {
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
const { value_template } = condition;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<ha-textarea
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.template.value_template"
|
|
||||||
)}
|
|
||||||
name="value_template"
|
|
||||||
value={value_template}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
dir="ltr"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(TemplateCondition as any).defaultConfig = {
|
|
||||||
value_template: "",
|
|
||||||
};
|
|
@ -1,41 +0,0 @@
|
|||||||
import { h } from "preact";
|
|
||||||
import "@polymer/paper-input/paper-input";
|
|
||||||
|
|
||||||
import { onChangeEvent } from "../../../../common/preact/event";
|
|
||||||
import { AutomationComponent } from "../automation-component";
|
|
||||||
|
|
||||||
export default class TimeCondition extends AutomationComponent<any> {
|
|
||||||
private onChange: (obj: any) => void;
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.onChange = onChangeEvent.bind(this, "condition");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
public render({ condition, localize }) {
|
|
||||||
const { after, before } = condition;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<paper-input
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.time.after"
|
|
||||||
)}
|
|
||||||
name="after"
|
|
||||||
value={after}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
/>
|
|
||||||
<paper-input
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.time.before"
|
|
||||||
)}
|
|
||||||
name="before"
|
|
||||||
value={before}
|
|
||||||
onvalue-changed={this.onChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(TimeCondition as any).defaultConfig = {};
|
|
@ -1,73 +0,0 @@
|
|||||||
import { h } from "preact";
|
|
||||||
import "../../../../components/entity/ha-entity-picker";
|
|
||||||
import { hasLocation } from "../../../../common/entity/has_location";
|
|
||||||
import { computeStateDomain } from "../../../../common/entity/compute_state_domain";
|
|
||||||
|
|
||||||
import { AutomationComponent } from "../automation-component";
|
|
||||||
|
|
||||||
function zoneAndLocationFilter(stateObj) {
|
|
||||||
return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone";
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class ZoneCondition extends AutomationComponent<any> {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.entityPicked = this.entityPicked.bind(this);
|
|
||||||
this.zonePicked = this.zonePicked.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public entityPicked(ev) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.props.onChange(this.props.index, {
|
|
||||||
...this.props.condition,
|
|
||||||
entity_id: ev.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public zonePicked(ev) {
|
|
||||||
if (!this.initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.props.onChange(this.props.index, {
|
|
||||||
...this.props.condition,
|
|
||||||
zone: ev.target.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/* eslint-disable camelcase */
|
|
||||||
public render({ condition, hass, localize }) {
|
|
||||||
const { entity_id, zone } = condition;
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<ha-entity-picker
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.zone.entity"
|
|
||||||
)}
|
|
||||||
value={entity_id}
|
|
||||||
onChange={this.entityPicked}
|
|
||||||
hass={hass}
|
|
||||||
allowCustomEntity
|
|
||||||
entityFilter={zoneAndLocationFilter}
|
|
||||||
/>
|
|
||||||
<ha-entity-picker
|
|
||||||
label={localize(
|
|
||||||
"ui.panel.config.automation.editor.conditions.type.zone.zone"
|
|
||||||
)}
|
|
||||||
value={zone}
|
|
||||||
onChange={this.zonePicked}
|
|
||||||
hass={hass}
|
|
||||||
allowCustomEntity
|
|
||||||
includeDomains={["zone"]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(ZoneCondition as any).defaultConfig = {
|
|
||||||
entity_id: "",
|
|
||||||
zone: "",
|
|
||||||
};
|
|
@ -24,6 +24,8 @@ declare global {
|
|||||||
"ha-service-picker": any;
|
"ha-service-picker": any;
|
||||||
"mwc-button": any;
|
"mwc-button": any;
|
||||||
"ha-automation-trigger": any;
|
"ha-automation-trigger": any;
|
||||||
|
"ha-automation-condition": any;
|
||||||
|
"ha-automation-condition-editor": any;
|
||||||
"ha-device-trigger-picker": any;
|
"ha-device-trigger-picker": any;
|
||||||
"ha-device-action-picker": any;
|
"ha-device-action-picker": any;
|
||||||
"ha-form": any;
|
"ha-form": any;
|
||||||
|
@ -1,24 +1,32 @@
|
|||||||
import { h, Component } from "preact";
|
import { h, Component } from "preact";
|
||||||
|
|
||||||
import StateCondition from "../condition/state";
|
import "../../automation/condition/ha-automation-condition-editor";
|
||||||
import ConditionEdit from "../condition/condition_edit";
|
|
||||||
|
|
||||||
export default class ConditionAction extends Component<any> {
|
export default class ConditionAction extends Component<any> {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.conditionChanged = this.conditionChanged.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public conditionChanged(ev) {
|
||||||
|
this.props.onChange(this.props.index, ev.detail.value);
|
||||||
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
public render({ action, index, onChange, hass, localize }) {
|
public render({ action, hass }) {
|
||||||
return (
|
return (
|
||||||
<ConditionEdit
|
<div>
|
||||||
|
<ha-automation-condition-editor
|
||||||
condition={action}
|
condition={action}
|
||||||
onChange={onChange}
|
onvalue-changed={this.conditionChanged}
|
||||||
index={index}
|
|
||||||
hass={hass}
|
hass={hass}
|
||||||
localize={localize}
|
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(ConditionAction as any).defaultConfig = {
|
(ConditionAction as any).defaultConfig = {
|
||||||
condition: "state",
|
condition: "state",
|
||||||
...(StateCondition as any).defaultConfig,
|
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user