mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 09:17:10 +00:00
Adapt template sensors to use the same plural trigger/condition/action definitions as automations (#127875)
* Add plurals to template entities * Ruff * Ruffy ruff * Fix linters * Fix bug introduced after merging dev * Fix merge mistake * Revert adding automation helper * Revert "Fix bug introduced after merging dev" This reverts commit 098d478f150a06546fb9ec3668865fa5d763c6b2. * Fix blueprint validation * Apply suggestions from code review --------- Co-authored-by: Erik <erik@montnemery.com>
This commit is contained in:
parent
f2838e493b
commit
8ff4d5dcbf
@ -18,6 +18,7 @@ from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_MODE,
|
||||
ATTR_NAME,
|
||||
CONF_ACTIONS,
|
||||
CONF_ALIAS,
|
||||
CONF_CONDITIONS,
|
||||
CONF_DEVICE_ID,
|
||||
@ -27,6 +28,7 @@ from homeassistant.const import (
|
||||
CONF_MODE,
|
||||
CONF_PATH,
|
||||
CONF_PLATFORM,
|
||||
CONF_TRIGGERS,
|
||||
CONF_VARIABLES,
|
||||
CONF_ZONE,
|
||||
EVENT_HOMEASSISTANT_STARTED,
|
||||
@ -86,11 +88,9 @@ from homeassistant.util.hass_dict import HassKey
|
||||
|
||||
from .config import AutomationConfig, ValidationStatus
|
||||
from .const import (
|
||||
CONF_ACTIONS,
|
||||
CONF_INITIAL_STATE,
|
||||
CONF_TRACE,
|
||||
CONF_TRIGGER_VARIABLES,
|
||||
CONF_TRIGGERS,
|
||||
DEFAULT_INITIAL_STATE,
|
||||
DOMAIN,
|
||||
LOGGER,
|
||||
|
@ -14,11 +14,15 @@ from homeassistant.components import blueprint
|
||||
from homeassistant.components.trace import TRACE_CONFIG_SCHEMA
|
||||
from homeassistant.config import config_per_platform, config_without_domain
|
||||
from homeassistant.const import (
|
||||
CONF_ACTION,
|
||||
CONF_ACTIONS,
|
||||
CONF_ALIAS,
|
||||
CONF_CONDITION,
|
||||
CONF_CONDITIONS,
|
||||
CONF_DESCRIPTION,
|
||||
CONF_ID,
|
||||
CONF_TRIGGER,
|
||||
CONF_TRIGGERS,
|
||||
CONF_VARIABLES,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
@ -30,14 +34,10 @@ from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.util.yaml.input import UndefinedSubstitution
|
||||
|
||||
from .const import (
|
||||
CONF_ACTION,
|
||||
CONF_ACTIONS,
|
||||
CONF_HIDE_ENTITY,
|
||||
CONF_INITIAL_STATE,
|
||||
CONF_TRACE,
|
||||
CONF_TRIGGER,
|
||||
CONF_TRIGGER_VARIABLES,
|
||||
CONF_TRIGGERS,
|
||||
DOMAIN,
|
||||
LOGGER,
|
||||
)
|
||||
|
@ -2,10 +2,6 @@
|
||||
|
||||
import logging
|
||||
|
||||
CONF_ACTION = "action"
|
||||
CONF_ACTIONS = "actions"
|
||||
CONF_TRIGGER = "trigger"
|
||||
CONF_TRIGGERS = "triggers"
|
||||
CONF_TRIGGER_VARIABLES = "trigger_variables"
|
||||
DOMAIN = "automation"
|
||||
|
||||
|
@ -12,6 +12,7 @@ from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_DEVICE_ID,
|
||||
CONF_NAME,
|
||||
CONF_TRIGGERS,
|
||||
CONF_UNIQUE_ID,
|
||||
SERVICE_RELOAD,
|
||||
)
|
||||
@ -27,7 +28,7 @@ from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.loader import async_get_integration
|
||||
from homeassistant.util.hass_dict import HassKey
|
||||
|
||||
from .const import CONF_MAX, CONF_MIN, CONF_STEP, CONF_TRIGGER, DOMAIN, PLATFORMS
|
||||
from .const import CONF_MAX, CONF_MIN, CONF_STEP, DOMAIN, PLATFORMS
|
||||
from .coordinator import TriggerUpdateCoordinator
|
||||
from .helpers import async_get_blueprints
|
||||
|
||||
@ -136,7 +137,7 @@ async def _process_config(hass: HomeAssistant, hass_config: ConfigType) -> None:
|
||||
coordinator_tasks: list[Coroutine[Any, Any, TriggerUpdateCoordinator]] = []
|
||||
|
||||
for conf_section in hass_config[DOMAIN]:
|
||||
if CONF_TRIGGER in conf_section:
|
||||
if CONF_TRIGGERS in conf_section:
|
||||
coordinator_tasks.append(init_coordinator(hass, conf_section))
|
||||
continue
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
from collections.abc import Callable
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
@ -10,6 +11,7 @@ from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAI
|
||||
from homeassistant.components.blueprint import (
|
||||
BLUEPRINT_INSTANCE_FIELDS,
|
||||
is_blueprint_instance_config,
|
||||
schemas as blueprint_schemas,
|
||||
)
|
||||
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN
|
||||
from homeassistant.components.cover import DOMAIN as COVER_DOMAIN
|
||||
@ -22,9 +24,15 @@ from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||
from homeassistant.components.weather import DOMAIN as WEATHER_DOMAIN
|
||||
from homeassistant.config import async_log_schema_error, config_without_domain
|
||||
from homeassistant.const import (
|
||||
CONF_ACTION,
|
||||
CONF_ACTIONS,
|
||||
CONF_BINARY_SENSORS,
|
||||
CONF_CONDITION,
|
||||
CONF_CONDITIONS,
|
||||
CONF_NAME,
|
||||
CONF_SENSORS,
|
||||
CONF_TRIGGER,
|
||||
CONF_TRIGGERS,
|
||||
CONF_UNIQUE_ID,
|
||||
CONF_VARIABLES,
|
||||
)
|
||||
@ -47,14 +55,7 @@ from . import (
|
||||
switch as switch_platform,
|
||||
weather as weather_platform,
|
||||
)
|
||||
from .const import (
|
||||
CONF_ACTION,
|
||||
CONF_CONDITION,
|
||||
CONF_TRIGGER,
|
||||
DOMAIN,
|
||||
PLATFORMS,
|
||||
TemplateConfig,
|
||||
)
|
||||
from .const import DOMAIN, PLATFORMS, TemplateConfig
|
||||
from .helpers import async_get_blueprints
|
||||
|
||||
PACKAGE_MERGE_HINT = "list"
|
||||
@ -67,7 +68,7 @@ def ensure_domains_do_not_have_trigger_or_action(*keys: str) -> Callable[[dict],
|
||||
def validate(obj: dict):
|
||||
options = set(obj.keys())
|
||||
if found_domains := domains.intersection(options):
|
||||
invalid = {CONF_TRIGGER, CONF_ACTION}
|
||||
invalid = {CONF_TRIGGERS, CONF_ACTIONS}
|
||||
if found_invalid := invalid.intersection(set(obj.keys())):
|
||||
raise vol.Invalid(
|
||||
f"Unsupported option(s) found for domain {found_domains.pop()}, please remove ({', '.join(found_invalid)}) from your configuration",
|
||||
@ -78,13 +79,22 @@ def ensure_domains_do_not_have_trigger_or_action(*keys: str) -> Callable[[dict],
|
||||
return validate
|
||||
|
||||
|
||||
CONFIG_SECTION_SCHEMA = vol.Schema(
|
||||
vol.All(
|
||||
def _backward_compat_schema(value: Any | None) -> Any:
|
||||
"""Backward compatibility for automations."""
|
||||
|
||||
value = cv.renamed(CONF_TRIGGER, CONF_TRIGGERS)(value)
|
||||
value = cv.renamed(CONF_ACTION, CONF_ACTIONS)(value)
|
||||
return cv.renamed(CONF_CONDITION, CONF_CONDITIONS)(value)
|
||||
|
||||
|
||||
CONFIG_SECTION_SCHEMA = vol.All(
|
||||
_backward_compat_schema,
|
||||
vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||
vol.Optional(CONF_TRIGGER): cv.TRIGGER_SCHEMA,
|
||||
vol.Optional(CONF_CONDITION): cv.CONDITIONS_SCHEMA,
|
||||
vol.Optional(CONF_ACTION): cv.SCRIPT_SCHEMA,
|
||||
vol.Optional(CONF_TRIGGERS): cv.TRIGGER_SCHEMA,
|
||||
vol.Optional(CONF_CONDITIONS): cv.CONDITIONS_SCHEMA,
|
||||
vol.Optional(CONF_ACTIONS): cv.SCRIPT_SCHEMA,
|
||||
vol.Optional(CONF_VARIABLES): cv.SCRIPT_VARIABLES_SCHEMA,
|
||||
vol.Optional(NUMBER_DOMAIN): vol.All(
|
||||
cv.ensure_list, [number_platform.NUMBER_SCHEMA]
|
||||
@ -123,10 +133,14 @@ CONFIG_SECTION_SCHEMA = vol.Schema(
|
||||
cv.ensure_list, [cover_platform.COVER_SCHEMA]
|
||||
),
|
||||
},
|
||||
ensure_domains_do_not_have_trigger_or_action(
|
||||
BUTTON_DOMAIN, COVER_DOMAIN, LIGHT_DOMAIN
|
||||
),
|
||||
)
|
||||
),
|
||||
ensure_domains_do_not_have_trigger_or_action(
|
||||
BUTTON_DOMAIN, COVER_DOMAIN, LIGHT_DOMAIN
|
||||
),
|
||||
)
|
||||
|
||||
TEMPLATE_BLUEPRINT_SCHEMA = vol.All(
|
||||
_backward_compat_schema, blueprint_schemas.BLUEPRINT_SCHEMA
|
||||
)
|
||||
|
||||
TEMPLATE_BLUEPRINT_INSTANCE_SCHEMA = vol.Schema(
|
||||
@ -169,7 +183,7 @@ async def _async_resolve_blueprints(
|
||||
# house input results for template entities. For Trigger based template entities
|
||||
# CONF_VARIABLES should not be removed because the variables are always
|
||||
# executed between the trigger and action.
|
||||
if CONF_TRIGGER not in config and CONF_VARIABLES in config:
|
||||
if CONF_TRIGGERS not in config and CONF_VARIABLES in config:
|
||||
config[platform][CONF_VARIABLES] = config.pop(CONF_VARIABLES)
|
||||
raw_config = dict(config)
|
||||
|
||||
@ -187,14 +201,14 @@ async def async_validate_config_section(
|
||||
|
||||
validated_config = await _async_resolve_blueprints(hass, config)
|
||||
|
||||
if CONF_TRIGGER in validated_config:
|
||||
validated_config[CONF_TRIGGER] = await async_validate_trigger_config(
|
||||
hass, validated_config[CONF_TRIGGER]
|
||||
if CONF_TRIGGERS in validated_config:
|
||||
validated_config[CONF_TRIGGERS] = await async_validate_trigger_config(
|
||||
hass, validated_config[CONF_TRIGGERS]
|
||||
)
|
||||
|
||||
if CONF_CONDITION in validated_config:
|
||||
validated_config[CONF_CONDITION] = await async_validate_conditions_config(
|
||||
hass, validated_config[CONF_CONDITION]
|
||||
if CONF_CONDITIONS in validated_config:
|
||||
validated_config[CONF_CONDITIONS] = await async_validate_conditions_config(
|
||||
hass, validated_config[CONF_CONDITIONS]
|
||||
)
|
||||
|
||||
return validated_config
|
||||
|
@ -1,22 +1,18 @@
|
||||
"""Constants for the Template Platform Components."""
|
||||
|
||||
from homeassistant.components.blueprint import BLUEPRINT_SCHEMA
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
CONF_ACTION = "action"
|
||||
CONF_ATTRIBUTE_TEMPLATES = "attribute_templates"
|
||||
CONF_ATTRIBUTES = "attributes"
|
||||
CONF_AVAILABILITY = "availability"
|
||||
CONF_AVAILABILITY_TEMPLATE = "availability_template"
|
||||
CONF_CONDITION = "condition"
|
||||
CONF_MAX = "max"
|
||||
CONF_MIN = "min"
|
||||
CONF_OBJECT_ID = "object_id"
|
||||
CONF_PICTURE = "picture"
|
||||
CONF_PRESS = "press"
|
||||
CONF_STEP = "step"
|
||||
CONF_TRIGGER = "trigger"
|
||||
CONF_TURN_OFF = "turn_off"
|
||||
CONF_TURN_ON = "turn_on"
|
||||
|
||||
@ -41,8 +37,6 @@ PLATFORMS = [
|
||||
Platform.WEATHER,
|
||||
]
|
||||
|
||||
TEMPLATE_BLUEPRINT_SCHEMA = BLUEPRINT_SCHEMA
|
||||
|
||||
|
||||
class TemplateConfig(dict):
|
||||
"""Dummy class to allow adding attributes."""
|
||||
|
@ -5,7 +5,14 @@ import logging
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
from homeassistant.components.blueprint import CONF_USE_BLUEPRINT
|
||||
from homeassistant.const import CONF_PATH, CONF_VARIABLES, EVENT_HOMEASSISTANT_START
|
||||
from homeassistant.const import (
|
||||
CONF_ACTIONS,
|
||||
CONF_CONDITIONS,
|
||||
CONF_PATH,
|
||||
CONF_TRIGGERS,
|
||||
CONF_VARIABLES,
|
||||
EVENT_HOMEASSISTANT_START,
|
||||
)
|
||||
from homeassistant.core import Context, CoreState, Event, HomeAssistant, callback
|
||||
from homeassistant.helpers import condition, discovery, trigger as trigger_helper
|
||||
from homeassistant.helpers.script import Script
|
||||
@ -14,7 +21,7 @@ from homeassistant.helpers.trace import trace_get
|
||||
from homeassistant.helpers.typing import ConfigType, TemplateVarsType
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
from .const import CONF_ACTION, CONF_CONDITION, CONF_TRIGGER, DOMAIN, PLATFORMS
|
||||
from .const import DOMAIN, PLATFORMS
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -84,17 +91,17 @@ class TriggerUpdateCoordinator(DataUpdateCoordinator):
|
||||
|
||||
async def _attach_triggers(self, start_event: Event | None = None) -> None:
|
||||
"""Attach the triggers."""
|
||||
if CONF_ACTION in self.config:
|
||||
if CONF_ACTIONS in self.config:
|
||||
self._script = Script(
|
||||
self.hass,
|
||||
self.config[CONF_ACTION],
|
||||
self.config[CONF_ACTIONS],
|
||||
self.name,
|
||||
DOMAIN,
|
||||
)
|
||||
|
||||
if CONF_CONDITION in self.config:
|
||||
if CONF_CONDITIONS in self.config:
|
||||
self._cond_func = await condition.async_conditions_from_config(
|
||||
self.hass, self.config[CONF_CONDITION], _LOGGER, "template entity"
|
||||
self.hass, self.config[CONF_CONDITIONS], _LOGGER, "template entity"
|
||||
)
|
||||
|
||||
if start_event is not None:
|
||||
@ -107,7 +114,7 @@ class TriggerUpdateCoordinator(DataUpdateCoordinator):
|
||||
|
||||
self._unsub_trigger = await trigger_helper.async_initialize_triggers(
|
||||
self.hass,
|
||||
self.config[CONF_TRIGGER],
|
||||
self.config[CONF_TRIGGERS],
|
||||
action,
|
||||
DOMAIN,
|
||||
self.name,
|
||||
|
@ -8,7 +8,7 @@ from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import async_get_platforms
|
||||
from homeassistant.helpers.singleton import singleton
|
||||
|
||||
from .const import DOMAIN, TEMPLATE_BLUEPRINT_SCHEMA
|
||||
from .const import DOMAIN
|
||||
from .entity import AbstractTemplateEntity
|
||||
|
||||
DATA_BLUEPRINTS = "template_blueprints"
|
||||
@ -54,6 +54,9 @@ async def _reload_blueprint_templates(hass: HomeAssistant, blueprint_path: str)
|
||||
@callback
|
||||
def async_get_blueprints(hass: HomeAssistant) -> blueprint.DomainBlueprints:
|
||||
"""Get template blueprints."""
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from .config import TEMPLATE_BLUEPRINT_SCHEMA
|
||||
|
||||
return blueprint.DomainBlueprints(
|
||||
hass,
|
||||
DOMAIN,
|
||||
|
@ -33,6 +33,8 @@ from homeassistant.const import (
|
||||
CONF_NAME,
|
||||
CONF_SENSORS,
|
||||
CONF_STATE,
|
||||
CONF_TRIGGER,
|
||||
CONF_TRIGGERS,
|
||||
CONF_UNIQUE_ID,
|
||||
CONF_UNIT_OF_MEASUREMENT,
|
||||
CONF_VALUE_TEMPLATE,
|
||||
@ -53,12 +55,7 @@ from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import TriggerUpdateCoordinator
|
||||
from .const import (
|
||||
CONF_ATTRIBUTE_TEMPLATES,
|
||||
CONF_AVAILABILITY_TEMPLATE,
|
||||
CONF_OBJECT_ID,
|
||||
CONF_TRIGGER,
|
||||
)
|
||||
from .const import CONF_ATTRIBUTE_TEMPLATES, CONF_AVAILABILITY_TEMPLATE, CONF_OBJECT_ID
|
||||
from .template_entity import (
|
||||
TEMPLATE_ENTITY_COMMON_SCHEMA,
|
||||
TemplateEntity,
|
||||
@ -132,7 +129,7 @@ LEGACY_SENSOR_SCHEMA = vol.All(
|
||||
|
||||
def extra_validation_checks(val):
|
||||
"""Run extra validation checks."""
|
||||
if CONF_TRIGGER in val:
|
||||
if CONF_TRIGGERS in val or CONF_TRIGGER in val:
|
||||
raise vol.Invalid(
|
||||
"You can only add triggers to template entities if they are defined under"
|
||||
" `template:`. See the template documentation for more information:"
|
||||
@ -170,6 +167,7 @@ PLATFORM_SCHEMA = vol.All(
|
||||
SENSOR_PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Optional(CONF_TRIGGER): cv.match_all, # to raise custom warning
|
||||
vol.Optional(CONF_TRIGGERS): cv.match_all, # to raise custom warning
|
||||
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(LEGACY_SENSOR_SCHEMA),
|
||||
}
|
||||
),
|
||||
|
@ -115,6 +115,7 @@ SUN_EVENT_SUNRISE: Final = "sunrise"
|
||||
CONF_ABOVE: Final = "above"
|
||||
CONF_ACCESS_TOKEN: Final = "access_token"
|
||||
CONF_ACTION: Final = "action"
|
||||
CONF_ACTIONS: Final = "actions"
|
||||
CONF_ADDRESS: Final = "address"
|
||||
CONF_AFTER: Final = "after"
|
||||
CONF_ALIAS: Final = "alias"
|
||||
|
@ -212,11 +212,16 @@ async def test_reload_template_when_blueprint_changes(hass: HomeAssistant) -> No
|
||||
assert not_inverted.state == "on"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("blueprint"),
|
||||
["test_event_sensor.yaml", "test_event_sensor_legacy_schema.yaml"],
|
||||
)
|
||||
async def test_trigger_event_sensor(
|
||||
hass: HomeAssistant, device_registry: dr.DeviceRegistry
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
blueprint: str,
|
||||
) -> None:
|
||||
"""Test event sensor blueprint."""
|
||||
blueprint = "test_event_sensor.yaml"
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"template",
|
||||
|
@ -2303,6 +2303,61 @@ async def test_trigger_conditional_action(hass: HomeAssistant) -> None:
|
||||
assert len(events) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("trigger_field", ["trigger", "triggers"])
|
||||
@pytest.mark.parametrize("condition_field", ["condition", "conditions"])
|
||||
@pytest.mark.parametrize("action_field", ["action", "actions"])
|
||||
async def test_legacy_and_new_config_schema(
|
||||
hass: HomeAssistant, trigger_field: str, condition_field: str, action_field: str
|
||||
) -> None:
|
||||
"""Tests that both old and new config schema (singular -> plural) work."""
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
"template",
|
||||
{
|
||||
"template": [
|
||||
{
|
||||
"unique_id": "listening-test-event",
|
||||
f"{trigger_field}": {
|
||||
"platform": "event",
|
||||
"event_type": "beer_event",
|
||||
},
|
||||
f"{condition_field}": [
|
||||
{
|
||||
"condition": "template",
|
||||
"value_template": "{{ trigger.event.data.beer >= 42 }}",
|
||||
}
|
||||
],
|
||||
f"{action_field}": [
|
||||
{"event": "test_event_by_action"},
|
||||
],
|
||||
"sensor": [
|
||||
{
|
||||
"name": "Unimportant",
|
||||
"state": "Uninteresting",
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
event = "test_event_by_action"
|
||||
events = async_capture_events(hass, event)
|
||||
|
||||
hass.bus.async_fire("beer_event", {"beer": 1})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 0
|
||||
|
||||
hass.bus.async_fire("beer_event", {"beer": 42})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 1
|
||||
|
||||
|
||||
async def test_device_id(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
|
@ -14,7 +14,7 @@ blueprint:
|
||||
description: The event_data for the event trigger
|
||||
selector:
|
||||
object:
|
||||
trigger:
|
||||
triggers:
|
||||
- trigger: event
|
||||
event_type: !input event_type
|
||||
event_data: !input event_data
|
||||
|
@ -0,0 +1,27 @@
|
||||
blueprint:
|
||||
name: Create Sensor from Event
|
||||
description: Creates a timestamp sensor from an event
|
||||
domain: template
|
||||
source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/template/blueprints/event_sensor.yaml
|
||||
input:
|
||||
event_type:
|
||||
name: Name of the event_type
|
||||
description: The event_type for the event trigger
|
||||
selector:
|
||||
text:
|
||||
event_data:
|
||||
name: The data for the event
|
||||
description: The event_data for the event trigger
|
||||
selector:
|
||||
object:
|
||||
trigger:
|
||||
- trigger: event
|
||||
event_type: !input event_type
|
||||
event_data: !input event_data
|
||||
variables:
|
||||
event_data: "{{ trigger.event.data }}"
|
||||
sensor:
|
||||
state: "{{ now() }}"
|
||||
device_class: timestamp
|
||||
attributes:
|
||||
data: "{{ event_data }}"
|
Loading…
x
Reference in New Issue
Block a user