mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Convert switch to AsnycIO (#4382)
* Convert switch to AsnycIO * Move update entity to service * use time better for faster handling * Change to suggestion from paulus * Use new shedule_update_ha_state * fix lint * minimize executor calls
This commit is contained in:
parent
5d8a465c18
commit
41aaeb715a
@ -4,6 +4,7 @@ Component to interface with various switches that can be controlled remotely.
|
|||||||
For more details about this component, please refer to the documentation
|
For more details about this component, please refer to the documentation
|
||||||
at https://home-assistant.io/components/switch/
|
at https://home-assistant.io/components/switch/
|
||||||
"""
|
"""
|
||||||
|
import asyncio
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@ -69,38 +70,50 @@ def toggle(hass, entity_id=None):
|
|||||||
hass.services.call(DOMAIN, SERVICE_TOGGLE, data)
|
hass.services.call(DOMAIN, SERVICE_TOGGLE, data)
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
@asyncio.coroutine
|
||||||
|
def async_setup(hass, config):
|
||||||
"""Track states and offer events for switches."""
|
"""Track states and offer events for switches."""
|
||||||
component = EntityComponent(
|
component = EntityComponent(
|
||||||
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_SWITCHES)
|
_LOGGER, DOMAIN, hass, SCAN_INTERVAL, GROUP_NAME_ALL_SWITCHES)
|
||||||
component.setup(config)
|
yield from component.async_setup(config)
|
||||||
|
|
||||||
def handle_switch_service(service):
|
@asyncio.coroutine
|
||||||
|
def async_handle_switch_service(service):
|
||||||
"""Handle calls to the switch services."""
|
"""Handle calls to the switch services."""
|
||||||
target_switches = component.extract_from_service(service)
|
target_switches = component.async_extract_from_service(service)
|
||||||
|
|
||||||
|
update_tasks = []
|
||||||
for switch in target_switches:
|
for switch in target_switches:
|
||||||
if service.service == SERVICE_TURN_ON:
|
if service.service == SERVICE_TURN_ON:
|
||||||
switch.turn_on()
|
yield from switch.async_turn_on()
|
||||||
elif service.service == SERVICE_TOGGLE:
|
elif service.service == SERVICE_TOGGLE:
|
||||||
switch.toggle()
|
yield from switch.async_toggle()
|
||||||
else:
|
else:
|
||||||
switch.turn_off()
|
yield from switch.async_turn_off()
|
||||||
|
|
||||||
if switch.should_poll:
|
if switch.should_poll:
|
||||||
switch.update_ha_state(True)
|
update_coro = switch.async_update_ha_state(True)
|
||||||
|
if hasattr(switch, 'async_update'):
|
||||||
|
update_tasks.append(hass.loop.create_task(update_coro))
|
||||||
|
else:
|
||||||
|
yield from update_coro
|
||||||
|
|
||||||
descriptions = load_yaml_config_file(
|
if update_tasks:
|
||||||
os.path.join(os.path.dirname(__file__), 'services.yaml'))
|
yield from asyncio.wait(update_tasks, loop=hass.loop)
|
||||||
hass.services.register(DOMAIN, SERVICE_TURN_OFF, handle_switch_service,
|
|
||||||
descriptions.get(SERVICE_TURN_OFF),
|
descriptions = yield from hass.loop.run_in_executor(
|
||||||
schema=SWITCH_SERVICE_SCHEMA)
|
None, load_yaml_config_file, os.path.join(
|
||||||
hass.services.register(DOMAIN, SERVICE_TURN_ON, handle_switch_service,
|
os.path.dirname(__file__), 'services.yaml'))
|
||||||
descriptions.get(SERVICE_TURN_ON),
|
|
||||||
schema=SWITCH_SERVICE_SCHEMA)
|
hass.services.async_register(
|
||||||
hass.services.register(DOMAIN, SERVICE_TOGGLE, handle_switch_service,
|
DOMAIN, SERVICE_TURN_OFF, async_handle_switch_service,
|
||||||
descriptions.get(SERVICE_TOGGLE),
|
descriptions.get(SERVICE_TURN_OFF), schema=SWITCH_SERVICE_SCHEMA)
|
||||||
schema=SWITCH_SERVICE_SCHEMA)
|
hass.services.async_register(
|
||||||
|
DOMAIN, SERVICE_TURN_ON, async_handle_switch_service,
|
||||||
|
descriptions.get(SERVICE_TURN_ON), schema=SWITCH_SERVICE_SCHEMA)
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN, SERVICE_TOGGLE, async_handle_switch_service,
|
||||||
|
descriptions.get(SERVICE_TOGGLE), schema=SWITCH_SERVICE_SCHEMA)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -149,11 +149,11 @@ class CommandSwitch(SwitchDevice):
|
|||||||
if (CommandSwitch._switch(self._command_on) and
|
if (CommandSwitch._switch(self._command_on) and
|
||||||
not self._command_state):
|
not self._command_state):
|
||||||
self._state = True
|
self._state = True
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
if (CommandSwitch._switch(self._command_off) and
|
if (CommandSwitch._switch(self._command_off) and
|
||||||
not self._command_state):
|
not self._command_state):
|
||||||
self._state = False
|
self._state = False
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
@ -66,9 +66,9 @@ class DemoSwitch(SwitchDevice):
|
|||||||
def turn_on(self, **kwargs):
|
def turn_on(self, **kwargs):
|
||||||
"""Turn the switch on."""
|
"""Turn the switch on."""
|
||||||
self._state = True
|
self._state = True
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
self._state = False
|
self._state = False
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
@ -79,4 +79,4 @@ class EnOceanSwitch(enocean.EnOceanDevice, ToggleEntity):
|
|||||||
def value_changed(self, val):
|
def value_changed(self, val):
|
||||||
"""Update the internal state of the switch."""
|
"""Update the internal state of the switch."""
|
||||||
self._on_state = val
|
self._on_state = val
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
@ -137,7 +137,7 @@ class FluxSwitch(SwitchDevice):
|
|||||||
self._state = True
|
self._state = True
|
||||||
self.unsub_tracker = track_utc_time_change(self.hass, self.flux_update,
|
self.unsub_tracker = track_utc_time_change(self.hass, self.flux_update,
|
||||||
second=[0, 30])
|
second=[0, 30])
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn off flux."""
|
"""Turn off flux."""
|
||||||
@ -146,7 +146,7 @@ class FluxSwitch(SwitchDevice):
|
|||||||
self.unsub_tracker = None
|
self.unsub_tracker = None
|
||||||
|
|
||||||
self._state = False
|
self._state = False
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def flux_update(self, now=None):
|
def flux_update(self, now=None):
|
||||||
"""Update all the lights using flux."""
|
"""Update all the lights using flux."""
|
||||||
|
@ -40,7 +40,7 @@ class KNXSwitch(KNXGroupAddress, SwitchDevice):
|
|||||||
self.group_write(1)
|
self.group_write(1)
|
||||||
self._state = [1]
|
self._state = [1]
|
||||||
if not self.should_poll:
|
if not self.should_poll:
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the switch off.
|
"""Turn the switch off.
|
||||||
@ -50,4 +50,4 @@ class KNXSwitch(KNXGroupAddress, SwitchDevice):
|
|||||||
self.group_write(0)
|
self.group_write(0)
|
||||||
self._state = [0]
|
self._state = [0]
|
||||||
if not self.should_poll:
|
if not self.should_poll:
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
@ -117,7 +117,7 @@ class MqttSwitch(SwitchDevice):
|
|||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that switch has changed state.
|
# Optimistically assume that switch has changed state.
|
||||||
self._state = True
|
self._state = True
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
@ -126,4 +126,4 @@ class MqttSwitch(SwitchDevice):
|
|||||||
if self._optimistic:
|
if self._optimistic:
|
||||||
# Optimistically assume that switch has changed state.
|
# Optimistically assume that switch has changed state.
|
||||||
self._state = False
|
self._state = False
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
@ -137,7 +137,7 @@ class MySensorsSwitch(mysensors.MySensorsDeviceEntity, SwitchDevice):
|
|||||||
if self.gateway.optimistic:
|
if self.gateway.optimistic:
|
||||||
# optimistically assume that switch has changed state
|
# optimistically assume that switch has changed state
|
||||||
self._values[self.value_type] = STATE_ON
|
self._values[self.value_type] = STATE_ON
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self):
|
def turn_off(self):
|
||||||
"""Turn the switch off."""
|
"""Turn the switch off."""
|
||||||
@ -146,7 +146,7 @@ class MySensorsSwitch(mysensors.MySensorsDeviceEntity, SwitchDevice):
|
|||||||
if self.gateway.optimistic:
|
if self.gateway.optimistic:
|
||||||
# optimistically assume that switch has changed state
|
# optimistically assume that switch has changed state
|
||||||
self._values[self.value_type] = STATE_OFF
|
self._values[self.value_type] = STATE_OFF
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
|
|
||||||
class MySensorsIRSwitch(MySensorsSwitch):
|
class MySensorsIRSwitch(MySensorsSwitch):
|
||||||
@ -182,7 +182,7 @@ class MySensorsIRSwitch(MySensorsSwitch):
|
|||||||
# optimistically assume that switch has changed state
|
# optimistically assume that switch has changed state
|
||||||
self._values[self.value_type] = self._ir_code
|
self._values[self.value_type] = self._ir_code
|
||||||
self._values[set_req.V_LIGHT] = STATE_ON
|
self._values[set_req.V_LIGHT] = STATE_ON
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
# turn off switch after switch was turned on
|
# turn off switch after switch was turned on
|
||||||
self.turn_off()
|
self.turn_off()
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ class MySensorsIRSwitch(MySensorsSwitch):
|
|||||||
if self.gateway.optimistic:
|
if self.gateway.optimistic:
|
||||||
# optimistically assume that switch has changed state
|
# optimistically assume that switch has changed state
|
||||||
self._values[set_req.V_LIGHT] = STATE_OFF
|
self._values[set_req.V_LIGHT] = STATE_OFF
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update the controller with the latest value from a sensor."""
|
"""Update the controller with the latest value from a sensor."""
|
||||||
|
@ -156,7 +156,7 @@ class NetioSwitch(SwitchDevice):
|
|||||||
val[self.outlet - 1] = '1' if value else '0'
|
val[self.outlet - 1] = '1' if value else '0'
|
||||||
self.netio.get('port list %s' % ''.join(val))
|
self.netio.get('port list %s' % ''.join(val))
|
||||||
self.netio.states[self.outlet - 1] = value
|
self.netio.states[self.outlet - 1] = value
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
|
@ -127,11 +127,11 @@ class PilightSwitch(SwitchDevice):
|
|||||||
self._hass.services.call(pilight.DOMAIN, pilight.SERVICE_NAME,
|
self._hass.services.call(pilight.DOMAIN, pilight.SERVICE_NAME,
|
||||||
self._code_on, blocking=True)
|
self._code_on, blocking=True)
|
||||||
self._state = True
|
self._state = True
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self):
|
def turn_off(self):
|
||||||
"""Turn the switch on by calling pilight.send service with off code."""
|
"""Turn the switch on by calling pilight.send service with off code."""
|
||||||
self._hass.services.call(pilight.DOMAIN, pilight.SERVICE_NAME,
|
self._hass.services.call(pilight.DOMAIN, pilight.SERVICE_NAME,
|
||||||
self._code_off, blocking=True)
|
self._code_off, blocking=True)
|
||||||
self._state = False
|
self._state = False
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
@ -170,7 +170,7 @@ class PALoopbackSwitch(SwitchDevice):
|
|||||||
self._pa_svr.update_module_state(no_throttle=True)
|
self._pa_svr.update_module_state(no_throttle=True)
|
||||||
self._module_idx = self._pa_svr.get_module_idx(
|
self._module_idx = self._pa_svr.get_module_idx(
|
||||||
self._sink_name, self._source_name)
|
self._sink_name, self._source_name)
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
else:
|
else:
|
||||||
_LOGGER.warning(IGNORED_SWITCH_WARN)
|
_LOGGER.warning(IGNORED_SWITCH_WARN)
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ class PALoopbackSwitch(SwitchDevice):
|
|||||||
self._pa_svr.update_module_state(no_throttle=True)
|
self._pa_svr.update_module_state(no_throttle=True)
|
||||||
self._module_idx = self._pa_svr.get_module_idx(
|
self._module_idx = self._pa_svr.get_module_idx(
|
||||||
self._sink_name, self._source_name)
|
self._sink_name, self._source_name)
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
else:
|
else:
|
||||||
_LOGGER.warning(IGNORED_SWITCH_WARN)
|
_LOGGER.warning(IGNORED_SWITCH_WARN)
|
||||||
|
|
||||||
|
@ -77,10 +77,10 @@ class RPiGPIOSwitch(ToggleEntity):
|
|||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
rpi_gpio.write_output(self._port, 0 if self._invert_logic else 1)
|
rpi_gpio.write_output(self._port, 0 if self._invert_logic else 1)
|
||||||
self._state = True
|
self._state = True
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self):
|
def turn_off(self):
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
rpi_gpio.write_output(self._port, 1 if self._invert_logic else 0)
|
rpi_gpio.write_output(self._port, 1 if self._invert_logic else 0)
|
||||||
self._state = False
|
self._state = False
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
@ -119,7 +119,7 @@ class SCSGateSwitch(SwitchDevice):
|
|||||||
ToggleStatusTask(target=self._scs_id, toggled=True))
|
ToggleStatusTask(target=self._scs_id, toggled=True))
|
||||||
|
|
||||||
self._toggled = True
|
self._toggled = True
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
@ -129,7 +129,7 @@ class SCSGateSwitch(SwitchDevice):
|
|||||||
ToggleStatusTask(target=self._scs_id, toggled=False))
|
ToggleStatusTask(target=self._scs_id, toggled=False))
|
||||||
|
|
||||||
self._toggled = False
|
self._toggled = False
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def process_event(self, message):
|
def process_event(self, message):
|
||||||
"""Handle a SCSGate message related with this switch."""
|
"""Handle a SCSGate message related with this switch."""
|
||||||
|
@ -92,7 +92,7 @@ class SwitchTemplate(SwitchDevice):
|
|||||||
@callback
|
@callback
|
||||||
def template_switch_state_listener(entity, old_state, new_state):
|
def template_switch_state_listener(entity, old_state, new_state):
|
||||||
"""Called when the target device changes state."""
|
"""Called when the target device changes state."""
|
||||||
hass.async_add_job(self.async_update_ha_state, True)
|
hass.async_add_job(self.async_update_ha_state(True))
|
||||||
|
|
||||||
async_track_state_change(
|
async_track_state_change(
|
||||||
hass, entity_ids, template_switch_state_listener)
|
hass, entity_ids, template_switch_state_listener)
|
||||||
|
@ -36,13 +36,13 @@ class VeraSwitch(VeraDevice, SwitchDevice):
|
|||||||
"""Turn device on."""
|
"""Turn device on."""
|
||||||
self.vera_device.switch_on()
|
self.vera_device.switch_on()
|
||||||
self._state = STATE_ON
|
self._state = STATE_ON
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn device off."""
|
"""Turn device off."""
|
||||||
self.vera_device.switch_off()
|
self.vera_device.switch_off()
|
||||||
self._state = STATE_OFF
|
self._state = STATE_OFF
|
||||||
self.update_ha_state()
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_power_mwh(self):
|
def current_power_mwh(self):
|
||||||
|
@ -76,13 +76,11 @@ class WOLSwitch(SwitchDevice):
|
|||||||
def turn_on(self):
|
def turn_on(self):
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
self._wol.send_magic_packet(self._mac_address)
|
self._wol.send_magic_packet(self._mac_address)
|
||||||
self.update_ha_state()
|
|
||||||
|
|
||||||
def turn_off(self):
|
def turn_off(self):
|
||||||
"""Turn the device off if an off action is present."""
|
"""Turn the device off if an off action is present."""
|
||||||
if self._off_script is not None:
|
if self._off_script is not None:
|
||||||
self._off_script.run()
|
self._off_script.run()
|
||||||
self.update_ha_state()
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Check if device is on and update the state."""
|
"""Check if device is on and update the state."""
|
||||||
|
@ -150,14 +150,14 @@ class WemoSwitch(SwitchDevice):
|
|||||||
def turn_on(self, **kwargs):
|
def turn_on(self, **kwargs):
|
||||||
"""Turn the switch on."""
|
"""Turn the switch on."""
|
||||||
self._state = WEMO_ON
|
self._state = WEMO_ON
|
||||||
self.update_ha_state()
|
|
||||||
self.wemo.on()
|
self.wemo.on()
|
||||||
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def turn_off(self):
|
def turn_off(self):
|
||||||
"""Turn the switch off."""
|
"""Turn the switch off."""
|
||||||
self._state = WEMO_OFF
|
self._state = WEMO_OFF
|
||||||
self.update_ha_state()
|
|
||||||
self.wemo.off()
|
self.wemo.off()
|
||||||
|
self.shedule_update_ha_state()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Update WeMo state."""
|
"""Update WeMo state."""
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
"""An abstract class for entities."""
|
"""An abstract class for entities."""
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
import functools as ft
|
||||||
from timeit import default_timer as timer
|
from timeit import default_timer as timer
|
||||||
|
|
||||||
from typing import Any, Optional, List, Dict
|
from typing import Any, Optional, List, Dict
|
||||||
@ -269,6 +270,18 @@ class Entity(object):
|
|||||||
self.hass.states.async_set(
|
self.hass.states.async_set(
|
||||||
self.entity_id, state, attr, self.force_update)
|
self.entity_id, state, attr, self.force_update)
|
||||||
|
|
||||||
|
def shedule_update_ha_state(self, force_refresh=False):
|
||||||
|
"""Shedule a update ha state change task.
|
||||||
|
|
||||||
|
That is only needed on executor to not block.
|
||||||
|
"""
|
||||||
|
# We're already in a thread, do the force refresh here.
|
||||||
|
if force_refresh and not hasattr(self, 'async_update'):
|
||||||
|
self.update()
|
||||||
|
force_refresh = False
|
||||||
|
|
||||||
|
self.hass.add_job(self.async_update_ha_state(force_refresh))
|
||||||
|
|
||||||
def remove(self) -> None:
|
def remove(self) -> None:
|
||||||
"""Remove entitiy from HASS."""
|
"""Remove entitiy from HASS."""
|
||||||
run_coroutine_threadsafe(
|
run_coroutine_threadsafe(
|
||||||
@ -324,23 +337,23 @@ class ToggleEntity(Entity):
|
|||||||
|
|
||||||
def turn_on(self, **kwargs) -> None:
|
def turn_on(self, **kwargs) -> None:
|
||||||
"""Turn the entity on."""
|
"""Turn the entity on."""
|
||||||
run_coroutine_threadsafe(self.async_turn_on(**kwargs),
|
raise NotImplementedError()
|
||||||
self.hass.loop).result()
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_turn_on(self, **kwargs):
|
def async_turn_on(self, **kwargs):
|
||||||
"""Turn the entity on."""
|
"""Turn the entity on."""
|
||||||
raise NotImplementedError()
|
yield from self.hass.loop.run_in_executor(
|
||||||
|
None, ft.partial(self.turn_on, **kwargs))
|
||||||
|
|
||||||
def turn_off(self, **kwargs) -> None:
|
def turn_off(self, **kwargs) -> None:
|
||||||
"""Turn the entity off."""
|
"""Turn the entity off."""
|
||||||
run_coroutine_threadsafe(self.async_turn_off(**kwargs),
|
raise NotImplementedError()
|
||||||
self.hass.loop).result()
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_turn_off(self, **kwargs):
|
def async_turn_off(self, **kwargs):
|
||||||
"""Turn the entity off."""
|
"""Turn the entity off."""
|
||||||
raise NotImplementedError()
|
yield from self.hass.loop.run_in_executor(
|
||||||
|
None, ft.partial(self.turn_off, **kwargs))
|
||||||
|
|
||||||
def toggle(self) -> None:
|
def toggle(self) -> None:
|
||||||
"""Toggle the entity."""
|
"""Toggle the entity."""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user