update to async/await (#13137)

pull/13164/head
Per Osbäck 2018-03-12 21:57:13 +01:00 committed by Paulus Schoutsen
parent 95a528a75f
commit f9e07e617c
2 changed files with 38 additions and 50 deletions

View File

@ -4,7 +4,6 @@ Lights on Zigbee Home Automation networks.
For more details on this platform, please refer to the documentation For more details on this platform, please refer to the documentation
at https://home-assistant.io/components/light.zha/ at https://home-assistant.io/components/light.zha/
""" """
import asyncio
import logging import logging
from homeassistant.components import light, zha from homeassistant.components import light, zha
@ -23,8 +22,8 @@ CAPABILITIES_COLOR_TEMP = 0x10
UNSUPPORTED_ATTRIBUTE = 0x86 UNSUPPORTED_ATTRIBUTE = 0x86
@asyncio.coroutine async def async_setup_platform(hass, config, async_add_devices,
def async_setup_platform(hass, config, async_add_devices, discovery_info=None): discovery_info=None):
"""Set up the Zigbee Home Automation lights.""" """Set up the Zigbee Home Automation lights."""
discovery_info = zha.get_discovery_info(hass, discovery_info) discovery_info = zha.get_discovery_info(hass, discovery_info)
if discovery_info is None: if discovery_info is None:
@ -32,7 +31,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
endpoint = discovery_info['endpoint'] endpoint = discovery_info['endpoint']
if hasattr(endpoint, 'light_color'): if hasattr(endpoint, 'light_color'):
caps = yield from zha.safe_read( caps = await zha.safe_read(
endpoint.light_color, ['color_capabilities']) endpoint.light_color, ['color_capabilities'])
discovery_info['color_capabilities'] = caps.get('color_capabilities') discovery_info['color_capabilities'] = caps.get('color_capabilities')
if discovery_info['color_capabilities'] is None: if discovery_info['color_capabilities'] is None:
@ -40,7 +39,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
# attribute. In this version XY support is mandatory, but we need # attribute. In this version XY support is mandatory, but we need
# to probe to determine if the device supports color temperature. # to probe to determine if the device supports color temperature.
discovery_info['color_capabilities'] = CAPABILITIES_COLOR_XY discovery_info['color_capabilities'] = CAPABILITIES_COLOR_XY
result = yield from zha.safe_read( result = await zha.safe_read(
endpoint.light_color, ['color_temperature']) endpoint.light_color, ['color_temperature'])
if result.get('color_temperature') is not UNSUPPORTED_ATTRIBUTE: if result.get('color_temperature') is not UNSUPPORTED_ATTRIBUTE:
discovery_info['color_capabilities'] |= CAPABILITIES_COLOR_TEMP discovery_info['color_capabilities'] |= CAPABILITIES_COLOR_TEMP
@ -83,14 +82,13 @@ class Light(zha.Entity, light.Light):
return False return False
return bool(self._state) return bool(self._state)
@asyncio.coroutine async def async_turn_on(self, **kwargs):
def async_turn_on(self, **kwargs):
"""Turn the entity on.""" """Turn the entity on."""
duration = kwargs.get(light.ATTR_TRANSITION, DEFAULT_DURATION) duration = kwargs.get(light.ATTR_TRANSITION, DEFAULT_DURATION)
duration = duration * 10 # tenths of s duration = duration * 10 # tenths of s
if light.ATTR_COLOR_TEMP in kwargs: if light.ATTR_COLOR_TEMP in kwargs:
temperature = kwargs[light.ATTR_COLOR_TEMP] temperature = kwargs[light.ATTR_COLOR_TEMP]
yield from self._endpoint.light_color.move_to_color_temp( await self._endpoint.light_color.move_to_color_temp(
temperature, duration) temperature, duration)
self._color_temp = temperature self._color_temp = temperature
@ -102,7 +100,7 @@ class Light(zha.Entity, light.Light):
self._xy_color = (xyb[0], xyb[1]) self._xy_color = (xyb[0], xyb[1])
self._brightness = xyb[2] self._brightness = xyb[2]
if light.ATTR_XY_COLOR in kwargs or light.ATTR_RGB_COLOR in kwargs: if light.ATTR_XY_COLOR in kwargs or light.ATTR_RGB_COLOR in kwargs:
yield from self._endpoint.light_color.move_to_color( await self._endpoint.light_color.move_to_color(
int(self._xy_color[0] * 65535), int(self._xy_color[0] * 65535),
int(self._xy_color[1] * 65535), int(self._xy_color[1] * 65535),
duration, duration,
@ -113,7 +111,7 @@ class Light(zha.Entity, light.Light):
light.ATTR_BRIGHTNESS, self._brightness or 255) light.ATTR_BRIGHTNESS, self._brightness or 255)
self._brightness = brightness self._brightness = brightness
# Move to level with on/off: # Move to level with on/off:
yield from self._endpoint.level.move_to_level_with_on_off( await self._endpoint.level.move_to_level_with_on_off(
brightness, brightness,
duration duration
) )
@ -121,14 +119,13 @@ class Light(zha.Entity, light.Light):
self.async_schedule_update_ha_state() self.async_schedule_update_ha_state()
return return
yield from self._endpoint.on_off.on() await self._endpoint.on_off.on()
self._state = 1 self._state = 1
self.async_schedule_update_ha_state() self.async_schedule_update_ha_state()
@asyncio.coroutine async def async_turn_off(self, **kwargs):
def async_turn_off(self, **kwargs):
"""Turn the entity off.""" """Turn the entity off."""
yield from self._endpoint.on_off.off() await self._endpoint.on_off.off()
self._state = 0 self._state = 0
self.async_schedule_update_ha_state() self.async_schedule_update_ha_state()
@ -152,26 +149,25 @@ class Light(zha.Entity, light.Light):
"""Flag supported features.""" """Flag supported features."""
return self._supported_features return self._supported_features
@asyncio.coroutine async def async_update(self):
def async_update(self):
"""Retrieve latest state.""" """Retrieve latest state."""
result = yield from zha.safe_read(self._endpoint.on_off, ['on_off']) result = await zha.safe_read(self._endpoint.on_off, ['on_off'])
self._state = result.get('on_off', self._state) self._state = result.get('on_off', self._state)
if self._supported_features & light.SUPPORT_BRIGHTNESS: if self._supported_features & light.SUPPORT_BRIGHTNESS:
result = yield from zha.safe_read(self._endpoint.level, result = await zha.safe_read(self._endpoint.level,
['current_level']) ['current_level'])
self._brightness = result.get('current_level', self._brightness) self._brightness = result.get('current_level', self._brightness)
if self._supported_features & light.SUPPORT_COLOR_TEMP: if self._supported_features & light.SUPPORT_COLOR_TEMP:
result = yield from zha.safe_read(self._endpoint.light_color, result = await zha.safe_read(self._endpoint.light_color,
['color_temperature']) ['color_temperature'])
self._color_temp = result.get('color_temperature', self._color_temp = result.get('color_temperature',
self._color_temp) self._color_temp)
if self._supported_features & light.SUPPORT_XY_COLOR: if self._supported_features & light.SUPPORT_XY_COLOR:
result = yield from zha.safe_read(self._endpoint.light_color, result = await zha.safe_read(self._endpoint.light_color,
['current_x', 'current_y']) ['current_x', 'current_y'])
if 'current_x' in result and 'current_y' in result: if 'current_x' in result and 'current_y' in result:
self._xy_color = (result['current_x'], result['current_y']) self._xy_color = (result['current_x'], result['current_y'])

View File

@ -4,7 +4,6 @@ Support for ZigBee Home Automation devices.
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/zha/ https://home-assistant.io/components/zha/
""" """
import asyncio
import collections import collections
import enum import enum
import logging import logging
@ -80,8 +79,7 @@ APPLICATION_CONTROLLER = None
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@asyncio.coroutine async def async_setup(hass, config):
def async_setup(hass, config):
"""Set up ZHA. """Set up ZHA.
Will automatically load components to support devices found on the network. Will automatically load components to support devices found on the network.
@ -100,35 +98,33 @@ def async_setup(hass, config):
from zigpy_xbee.zigbee.application import ControllerApplication from zigpy_xbee.zigbee.application import ControllerApplication
radio = zigpy_xbee.api.XBee() radio = zigpy_xbee.api.XBee()
yield from radio.connect(usb_path, baudrate) await radio.connect(usb_path, baudrate)
database = config[DOMAIN].get(CONF_DATABASE) database = config[DOMAIN].get(CONF_DATABASE)
APPLICATION_CONTROLLER = ControllerApplication(radio, database) APPLICATION_CONTROLLER = ControllerApplication(radio, database)
listener = ApplicationListener(hass, config) listener = ApplicationListener(hass, config)
APPLICATION_CONTROLLER.add_listener(listener) APPLICATION_CONTROLLER.add_listener(listener)
yield from APPLICATION_CONTROLLER.startup(auto_form=True) await APPLICATION_CONTROLLER.startup(auto_form=True)
for device in APPLICATION_CONTROLLER.devices.values(): for device in APPLICATION_CONTROLLER.devices.values():
hass.async_add_job(listener.async_device_initialized(device, False)) hass.async_add_job(listener.async_device_initialized(device, False))
@asyncio.coroutine async def permit(service):
def permit(service):
"""Allow devices to join this network.""" """Allow devices to join this network."""
duration = service.data.get(ATTR_DURATION) duration = service.data.get(ATTR_DURATION)
_LOGGER.info("Permitting joins for %ss", duration) _LOGGER.info("Permitting joins for %ss", duration)
yield from APPLICATION_CONTROLLER.permit(duration) await APPLICATION_CONTROLLER.permit(duration)
hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit, hass.services.async_register(DOMAIN, SERVICE_PERMIT, permit,
schema=SERVICE_SCHEMAS[SERVICE_PERMIT]) schema=SERVICE_SCHEMAS[SERVICE_PERMIT])
@asyncio.coroutine async def remove(service):
def remove(service):
"""Remove a node from the network.""" """Remove a node from the network."""
from bellows.types import EmberEUI64, uint8_t from bellows.types import EmberEUI64, uint8_t
ieee = service.data.get(ATTR_IEEE) ieee = service.data.get(ATTR_IEEE)
ieee = EmberEUI64([uint8_t(p, base=16) for p in ieee.split(':')]) ieee = EmberEUI64([uint8_t(p, base=16) for p in ieee.split(':')])
_LOGGER.info("Removing node %s", ieee) _LOGGER.info("Removing node %s", ieee)
yield from APPLICATION_CONTROLLER.remove(ieee) await APPLICATION_CONTROLLER.remove(ieee)
hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove, hass.services.async_register(DOMAIN, SERVICE_REMOVE, remove,
schema=SERVICE_SCHEMAS[SERVICE_REMOVE]) schema=SERVICE_SCHEMAS[SERVICE_REMOVE])
@ -168,8 +164,7 @@ class ApplicationListener:
for device_entity in self._device_registry[device.ieee]: for device_entity in self._device_registry[device.ieee]:
self._hass.async_add_job(device_entity.async_remove()) self._hass.async_add_job(device_entity.async_remove())
@asyncio.coroutine async def async_device_initialized(self, device, join):
def async_device_initialized(self, device, join):
"""Handle device joined and basic information discovered (async).""" """Handle device joined and basic information discovered (async)."""
import zigpy.profiles import zigpy.profiles
import homeassistant.components.zha.const as zha_const import homeassistant.components.zha.const as zha_const
@ -179,7 +174,7 @@ class ApplicationListener:
if endpoint_id == 0: # ZDO if endpoint_id == 0: # ZDO
continue continue
discovered_info = yield from _discover_endpoint_info(endpoint) discovered_info = await _discover_endpoint_info(endpoint)
component = None component = None
profile_clusters = ([], []) profile_clusters = ([], [])
@ -218,7 +213,7 @@ class ApplicationListener:
discovery_info.update(discovered_info) discovery_info.update(discovered_info)
self._hass.data[DISCOVERY_KEY][device_key] = discovery_info self._hass.data[DISCOVERY_KEY][device_key] = discovery_info
yield from discovery.async_load_platform( await discovery.async_load_platform(
self._hass, self._hass,
component, component,
DOMAIN, DOMAIN,
@ -247,7 +242,7 @@ class ApplicationListener:
discovery_info.update(discovered_info) discovery_info.update(discovered_info)
self._hass.data[DISCOVERY_KEY][cluster_key] = discovery_info self._hass.data[DISCOVERY_KEY][cluster_key] = discovery_info
yield from discovery.async_load_platform( await discovery.async_load_platform(
self._hass, self._hass,
component, component,
DOMAIN, DOMAIN,
@ -323,8 +318,7 @@ class Entity(entity.Entity):
pass pass
@asyncio.coroutine async def _discover_endpoint_info(endpoint):
def _discover_endpoint_info(endpoint):
"""Find some basic information about an endpoint.""" """Find some basic information about an endpoint."""
extra_info = { extra_info = {
'manufacturer': None, 'manufacturer': None,
@ -333,20 +327,19 @@ def _discover_endpoint_info(endpoint):
if 0 not in endpoint.in_clusters: if 0 not in endpoint.in_clusters:
return extra_info return extra_info
@asyncio.coroutine async def read(attributes):
def read(attributes):
"""Read attributes and update extra_info convenience function.""" """Read attributes and update extra_info convenience function."""
result, _ = yield from endpoint.in_clusters[0].read_attributes( result, _ = await endpoint.in_clusters[0].read_attributes(
attributes, attributes,
allow_cache=True, allow_cache=True,
) )
extra_info.update(result) extra_info.update(result)
yield from read(['manufacturer', 'model']) await read(['manufacturer', 'model'])
if extra_info['manufacturer'] is None or extra_info['model'] is None: if extra_info['manufacturer'] is None or extra_info['model'] is None:
# Some devices fail at returning multiple results. Attempt separately. # Some devices fail at returning multiple results. Attempt separately.
yield from read(['manufacturer']) await read(['manufacturer'])
yield from read(['model']) await read(['model'])
for key, value in extra_info.items(): for key, value in extra_info.items():
if isinstance(value, bytes): if isinstance(value, bytes):
@ -376,8 +369,7 @@ def get_discovery_info(hass, discovery_info):
return all_discovery_info.get(discovery_key, None) return all_discovery_info.get(discovery_key, None)
@asyncio.coroutine async def safe_read(cluster, attributes):
def safe_read(cluster, attributes):
"""Swallow all exceptions from network read. """Swallow all exceptions from network read.
If we throw during initialization, setup fails. Rather have an entity that If we throw during initialization, setup fails. Rather have an entity that
@ -385,7 +377,7 @@ def safe_read(cluster, attributes):
probably only be used during initialization. probably only be used during initialization.
""" """
try: try:
result, _ = yield from cluster.read_attributes( result, _ = await cluster.read_attributes(
attributes, attributes,
allow_cache=False, allow_cache=False,
) )