diff --git a/homeassistant/components/light/__init__.py b/homeassistant/components/light/__init__.py index b8a97607215..bd428a84bed 100644 --- a/homeassistant/components/light/__init__.py +++ b/homeassistant/components/light/__init__.py @@ -83,17 +83,6 @@ COLOR_GROUP = "Color descriptors" LIGHT_PROFILES_FILE = "light_profiles.csv" -PROP_TO_ATTR = { - 'brightness': ATTR_BRIGHTNESS, - 'color_temp': ATTR_COLOR_TEMP, - 'min_mireds': ATTR_MIN_MIREDS, - 'max_mireds': ATTR_MAX_MIREDS, - 'hs_color': ATTR_HS_COLOR, - 'white_value': ATTR_WHITE_VALUE, - 'effect_list': ATTR_EFFECT_LIST, - 'effect': ATTR_EFFECT, -} - # Service call validation schemas VALID_TRANSITION = vol.All(vol.Coerce(float), vol.Clamp(min=0, max=6553)) VALID_BRIGHTNESS = vol.All(vol.Coerce(int), vol.Clamp(min=0, max=255)) @@ -494,29 +483,37 @@ class Light(ToggleEntity): def state_attributes(self): """Return optional state attributes.""" data = {} + supported_features = self.supported_features - if self.supported_features & SUPPORT_COLOR_TEMP: + if supported_features & SUPPORT_COLOR_TEMP: data[ATTR_MIN_MIREDS] = self.min_mireds data[ATTR_MAX_MIREDS] = self.max_mireds if self.is_on: - for prop, attr in PROP_TO_ATTR.items(): - value = getattr(self, prop) - if value is not None: - data[attr] = value + if supported_features & SUPPORT_BRIGHTNESS: + data[ATTR_BRIGHTNESS] = self.brightness - # Expose current color also as RGB and XY - if ATTR_HS_COLOR in data: - data[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB( - *data[ATTR_HS_COLOR]) - data[ATTR_XY_COLOR] = color_util.color_hs_to_xy( - *data[ATTR_HS_COLOR]) + if supported_features & SUPPORT_COLOR_TEMP: + data[ATTR_COLOR_TEMP] = self.color_temp + + if self.supported_features & SUPPORT_COLOR and self.hs_color: + # pylint: disable=unsubscriptable-object,not-an-iterable + hs_color = self.hs_color data[ATTR_HS_COLOR] = ( - round(data[ATTR_HS_COLOR][0], 3), - round(data[ATTR_HS_COLOR][1], 3), + round(hs_color[0], 3), + round(hs_color[1], 3), ) + data[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(*hs_color) + data[ATTR_XY_COLOR] = color_util.color_hs_to_xy(*hs_color) - return data + if supported_features & SUPPORT_WHITE_VALUE: + data[ATTR_WHITE_VALUE] = self.white_value + + if supported_features & SUPPORT_EFFECT: + data[ATTR_EFFECT_LIST] = self.effect_list + data[ATTR_EFFECT] = self.effect + + return {key: val for key, val in data.items() if val is not None} @property def supported_features(self): diff --git a/homeassistant/components/light/mqtt.py b/homeassistant/components/light/mqtt.py index cfc1ce27b94..09fa094c1b2 100644 --- a/homeassistant/components/light/mqtt.py +++ b/homeassistant/components/light/mqtt.py @@ -205,7 +205,7 @@ class MqttLight(MqttAvailability, Light): topic[CONF_COLOR_TEMP_COMMAND_TOPIC] is not None and SUPPORT_COLOR_TEMP) self._supported_features |= ( - topic[CONF_EFFECT_STATE_TOPIC] is not None and + topic[CONF_EFFECT_COMMAND_TOPIC] is not None and SUPPORT_EFFECT) self._supported_features |= ( topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None and diff --git a/tests/components/light/test_group.py b/tests/components/light/test_group.py index 26b949720d9..901535c5465 100644 --- a/tests/components/light/test_group.py +++ b/tests/components/light/test_group.py @@ -200,21 +200,24 @@ async def test_effect_list(hass): }}) hass.states.async_set('light.test1', 'on', - {'effect_list': ['None', 'Random', 'Colorloop']}) + {'effect_list': ['None', 'Random', 'Colorloop'], + 'supported_features': 4}) await hass.async_block_till_done() state = hass.states.get('light.light_group') assert set(state.attributes['effect_list']) == { 'None', 'Random', 'Colorloop'} hass.states.async_set('light.test2', 'on', - {'effect_list': ['None', 'Random', 'Rainbow']}) + {'effect_list': ['None', 'Random', 'Rainbow'], + 'supported_features': 4}) await hass.async_block_till_done() state = hass.states.get('light.light_group') assert set(state.attributes['effect_list']) == { 'None', 'Random', 'Colorloop', 'Rainbow'} hass.states.async_set('light.test1', 'off', - {'effect_list': ['None', 'Colorloop', 'Seven']}) + {'effect_list': ['None', 'Colorloop', 'Seven'], + 'supported_features': 4}) await hass.async_block_till_done() state = hass.states.get('light.light_group') assert set(state.attributes['effect_list']) == { @@ -229,27 +232,27 @@ async def test_effect(hass): }}) hass.states.async_set('light.test1', 'on', - {'effect': 'None', 'supported_features': 2}) + {'effect': 'None', 'supported_features': 6}) await hass.async_block_till_done() state = hass.states.get('light.light_group') assert state.attributes['effect'] == 'None' hass.states.async_set('light.test2', 'on', - {'effect': 'None', 'supported_features': 2}) + {'effect': 'None', 'supported_features': 6}) await hass.async_block_till_done() state = hass.states.get('light.light_group') assert state.attributes['effect'] == 'None' hass.states.async_set('light.test3', 'on', - {'effect': 'Random', 'supported_features': 2}) + {'effect': 'Random', 'supported_features': 6}) await hass.async_block_till_done() state = hass.states.get('light.light_group') assert state.attributes['effect'] == 'None' hass.states.async_set('light.test1', 'off', - {'effect': 'None', 'supported_features': 2}) + {'effect': 'None', 'supported_features': 6}) hass.states.async_set('light.test2', 'off', - {'effect': 'None', 'supported_features': 2}) + {'effect': 'None', 'supported_features': 6}) await hass.async_block_till_done() state = hass.states.get('light.light_group') assert state.attributes['effect'] == 'Random' diff --git a/tests/components/light/test_mqtt.py b/tests/components/light/test_mqtt.py index 7d6dd65e90a..404d60c0a2e 100644 --- a/tests/components/light/test_mqtt.py +++ b/tests/components/light/test_mqtt.py @@ -415,6 +415,12 @@ class TestLightMQTT(unittest.TestCase): 'name': 'test', 'state_topic': 'test_light_rgb/status', 'command_topic': 'test_light_rgb/set', + 'brightness_command_topic': 'test_light_rgb/brightness/set', + 'rgb_command_topic': 'test_light_rgb/rgb/set', + 'color_temp_command_topic': 'test_light_rgb/color_temp/set', + 'effect_command_topic': 'test_light_rgb/effect/set', + 'white_value_command_topic': 'test_light_rgb/white_value/set', + 'xy_command_topic': 'test_light_rgb/xy/set', 'brightness_state_topic': 'test_light_rgb/brightness/status', 'color_temp_state_topic': 'test_light_rgb/color_temp/status', 'effect_state_topic': 'test_light_rgb/effect/status', @@ -475,6 +481,7 @@ class TestLightMQTT(unittest.TestCase): 'effect_command_topic': 'test_light_rgb/effect/set', 'white_value_command_topic': 'test_light_rgb/white_value/set', 'xy_command_topic': 'test_light_rgb/xy/set', + 'effect_list': ['colorloop', 'random'], 'qos': 2, 'payload_on': 'on', 'payload_off': 'off' diff --git a/tests/components/light/test_mqtt_template.py b/tests/components/light/test_mqtt_template.py index e1c3da50e7e..1cf09f2ccb5 100644 --- a/tests/components/light/test_mqtt_template.py +++ b/tests/components/light/test_mqtt_template.py @@ -228,6 +228,8 @@ class TestLightMQTTTemplate(unittest.TestCase): '{{ green|d }}-' '{{ blue|d }}', 'command_off_template': 'off', + 'effect_list': ['colorloop', 'random'], + 'effect_command_topic': 'test_light_rgb/effect/set', 'qos': 2 } })