RFC: Only use supported light properties (#15484)

* Only use supported light properties

* Fix tests
This commit is contained in:
Anders Melchiorsen 2018-07-18 12:18:22 +02:00 committed by Paulus Schoutsen
parent e62e2bb131
commit e427f9ee38
5 changed files with 43 additions and 34 deletions

View file

@ -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):

View file

@ -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

View file

@ -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'

View file

@ -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'

View file

@ -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
}
})