Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optimistic mode to template switch #31637

Merged
merged 15 commits into from Jul 6, 2020
32 changes: 29 additions & 3 deletions homeassistant/components/template/switch.py
Expand Up @@ -24,6 +24,7 @@
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.event import async_track_state_change
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.script import Script

from . import extract_entities, initialise_templates
Expand All @@ -37,7 +38,7 @@

SWITCH_SCHEMA = vol.Schema(
{
vol.Required(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_ICON_TEMPLATE): cv.template,
vol.Optional(CONF_ENTITY_PICTURE_TEMPLATE): cv.template,
vol.Optional(CONF_AVAILABILITY_TEMPLATE): cv.template,
Expand All @@ -59,7 +60,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=

for device, device_config in config[CONF_SWITCHES].items():
friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device)
state_template = device_config[CONF_VALUE_TEMPLATE]
state_template = device_config.get(CONF_VALUE_TEMPLATE)
icon_template = device_config.get(CONF_ICON_TEMPLATE)
entity_picture_template = device_config.get(CONF_ENTITY_PICTURE_TEMPLATE)
availability_template = device_config.get(CONF_AVAILABILITY_TEMPLATE)
Expand Down Expand Up @@ -96,7 +97,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
async_add_entities(switches)


class SwitchTemplate(SwitchEntity):
class SwitchTemplate(SwitchEntity, RestoreEntity):
"""Representation of a Template switch."""

def __init__(
Expand Down Expand Up @@ -133,6 +134,18 @@ def __init__(
async def async_added_to_hass(self):
"""Register callbacks."""

if self._template is None:

# restore state after startup
await super().async_added_to_hass()
state = await self.async_get_last_state()
if state:
self._state = state.state == STATE_ON

# no need to listen for events
return

# set up event listening
@callback
def template_switch_state_listener(entity, old_state, new_state):
"""Handle target device state changes."""
Expand Down Expand Up @@ -184,13 +197,21 @@ def available(self) -> bool:
async def async_turn_on(self, **kwargs):
"""Fire the on action."""
await self._on_script.async_run(context=self._context)
if self._template is None:
self._state = True
self.async_write_ha_state()

async def async_turn_off(self, **kwargs):
"""Fire the off action."""
await self._off_script.async_run(context=self._context)
if self._template is None:
self._state = False
self.async_write_ha_state()

async def async_update(self):
"""Update the state from the template."""
if self._template is None:
return
try:
state = self._template.async_render().lower()

Expand Down Expand Up @@ -243,3 +264,8 @@ async def async_update(self):
self._name,
ex,
)

@property
def assumed_state(self):
"""State is assumed, if no template given."""
return self._template is None