Async input_*/zone migration (#4095)
* Async input_* * Async zone component * rename service callback
This commit is contained in:
parent
d4b3f56d53
commit
08a65a3b31
5 changed files with 68 additions and 48 deletions
|
@ -4,10 +4,12 @@ Component to keep track of user controlled booleans for within automation.
|
||||||
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/input_boolean/
|
at https://home-assistant.io/components/input_boolean/
|
||||||
"""
|
"""
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, SERVICE_TURN_OFF, SERVICE_TURN_ON,
|
ATTR_ENTITY_ID, CONF_ICON, CONF_NAME, SERVICE_TURN_OFF, SERVICE_TURN_ON,
|
||||||
SERVICE_TOGGLE, STATE_ON)
|
SERVICE_TOGGLE, STATE_ON)
|
||||||
|
@ -55,7 +57,8 @@ def toggle(hass, entity_id):
|
||||||
hass.services.call(DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: entity_id})
|
hass.services.call(DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: entity_id})
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
@asyncio.coroutine
|
||||||
|
def async_setup(hass, config):
|
||||||
"""Set up input boolean."""
|
"""Set up input boolean."""
|
||||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||||
|
|
||||||
|
@ -74,9 +77,10 @@ def setup(hass, config):
|
||||||
if not entities:
|
if not entities:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def handler_service(service):
|
@callback
|
||||||
|
def async_handler_service(service):
|
||||||
"""Handle a calls to the input boolean services."""
|
"""Handle a calls to the input boolean services."""
|
||||||
target_inputs = component.extract_from_service(service)
|
target_inputs = component.async_extract_from_service(service)
|
||||||
|
|
||||||
for input_b in target_inputs:
|
for input_b in target_inputs:
|
||||||
if service.service == SERVICE_TURN_ON:
|
if service.service == SERVICE_TURN_ON:
|
||||||
|
@ -86,15 +90,14 @@ def setup(hass, config):
|
||||||
else:
|
else:
|
||||||
input_b.toggle()
|
input_b.toggle()
|
||||||
|
|
||||||
hass.services.register(DOMAIN, SERVICE_TURN_OFF, handler_service,
|
hass.services.async_register(
|
||||||
schema=SERVICE_SCHEMA)
|
DOMAIN, SERVICE_TURN_OFF, async_handler_service, schema=SERVICE_SCHEMA)
|
||||||
hass.services.register(DOMAIN, SERVICE_TURN_ON, handler_service,
|
hass.services.async_register(
|
||||||
schema=SERVICE_SCHEMA)
|
DOMAIN, SERVICE_TURN_ON, async_handler_service, schema=SERVICE_SCHEMA)
|
||||||
hass.services.register(DOMAIN, SERVICE_TOGGLE, handler_service,
|
hass.services.async_register(
|
||||||
schema=SERVICE_SCHEMA)
|
DOMAIN, SERVICE_TOGGLE, async_handler_service, schema=SERVICE_SCHEMA)
|
||||||
|
|
||||||
component.add_entities(entities)
|
|
||||||
|
|
||||||
|
yield from component.async_add_entities(entities)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,9 +134,9 @@ class InputBoolean(ToggleEntity):
|
||||||
def turn_on(self, **kwargs):
|
def turn_on(self, **kwargs):
|
||||||
"""Turn the entity on."""
|
"""Turn the entity on."""
|
||||||
self._state = True
|
self._state = True
|
||||||
self.update_ha_state()
|
self.hass.loop.create_task(self.async_update_ha_state())
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn the entity off."""
|
"""Turn the entity off."""
|
||||||
self._state = False
|
self._state = False
|
||||||
self.update_ha_state()
|
self.hass.loop.create_task(self.async_update_ha_state())
|
||||||
|
|
|
@ -4,10 +4,12 @@ Component to offer a way to select an option from a list.
|
||||||
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/input_select/
|
at https://home-assistant.io/components/input_select/
|
||||||
"""
|
"""
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, CONF_ICON, CONF_NAME
|
from homeassistant.const import ATTR_ENTITY_ID, CONF_ICON, CONF_NAME
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
@ -86,7 +88,8 @@ def select_previous(hass, entity_id):
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
@asyncio.coroutine
|
||||||
|
def async_setup(hass, config):
|
||||||
"""Setup input select."""
|
"""Setup input select."""
|
||||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||||
|
|
||||||
|
@ -102,41 +105,43 @@ def setup(hass, config):
|
||||||
if not entities:
|
if not entities:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def select_option_service(call):
|
@callback
|
||||||
|
def async_select_option_service(call):
|
||||||
"""Handle a calls to the input select option service."""
|
"""Handle a calls to the input select option service."""
|
||||||
target_inputs = component.extract_from_service(call)
|
target_inputs = component.async_extract_from_service(call)
|
||||||
|
|
||||||
for input_select in target_inputs:
|
for input_select in target_inputs:
|
||||||
input_select.select_option(call.data[ATTR_OPTION])
|
input_select.select_option(call.data[ATTR_OPTION])
|
||||||
|
|
||||||
hass.services.register(DOMAIN, SERVICE_SELECT_OPTION,
|
hass.services.async_register(
|
||||||
select_option_service,
|
DOMAIN, SERVICE_SELECT_OPTION, async_select_option_service,
|
||||||
schema=SERVICE_SELECT_OPTION_SCHEMA)
|
schema=SERVICE_SELECT_OPTION_SCHEMA)
|
||||||
|
|
||||||
def select_next_service(call):
|
@callback
|
||||||
|
def async_select_next_service(call):
|
||||||
"""Handle a calls to the input select next service."""
|
"""Handle a calls to the input select next service."""
|
||||||
target_inputs = component.extract_from_service(call)
|
target_inputs = component.async_extract_from_service(call)
|
||||||
|
|
||||||
for input_select in target_inputs:
|
for input_select in target_inputs:
|
||||||
input_select.offset_index(1)
|
input_select.offset_index(1)
|
||||||
|
|
||||||
hass.services.register(DOMAIN, SERVICE_SELECT_NEXT,
|
hass.services.async_register(
|
||||||
select_next_service,
|
DOMAIN, SERVICE_SELECT_NEXT, async_select_next_service,
|
||||||
schema=SERVICE_SELECT_NEXT_SCHEMA)
|
schema=SERVICE_SELECT_NEXT_SCHEMA)
|
||||||
|
|
||||||
def select_previous_service(call):
|
@callback
|
||||||
|
def async_select_previous_service(call):
|
||||||
"""Handle a calls to the input select previous service."""
|
"""Handle a calls to the input select previous service."""
|
||||||
target_inputs = component.extract_from_service(call)
|
target_inputs = component.async_extract_from_service(call)
|
||||||
|
|
||||||
for input_select in target_inputs:
|
for input_select in target_inputs:
|
||||||
input_select.offset_index(-1)
|
input_select.offset_index(-1)
|
||||||
|
|
||||||
hass.services.register(DOMAIN, SERVICE_SELECT_PREVIOUS,
|
hass.services.async_register(
|
||||||
select_previous_service,
|
DOMAIN, SERVICE_SELECT_PREVIOUS, async_select_previous_service,
|
||||||
schema=SERVICE_SELECT_PREVIOUS_SCHEMA)
|
schema=SERVICE_SELECT_PREVIOUS_SCHEMA)
|
||||||
|
|
||||||
component.add_entities(entities)
|
|
||||||
|
|
||||||
|
yield from component.async_add_entities(entities)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -186,11 +191,11 @@ class InputSelect(Entity):
|
||||||
option, ', '.join(self._options))
|
option, ', '.join(self._options))
|
||||||
return
|
return
|
||||||
self._current_option = option
|
self._current_option = option
|
||||||
self.update_ha_state()
|
self.hass.loop.create_task(self.async_update_ha_state())
|
||||||
|
|
||||||
def offset_index(self, offset):
|
def offset_index(self, offset):
|
||||||
"""Offset current index."""
|
"""Offset current index."""
|
||||||
current_index = self._options.index(self._current_option)
|
current_index = self._options.index(self._current_option)
|
||||||
new_index = (current_index + offset) % len(self._options)
|
new_index = (current_index + offset) % len(self._options)
|
||||||
self._current_option = self._options[new_index]
|
self._current_option = self._options[new_index]
|
||||||
self.update_ha_state()
|
self.hass.loop.create_task(self.async_update_ha_state())
|
||||||
|
|
|
@ -4,10 +4,12 @@ Component to offer a way to select a value from a slider.
|
||||||
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/input_slider/
|
at https://home-assistant.io/components/input_slider/
|
||||||
"""
|
"""
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.core import callback
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT, CONF_ICON, CONF_NAME)
|
ATTR_ENTITY_ID, ATTR_UNIT_OF_MEASUREMENT, CONF_ICON, CONF_NAME)
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
@ -71,7 +73,8 @@ def select_value(hass, entity_id, value):
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
@asyncio.coroutine
|
||||||
|
def async_setup(hass, config):
|
||||||
"""Set up input slider."""
|
"""Set up input slider."""
|
||||||
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
component = EntityComponent(_LOGGER, DOMAIN, hass)
|
||||||
|
|
||||||
|
@ -92,19 +95,19 @@ def setup(hass, config):
|
||||||
if not entities:
|
if not entities:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def select_value_service(call):
|
@callback
|
||||||
|
def async_select_value_service(call):
|
||||||
"""Handle a calls to the input slider services."""
|
"""Handle a calls to the input slider services."""
|
||||||
target_inputs = component.extract_from_service(call)
|
target_inputs = component.async_extract_from_service(call)
|
||||||
|
|
||||||
for input_slider in target_inputs:
|
for input_slider in target_inputs:
|
||||||
input_slider.select_value(call.data[ATTR_VALUE])
|
input_slider.select_value(call.data[ATTR_VALUE])
|
||||||
|
|
||||||
hass.services.register(DOMAIN, SERVICE_SELECT_VALUE,
|
hass.services.async_register(
|
||||||
select_value_service,
|
DOMAIN, SERVICE_SELECT_VALUE, async_select_value_service,
|
||||||
schema=SERVICE_SELECT_VALUE_SCHEMA)
|
schema=SERVICE_SELECT_VALUE_SCHEMA)
|
||||||
|
|
||||||
component.add_entities(entities)
|
|
||||||
|
|
||||||
|
yield from component.async_add_entities(entities)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,4 +169,4 @@ class InputSlider(Entity):
|
||||||
num_value, self._minimum, self._maximum)
|
num_value, self._minimum, self._maximum)
|
||||||
return
|
return
|
||||||
self._current_value = num_value
|
self._current_value = num_value
|
||||||
self.update_ha_state()
|
self.hass.loop.create_task(self.async_update_ha_state())
|
||||||
|
|
|
@ -4,6 +4,7 @@ Support for the definition of zones.
|
||||||
For more details about this component, please refer to the documentation at
|
For more details about this component, please refer to the documentation at
|
||||||
https://home-assistant.io/components/zone/
|
https://home-assistant.io/components/zone/
|
||||||
"""
|
"""
|
||||||
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
@ -12,7 +13,7 @@ from homeassistant.const import (
|
||||||
ATTR_HIDDEN, ATTR_LATITUDE, ATTR_LONGITUDE, CONF_NAME, CONF_LATITUDE,
|
ATTR_HIDDEN, ATTR_LATITUDE, ATTR_LONGITUDE, CONF_NAME, CONF_LATITUDE,
|
||||||
CONF_LONGITUDE, CONF_ICON)
|
CONF_LONGITUDE, CONF_ICON)
|
||||||
from homeassistant.helpers import config_per_platform
|
from homeassistant.helpers import config_per_platform
|
||||||
from homeassistant.helpers.entity import Entity, generate_entity_id
|
from homeassistant.helpers.entity import Entity, async_generate_entity_id
|
||||||
from homeassistant.util.location import distance
|
from homeassistant.util.location import distance
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
|
@ -87,16 +88,19 @@ def in_zone(zone, latitude, longitude, radius=0):
|
||||||
return zone_dist - radius < zone.attributes[ATTR_RADIUS]
|
return zone_dist - radius < zone.attributes[ATTR_RADIUS]
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
@asyncio.coroutine
|
||||||
|
def async_setup(hass, config):
|
||||||
"""Setup zone."""
|
"""Setup zone."""
|
||||||
entities = set()
|
entities = set()
|
||||||
|
tasks = []
|
||||||
for _, entry in config_per_platform(config, DOMAIN):
|
for _, entry in config_per_platform(config, DOMAIN):
|
||||||
name = entry.get(CONF_NAME)
|
name = entry.get(CONF_NAME)
|
||||||
zone = Zone(hass, name, entry[CONF_LATITUDE], entry[CONF_LONGITUDE],
|
zone = Zone(hass, name, entry[CONF_LATITUDE], entry[CONF_LONGITUDE],
|
||||||
entry.get(CONF_RADIUS), entry.get(CONF_ICON),
|
entry.get(CONF_RADIUS), entry.get(CONF_ICON),
|
||||||
entry.get(CONF_PASSIVE))
|
entry.get(CONF_PASSIVE))
|
||||||
zone.entity_id = generate_entity_id(ENTITY_ID_FORMAT, name, entities)
|
zone.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, name,
|
||||||
zone.update_ha_state()
|
entities)
|
||||||
|
tasks.append(zone.async_update_ha_state())
|
||||||
entities.add(zone.entity_id)
|
entities.add(zone.entity_id)
|
||||||
|
|
||||||
if ENTITY_ID_HOME not in entities:
|
if ENTITY_ID_HOME not in entities:
|
||||||
|
@ -104,8 +108,9 @@ def setup(hass, config):
|
||||||
hass.config.latitude, hass.config.longitude,
|
hass.config.latitude, hass.config.longitude,
|
||||||
DEFAULT_RADIUS, ICON_HOME, False)
|
DEFAULT_RADIUS, ICON_HOME, False)
|
||||||
zone.entity_id = ENTITY_ID_HOME
|
zone.entity_id = ENTITY_ID_HOME
|
||||||
zone.update_ha_state()
|
tasks.append(zone.async_update_ha_state())
|
||||||
|
|
||||||
|
yield from asyncio.gather(*tasks, loop=hass.loop)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ def config_per_platform(config: ConfigType,
|
||||||
"""Generator to break a component config into different platforms.
|
"""Generator to break a component config into different platforms.
|
||||||
|
|
||||||
For example, will find 'switch', 'switch 2', 'switch 3', .. etc
|
For example, will find 'switch', 'switch 2', 'switch 3', .. etc
|
||||||
|
Async friendly.
|
||||||
"""
|
"""
|
||||||
for config_key in extract_domain_configs(config, domain):
|
for config_key in extract_domain_configs(config, domain):
|
||||||
platform_config = config[config_key]
|
platform_config = config[config_key]
|
||||||
|
@ -38,6 +39,9 @@ def config_per_platform(config: ConfigType,
|
||||||
|
|
||||||
|
|
||||||
def extract_domain_configs(config: ConfigType, domain: str) -> Sequence[str]:
|
def extract_domain_configs(config: ConfigType, domain: str) -> Sequence[str]:
|
||||||
"""Extract keys from config for given domain name."""
|
"""Extract keys from config for given domain name.
|
||||||
|
|
||||||
|
Async friendly.
|
||||||
|
"""
|
||||||
pattern = re.compile(r'^{}(| .+)$'.format(domain))
|
pattern = re.compile(r'^{}(| .+)$'.format(domain))
|
||||||
return [key for key in config.keys() if pattern.match(key)]
|
return [key for key in config.keys() if pattern.match(key)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue