From 619d329a1658c864951e1f683f803b77ea0abc8b Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Wed, 1 Nov 2017 12:16:05 +0100 Subject: [PATCH] Add xy support to Alexa HomeAPI v3 (#10268) * Add xy support to Alexa HomeAPI v3 * Update smart_home.py * Update smart_home.py * fix lint * fix copy paste * Update smart_home.py * simplify * Add test for xy/rgb * Update test_smart_home.py * Update smart_home.py * add test --- homeassistant/components/alexa/smart_home.py | 31 +++++++++----- tests/components/alexa/test_smart_home.py | 44 ++++++++++++++++++-- 2 files changed, 62 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/alexa/smart_home.py b/homeassistant/components/alexa/smart_home.py index 03aa5249d91..e65345cabca 100644 --- a/homeassistant/components/alexa/smart_home.py +++ b/homeassistant/components/alexa/smart_home.py @@ -26,6 +26,7 @@ MAPPING_COMPONENT = { 'LIGHT', ('Alexa.PowerController',), { light.SUPPORT_BRIGHTNESS: 'Alexa.BrightnessController', light.SUPPORT_RGB_COLOR: 'Alexa.ColorController', + light.SUPPORT_XY_COLOR: 'Alexa.ColorController', light.SUPPORT_COLOR_TEMP: 'Alexa.ColorTemperatureController', } ], @@ -219,10 +220,10 @@ def async_api_adjust_brightness(hass, request, entity): current = math.floor( int(entity.attributes.get(light.ATTR_BRIGHTNESS)) / 255 * 100) except ZeroDivisionError: - return api_error(request, error_type='INVALID_VALUE') + current = 0 # set brightness - brightness = brightness_delta + current + brightness = max(0, brightness_delta + current) yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, { ATTR_ENTITY_ID: entity.entity_id, light.ATTR_BRIGHTNESS_PCT: brightness, @@ -236,15 +237,25 @@ def async_api_adjust_brightness(hass, request, entity): @asyncio.coroutine def async_api_set_color(hass, request, entity): """Process a set color request.""" - hue = float(request[API_PAYLOAD]['color']['hue']) - saturation = float(request[API_PAYLOAD]['color']['saturation']) - brightness = float(request[API_PAYLOAD]['color']['brightness']) + supported = entity.attributes.get(ATTR_SUPPORTED_FEATURES) + rgb = color_util.color_hsb_to_RGB( + float(request[API_PAYLOAD]['color']['hue']), + float(request[API_PAYLOAD]['color']['saturation']), + float(request[API_PAYLOAD]['color']['brightness']) + ) - rgb = color_util.color_hsb_to_RGB(hue, saturation, brightness) - yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, { - ATTR_ENTITY_ID: entity.entity_id, - light.ATTR_RGB_COLOR: rgb, - }, blocking=True) + if supported & light.SUPPORT_RGB_COLOR > 0: + yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, { + ATTR_ENTITY_ID: entity.entity_id, + light.ATTR_RGB_COLOR: rgb, + }, blocking=True) + else: + xyz = color_util.color_RGB_to_xy(*rgb) + yield from hass.services.async_call(entity.domain, SERVICE_TURN_ON, { + ATTR_ENTITY_ID: entity.entity_id, + light.ATTR_XY_COLOR: (xyz[0], xyz[1]), + light.ATTR_BRIGHTNESS: xyz[2], + }, blocking=True) return api_message(request) diff --git a/tests/components/alexa/test_smart_home.py b/tests/components/alexa/test_smart_home.py index 3d42add8ae8..4c79e95b324 100644 --- a/tests/components/alexa/test_smart_home.py +++ b/tests/components/alexa/test_smart_home.py @@ -282,7 +282,8 @@ def test_api_set_brightness(hass): @asyncio.coroutine -@pytest.mark.parametrize("result,adjust", [(25, '-5'), (35, '5')]) +@pytest.mark.parametrize( + "result,adjust", [(25, '-5'), (35, '5'), (0, '-80')]) def test_api_adjust_brightness(hass, result, adjust): """Test api adjust brightness process.""" request = get_new_request( @@ -311,7 +312,7 @@ def test_api_adjust_brightness(hass, result, adjust): @asyncio.coroutine -def test_api_set_color(hass): +def test_api_set_color_rgb(hass): """Test api set color process.""" request = get_new_request( 'Alexa.ColorController', 'SetColor', 'light#test') @@ -325,7 +326,10 @@ def test_api_set_color(hass): # settup test devices hass.states.async_set( - 'light.test', 'off', {'friendly_name': "Test light"}) + 'light.test', 'off', { + 'friendly_name': "Test light", + 'supported_features': 16, + }) call_light = async_mock_service(hass, 'light', 'turn_on') @@ -340,6 +344,40 @@ def test_api_set_color(hass): assert msg['header']['name'] == 'Response' +@asyncio.coroutine +def test_api_set_color_xy(hass): + """Test api set color process.""" + request = get_new_request( + 'Alexa.ColorController', 'SetColor', 'light#test') + + # add payload + request['directive']['payload']['color'] = { + 'hue': '120', + 'saturation': '0.612', + 'brightness': '0.342', + } + + # settup test devices + hass.states.async_set( + 'light.test', 'off', { + 'friendly_name': "Test light", + 'supported_features': 64, + }) + + call_light = async_mock_service(hass, 'light', 'turn_on') + + msg = yield from smart_home.async_handle_message(hass, request) + + assert 'event' in msg + msg = msg['event'] + + assert len(call_light) == 1 + assert call_light[0].data['entity_id'] == 'light.test' + assert call_light[0].data['xy_color'] == (0.23, 0.585) + assert call_light[0].data['brightness'] == 18 + assert msg['header']['name'] == 'Response' + + @asyncio.coroutine def test_api_set_color_temperature(hass): """Test api set color temperature process."""