diff --git a/src/data/device_automation.ts b/src/data/device_automation.ts index 093de90b2f..0a308fcdbc 100644 --- a/src/data/device_automation.ts +++ b/src/data/device_automation.ts @@ -39,6 +39,15 @@ export const fetchDeviceTriggers = (hass: HomeAssistant, deviceId: string) => device_id: deviceId, }); +export const fetchDeviceConditionCapabilities = ( + hass: HomeAssistant, + condition: DeviceCondition +) => + hass.callWS({ + type: "device_automation/condition/capabilities", + condition, + }); + export const fetchDeviceTriggerCapabilities = ( hass: HomeAssistant, trigger: DeviceTrigger diff --git a/src/panels/config/js/condition/device.tsx b/src/panels/config/js/condition/device.tsx index 30962fec46..6c3206c4b6 100644 --- a/src/panels/config/js/condition/device.tsx +++ b/src/panels/config/js/condition/device.tsx @@ -2,29 +2,49 @@ import { h, Component } from "preact"; import "../../../../components/device/ha-device-picker"; import "../../../../components/device/ha-device-condition-picker"; +import "../../../../components/ha-form"; +import { + fetchDeviceConditionCapabilities, + deviceAutomationsEqual, +} from "../../../../data/device_automation"; export default class DeviceCondition extends Component { + private _origCondition; + constructor() { super(); this.devicePicked = this.devicePicked.bind(this); this.deviceConditionPicked = this.deviceConditionPicked.bind(this); - this.state = { device_id: undefined }; + this._extraFieldsChanged = this._extraFieldsChanged.bind(this); + this.state = { device_id: undefined, capabilities: undefined }; } public devicePicked(ev) { - this.setState({ device_id: ev.target.value }); + this.setState({ ...this.state, device_id: ev.target.value }); } public deviceConditionPicked(ev) { - const deviceCondition = ev.target.value; - this.props.onChange(this.props.index, deviceCondition); + 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 }) { + 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 (
@@ -41,9 +61,64 @@ export default class DeviceCondition extends Component { hass={hass} label="Condition" /> + {extraFieldsData && ( + + )}
); } + + public componentDidMount() { + if (!this.state.capabilities) { + this._getCapabilities(); + } + if (this.props.condition) { + this._origCondition = this.props.condition; + } + } + + public componentDidUpdate(prevProps) { + if (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 (!ev.detail.path) { + return; + } + const item = ev.detail.path.replace("data.", ""); + const value = ev.detail.value || undefined; + + this.props.onChange(this.props.index, { + ...this.props.condition, + [item]: 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 = { diff --git a/src/translations/en.json b/src/translations/en.json index 83deb0d04b..a707ab7015 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -830,7 +830,12 @@ "label": "And" }, "device": { - "label": "Device" + "label": "Device", + "extra_fields": { + "above": "Above", + "below": "Below", + "for": "Duration" + } }, "numeric_state": { "label": "[%key:ui::panel::config::automation::editor::triggers::type::numeric_state::label%]",