diff --git a/homeassistant/components/emulated_hue.py b/homeassistant/components/emulated_hue.py index 187ee0de603..667a73c6a16 100644 --- a/homeassistant/components/emulated_hue.py +++ b/homeassistant/components/emulated_hue.py @@ -18,7 +18,7 @@ from homeassistant import util, core from homeassistant.const import ( ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME, SERVICE_TURN_OFF, SERVICE_TURN_ON, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, - STATE_ON, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, + STATE_ON, STATE_OFF, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, ) from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_SUPPORTED_FEATURES, SUPPORT_BRIGHTNESS @@ -317,7 +317,16 @@ class HueLightsView(HomeAssistantView): # Construct what we need to send to the service data = {ATTR_ENTITY_ID: entity_id} - if brightness is not None: + # If the requested entity is a script add some variables + if entity.domain.lower() == "script": + data['variables'] = { + 'requested_state': STATE_ON if result else STATE_OFF + } + + if brightness is not None: + data['variables']['requested_level'] = brightness + + elif brightness is not None: data[ATTR_BRIGHTNESS] = brightness if entity.domain.lower() in config.off_maps_to_on_domains: @@ -401,6 +410,13 @@ def parse_hue_api_put_light_body(request_json, entity): report_brightness = True result = (brightness > 0) + elif entity.domain.lower() == "script": + # Convert 0-255 to 0-100 + level = int(request_json[HUE_API_STATE_BRI]) / 255 * 100 + + brightness = round(level) + report_brightness = True + result = True return (result, brightness) if report_brightness else (result, None) diff --git a/tests/components/test_emulated_hue.py b/tests/components/test_emulated_hue.py index edb2181c813..db46fcdbcc3 100755 --- a/tests/components/test_emulated_hue.py +++ b/tests/components/test_emulated_hue.py @@ -6,7 +6,7 @@ import requests from homeassistant import bootstrap, const, core import homeassistant.components as core_components -from homeassistant.components import emulated_hue, http, light +from homeassistant.components import emulated_hue, http, light, script from homeassistant.const import STATE_ON, STATE_OFF from homeassistant.components.emulated_hue import ( HUE_API_STATE_ON, HUE_API_STATE_BRI) @@ -129,6 +129,22 @@ class TestEmulatedHueExposedByDefault(unittest.TestCase): ] }) + bootstrap.setup_component(cls.hass, script.DOMAIN, { + 'script': { + 'set_kitchen_light': { + 'sequence': [ + { + 'service_template': "light.turn_{{ requested_state }}", + 'data_template': { + 'entity_id': 'light.kitchen_lights', + 'brightness': "{{ requested_level }}" + } + } + ] + } + } + }) + start_hass_instance(cls.hass) # Kitchen light is explicitly excluded from being exposed @@ -139,6 +155,14 @@ class TestEmulatedHueExposedByDefault(unittest.TestCase): kitchen_light_entity.entity_id, kitchen_light_entity.state, attributes=attrs) + # Expose the script + script_entity = cls.hass.states.get('script.set_kitchen_light') + attrs = dict(script_entity.attributes) + attrs[emulated_hue.ATTR_EMULATED_HUE] = True + cls.hass.states.set( + script_entity.entity_id, script_entity.state, attributes=attrs + ) + @classmethod def tearDownClass(cls): """Stop the class.""" @@ -157,6 +181,7 @@ class TestEmulatedHueExposedByDefault(unittest.TestCase): # Make sure the lights we added to the config are there self.assertTrue('light.ceiling_lights' in result_json) self.assertTrue('light.bed_light' in result_json) + self.assertTrue('script.set_kitchen_light' in result_json) self.assertTrue('light.kitchen_lights' not in result_json) def test_get_light_state(self): @@ -231,6 +256,35 @@ class TestEmulatedHueExposedByDefault(unittest.TestCase): 'light.kitchen_light', True) self.assertEqual(kitchen_result.status_code, 404) + def test_put_light_state_script(self): + """Test the setting of script variables.""" + # Turn the kitchen light off first + self.hass.services.call( + light.DOMAIN, const.SERVICE_TURN_OFF, + {const.ATTR_ENTITY_ID: 'light.kitchen_lights'}, + blocking=True) + + # Emulated hue converts 0-100% to 0-255. + level = 23 + brightness = round(level * 255 / 100) + + script_result = self.perform_put_light_state( + 'script.set_kitchen_light', True, brightness) + + script_result_json = script_result.json() + + self.assertEqual(script_result.status_code, 200) + self.assertEqual(len(script_result_json), 2) + + # Wait until script is complete before continuing + self.hass.block_till_done() + + kitchen_light = self.hass.states.get('light.kitchen_lights') + self.assertEqual(kitchen_light.state, 'on') + self.assertEqual( + kitchen_light.attributes[light.ATTR_BRIGHTNESS], + level) + def test_put_with_form_urlencoded_content_type(self): """Test the form with urlencoded content.""" # Needed for Alexa