Make flux switch async (#18277)

* Make flux switch async

* Fix line lengths

* Fix indentation

* Set tracker before await to avoid race condition

* Fix lint errors
This commit is contained in:
Jeff Wilson 2018-11-07 15:52:55 -05:00 committed by Anders Melchiorsen
parent 0bf054fb59
commit 5bab0018f5

View File

@ -19,7 +19,7 @@ from homeassistant.components.switch import DOMAIN, SwitchDevice
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, CONF_NAME, CONF_PLATFORM, CONF_LIGHTS, CONF_MODE, ATTR_ENTITY_ID, CONF_NAME, CONF_PLATFORM, CONF_LIGHTS, CONF_MODE,
SERVICE_TURN_ON, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET) SERVICE_TURN_ON, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET)
from homeassistant.helpers.event import track_time_interval from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.sun import get_astral_event_date from homeassistant.helpers.sun import get_astral_event_date
from homeassistant.util import slugify from homeassistant.util import slugify
from homeassistant.util.color import ( from homeassistant.util.color import (
@ -67,7 +67,8 @@ PLATFORM_SCHEMA = vol.Schema({
}) })
def set_lights_xy(hass, lights, x_val, y_val, brightness, transition): async def async_set_lights_xy(hass, lights, x_val, y_val, brightness,
transition):
"""Set color of array of lights.""" """Set color of array of lights."""
for light in lights: for light in lights:
if is_on(hass, light): if is_on(hass, light):
@ -79,11 +80,11 @@ def set_lights_xy(hass, lights, x_val, y_val, brightness, transition):
service_data[ATTR_WHITE_VALUE] = brightness service_data[ATTR_WHITE_VALUE] = brightness
if transition is not None: if transition is not None:
service_data[ATTR_TRANSITION] = transition service_data[ATTR_TRANSITION] = transition
hass.services.call( await hass.services.async_call(
LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) LIGHT_DOMAIN, SERVICE_TURN_ON, service_data)
def set_lights_temp(hass, lights, mired, brightness, transition): async def async_set_lights_temp(hass, lights, mired, brightness, transition):
"""Set color of array of lights.""" """Set color of array of lights."""
for light in lights: for light in lights:
if is_on(hass, light): if is_on(hass, light):
@ -94,11 +95,11 @@ def set_lights_temp(hass, lights, mired, brightness, transition):
service_data[ATTR_BRIGHTNESS] = brightness service_data[ATTR_BRIGHTNESS] = brightness
if transition is not None: if transition is not None:
service_data[ATTR_TRANSITION] = transition service_data[ATTR_TRANSITION] = transition
hass.services.call( await hass.services.async_call(
LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) LIGHT_DOMAIN, SERVICE_TURN_ON, service_data)
def set_lights_rgb(hass, lights, rgb, transition): async def async_set_lights_rgb(hass, lights, rgb, transition):
"""Set color of array of lights.""" """Set color of array of lights."""
for light in lights: for light in lights:
if is_on(hass, light): if is_on(hass, light):
@ -107,11 +108,12 @@ def set_lights_rgb(hass, lights, rgb, transition):
service_data[ATTR_RGB_COLOR] = rgb service_data[ATTR_RGB_COLOR] = rgb
if transition is not None: if transition is not None:
service_data[ATTR_TRANSITION] = transition service_data[ATTR_TRANSITION] = transition
hass.services.call( await hass.services.async_call(
LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) LIGHT_DOMAIN, SERVICE_TURN_ON, service_data)
def setup_platform(hass, config, add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities,
discovery_info=None):
"""Set up the Flux switches.""" """Set up the Flux switches."""
name = config.get(CONF_NAME) name = config.get(CONF_NAME)
lights = config.get(CONF_LIGHTS) lights = config.get(CONF_LIGHTS)
@ -129,14 +131,14 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
start_colortemp, sunset_colortemp, stop_colortemp, start_colortemp, sunset_colortemp, stop_colortemp,
brightness, disable_brightness_adjust, mode, interval, brightness, disable_brightness_adjust, mode, interval,
transition) transition)
add_entities([flux]) async_add_entities([flux])
def update(call=None): async def async_update(call=None):
"""Update lights.""" """Update lights."""
flux.flux_update() await flux.async_flux_update()
service_name = slugify("{} {}".format(name, 'update')) service_name = slugify("{} {}".format(name, 'update'))
hass.services.register(DOMAIN, service_name, update) hass.services.async_register(DOMAIN, service_name, async_update)
class FluxSwitch(SwitchDevice): class FluxSwitch(SwitchDevice):
@ -172,30 +174,30 @@ class FluxSwitch(SwitchDevice):
"""Return true if switch is on.""" """Return true if switch is on."""
return self.unsub_tracker is not None return self.unsub_tracker is not None
def turn_on(self, **kwargs): async def async_turn_on(self, **kwargs):
"""Turn on flux.""" """Turn on flux."""
if self.is_on: if self.is_on:
return return
# Make initial update self.unsub_tracker = async_track_time_interval(
self.flux_update()
self.unsub_tracker = track_time_interval(
self.hass, self.hass,
self.flux_update, self.async_flux_update,
datetime.timedelta(seconds=self._interval)) datetime.timedelta(seconds=self._interval))
self.schedule_update_ha_state() # Make initial update
await self.async_flux_update()
def turn_off(self, **kwargs): self.async_schedule_update_ha_state()
async def async_turn_off(self, **kwargs):
"""Turn off flux.""" """Turn off flux."""
if self.unsub_tracker is not None: if self.is_on:
self.unsub_tracker() self.unsub_tracker()
self.unsub_tracker = None self.unsub_tracker = None
self.schedule_update_ha_state() self.async_schedule_update_ha_state()
def flux_update(self, utcnow=None): async def async_flux_update(self, utcnow=None):
"""Update all the lights using flux.""" """Update all the lights using flux."""
if utcnow is None: if utcnow is None:
utcnow = dt_utcnow() utcnow = dt_utcnow()
@ -258,22 +260,23 @@ class FluxSwitch(SwitchDevice):
if self._disable_brightness_adjust: if self._disable_brightness_adjust:
brightness = None brightness = None
if self._mode == MODE_XY: if self._mode == MODE_XY:
set_lights_xy(self.hass, self._lights, x_val, await async_set_lights_xy(self.hass, self._lights, x_val,
y_val, brightness, self._transition) y_val, brightness, self._transition)
_LOGGER.info("Lights updated to x:%s y:%s brightness:%s, %s%% " _LOGGER.info("Lights updated to x:%s y:%s brightness:%s, %s%% "
"of %s cycle complete at %s", x_val, y_val, "of %s cycle complete at %s", x_val, y_val,
brightness, round( brightness, round(
percentage_complete * 100), time_state, now) percentage_complete * 100), time_state, now)
elif self._mode == MODE_RGB: elif self._mode == MODE_RGB:
set_lights_rgb(self.hass, self._lights, rgb, self._transition) await async_set_lights_rgb(self.hass, self._lights, rgb,
self._transition)
_LOGGER.info("Lights updated to rgb:%s, %s%% " _LOGGER.info("Lights updated to rgb:%s, %s%% "
"of %s cycle complete at %s", rgb, "of %s cycle complete at %s", rgb,
round(percentage_complete * 100), time_state, now) round(percentage_complete * 100), time_state, now)
else: else:
# Convert to mired and clamp to allowed values # Convert to mired and clamp to allowed values
mired = color_temperature_kelvin_to_mired(temp) mired = color_temperature_kelvin_to_mired(temp)
set_lights_temp(self.hass, self._lights, mired, brightness, await async_set_lights_temp(self.hass, self._lights, mired,
self._transition) brightness, self._transition)
_LOGGER.info("Lights updated to mired:%s brightness:%s, %s%% " _LOGGER.info("Lights updated to mired:%s brightness:%s, %s%% "
"of %s cycle complete at %s", mired, brightness, "of %s cycle complete at %s", mired, brightness,
round(percentage_complete * 100), time_state, now) round(percentage_complete * 100), time_state, now)