Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Petro31 committed Oct 27, 2024
1 parent 058cb41 commit 7404c25
Show file tree
Hide file tree
Showing 4 changed files with 391 additions and 41 deletions.
9 changes: 9 additions & 0 deletions homeassistant/components/template/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
CONF_BINARY_SENSORS,
CONF_NAME,
CONF_SENSORS,
CONF_SWITCHES,
CONF_UNIQUE_ID,
CONF_VARIABLES,
)
Expand Down Expand Up @@ -91,6 +92,9 @@
vol.Optional(SWITCH_DOMAIN): vol.All(
cv.ensure_list, [switch_platform.SWITCH_SCHEMA]
),
vol.Optional(CONF_SWITCHES): cv.schema_with_slug_keys(
switch_platform.LEGACY_SWITCH_SCHEMA
),
},
)

Expand Down Expand Up @@ -189,6 +193,11 @@ async def async_validate_config(hass: HomeAssistant, config: ConfigType) -> Conf
BINARY_SENSOR_DOMAIN,
binary_sensor_platform.rewrite_legacy_to_modern_conf,
),
(
CONF_SWITCHES,
SWITCH_DOMAIN,
switch_platform.rewrite_legacy_to_modern_conf,
),
):
if old_key not in template_config:
continue
Expand Down
53 changes: 34 additions & 19 deletions homeassistant/components/template/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType

from . import TriggerUpdateCoordinator
from .const import CONF_OBJECT_ID, CONF_TURN_OFF, CONF_TURN_ON, DOMAIN
from .const import CONF_OBJECT_ID, CONF_PICTURE, CONF_TURN_OFF, CONF_TURN_ON, DOMAIN
from .template_entity import (
LEGACY_FIELDS as TEMPLATE_ENTITY_LEGACY_FIELDS,
TEMPLATE_ENTITY_COMMON_SCHEMA,
TEMPLATE_ENTITY_AVAILABILITY_SCHEMA,
TEMPLATE_ENTITY_COMMON_SCHEMA_LEGACY,
TEMPLATE_ENTITY_ICON_SCHEMA,
TemplateEntity,
rewrite_common_legacy_to_modern_conf,
)
Expand All @@ -54,15 +55,23 @@
CONF_VALUE_TEMPLATE: CONF_STATE,
}

DEFAULT_NAME = "Template Switch"

SWITCH_SCHEMA = vol.All(

SWITCH_SCHEMA = (
vol.Schema(
{
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.template,
vol.Optional(CONF_STATE): cv.template,
vol.Required(CONF_TURN_ON): cv.SCRIPT_SCHEMA,
vol.Required(CONF_TURN_OFF): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_UNIQUE_ID): cv.string,
vol.Optional(CONF_PICTURE): cv.template,
}
).extend(TEMPLATE_ENTITY_COMMON_SCHEMA.schema)
)
.extend(TEMPLATE_ENTITY_AVAILABILITY_SCHEMA.schema)
.extend(TEMPLATE_ENTITY_ICON_SCHEMA.schema)
.extend(TEMPLATE_ENTITY_ICON_SCHEMA.schema)
)

LEGACY_SWITCH_SCHEMA = vol.All(
Expand Down Expand Up @@ -294,7 +303,6 @@ class TriggerSwitchEntity(TriggerEntity, SwitchEntity, RestoreEntity):
"""Switch entity based on trigger data."""

domain = SWITCH_DOMAIN
extra_template_keys = (CONF_STATE,)

def __init__(
self,
Expand All @@ -304,19 +312,22 @@ def __init__(
) -> None:
"""Initialize the entity."""
super().__init__(hass, coordinator, config)
friendly_name = self._attr_name
self._on_script = (
Script(hass, config.get(CONF_TURN_ON), friendly_name, DOMAIN)
if config.get(CONF_TURN_ON) is not None
else None
)
self._off_script = (
Script(hass, config.get(CONF_TURN_OFF), friendly_name, DOMAIN)
if config.get(CONF_TURN_OFF) is not None
else None
friendly_name = self._rendered.get(CONF_NAME, DEFAULT_NAME)
self._on_script = Script(hass, config.get(CONF_TURN_ON), friendly_name, DOMAIN)

Check failure on line 316 in homeassistant/components/template/switch.py

View workflow job for this annotation

GitHub Actions / Check mypy

Argument 2 to "Script" has incompatible type "Any | None"; expected "Sequence[dict[str, Any]]" [arg-type]
self._off_script = Script(
hass, config.get(CONF_TURN_OFF), friendly_name, DOMAIN

Check failure on line 318 in homeassistant/components/template/switch.py

View workflow job for this annotation

GitHub Actions / Check mypy

Argument 2 to "Script" has incompatible type "Any | None"; expected "Sequence[dict[str, Any]]" [arg-type]
)
self._state: bool | None = False
self._attr_assumed_state = config.get(CONF_STATE) is None

self._state: bool | None = None
if (tmpl := config.get(CONF_STATE)) is not None and isinstance(
tmpl, template.Template
):
self._to_render_simple.append(CONF_STATE)
self._parse_result.add(CONF_STATE)
self._attr_assumed_state = False
else:
self._attr_assumed_state = True

self._attr_device_info = async_device_info_to_link_from_device_id(
hass,
config.get(CONF_DEVICE_ID),
Expand Down Expand Up @@ -350,6 +361,10 @@ def _handle_coordinator_update(self) -> None:

self.async_set_context(self.coordinator.data["context"])
self.async_write_ha_state()
elif self._attr_assumed_state and len(self._rendered) > 0:
# Incase name, icon, or friendly name have a template but

Check warning on line 365 in homeassistant/components/template/switch.py

View workflow job for this annotation

GitHub Actions / Check other linters

Incase ==> In case
# states does not.
self.async_write_ha_state()

@property
def is_on(self) -> bool | None:
Expand All @@ -359,15 +374,15 @@ def is_on(self) -> bool | None:
async def async_turn_on(self, **kwargs: Any) -> None:
"""Fire the on action."""
if self._on_script:
await self._on_script.async_run({}, context=self._context)
await self.async_run_script(self._on_script, context=self._context)
if self._attr_assumed_state:
self._state = True
self.async_write_ha_state()

async def async_turn_off(self, **kwargs: Any) -> None:
"""Fire the off action."""
if self._off_script:
await self._off_script.async_run({}, context=self._context)
await self.async_run_script(self._off_script, context=self._context)
if self._attr_assumed_state:
self._state = False
self.async_write_ha_state()
22 changes: 21 additions & 1 deletion homeassistant/components/template/trigger_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

from __future__ import annotations

from homeassistant.core import HomeAssistant, callback
from homeassistant.core import Context, HomeAssistant, callback
from homeassistant.helpers.script import Script, _VarsType
from homeassistant.helpers.template import TemplateStateFromEntityId
from homeassistant.helpers.trigger_template_entity import TriggerBaseEntity
from homeassistant.helpers.update_coordinator import CoordinatorEntity

Expand Down Expand Up @@ -56,3 +58,21 @@ def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self._process_data()
self.async_write_ha_state()

async def async_run_script(
self,
script: Script,
*,
run_variables: _VarsType | None = None,
context: Context | None = None,
) -> None:
"""Run an action script."""
if run_variables is None:
run_variables = {}
await script.async_run(
run_variables={
"this": TemplateStateFromEntityId(self.hass, self.entity_id),
**run_variables,
},
context=context,
)
Loading

0 comments on commit 7404c25

Please sign in to comment.