RFC: Only use supported light properties (#15484)
* Only use supported light properties * Fix tests
This commit is contained in:
parent
e62e2bb131
commit
e427f9ee38
5 changed files with 43 additions and 34 deletions
|
@ -83,17 +83,6 @@ COLOR_GROUP = "Color descriptors"
|
||||||
|
|
||||||
LIGHT_PROFILES_FILE = "light_profiles.csv"
|
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
|
# Service call validation schemas
|
||||||
VALID_TRANSITION = vol.All(vol.Coerce(float), vol.Clamp(min=0, max=6553))
|
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))
|
VALID_BRIGHTNESS = vol.All(vol.Coerce(int), vol.Clamp(min=0, max=255))
|
||||||
|
@ -494,29 +483,37 @@ class Light(ToggleEntity):
|
||||||
def state_attributes(self):
|
def state_attributes(self):
|
||||||
"""Return optional state attributes."""
|
"""Return optional state attributes."""
|
||||||
data = {}
|
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_MIN_MIREDS] = self.min_mireds
|
||||||
data[ATTR_MAX_MIREDS] = self.max_mireds
|
data[ATTR_MAX_MIREDS] = self.max_mireds
|
||||||
|
|
||||||
if self.is_on:
|
if self.is_on:
|
||||||
for prop, attr in PROP_TO_ATTR.items():
|
if supported_features & SUPPORT_BRIGHTNESS:
|
||||||
value = getattr(self, prop)
|
data[ATTR_BRIGHTNESS] = self.brightness
|
||||||
if value is not None:
|
|
||||||
data[attr] = value
|
|
||||||
|
|
||||||
# Expose current color also as RGB and XY
|
if supported_features & SUPPORT_COLOR_TEMP:
|
||||||
if ATTR_HS_COLOR in data:
|
data[ATTR_COLOR_TEMP] = self.color_temp
|
||||||
data[ATTR_RGB_COLOR] = color_util.color_hs_to_RGB(
|
|
||||||
*data[ATTR_HS_COLOR])
|
if self.supported_features & SUPPORT_COLOR and self.hs_color:
|
||||||
data[ATTR_XY_COLOR] = color_util.color_hs_to_xy(
|
# pylint: disable=unsubscriptable-object,not-an-iterable
|
||||||
*data[ATTR_HS_COLOR])
|
hs_color = self.hs_color
|
||||||
data[ATTR_HS_COLOR] = (
|
data[ATTR_HS_COLOR] = (
|
||||||
round(data[ATTR_HS_COLOR][0], 3),
|
round(hs_color[0], 3),
|
||||||
round(data[ATTR_HS_COLOR][1], 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
|
@property
|
||||||
def supported_features(self):
|
def supported_features(self):
|
||||||
|
|
|
@ -205,7 +205,7 @@ class MqttLight(MqttAvailability, Light):
|
||||||
topic[CONF_COLOR_TEMP_COMMAND_TOPIC] is not None and
|
topic[CONF_COLOR_TEMP_COMMAND_TOPIC] is not None and
|
||||||
SUPPORT_COLOR_TEMP)
|
SUPPORT_COLOR_TEMP)
|
||||||
self._supported_features |= (
|
self._supported_features |= (
|
||||||
topic[CONF_EFFECT_STATE_TOPIC] is not None and
|
topic[CONF_EFFECT_COMMAND_TOPIC] is not None and
|
||||||
SUPPORT_EFFECT)
|
SUPPORT_EFFECT)
|
||||||
self._supported_features |= (
|
self._supported_features |= (
|
||||||
topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None and
|
topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None and
|
||||||
|
|
|
@ -200,21 +200,24 @@ async def test_effect_list(hass):
|
||||||
}})
|
}})
|
||||||
|
|
||||||
hass.states.async_set('light.test1', 'on',
|
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()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get('light.light_group')
|
state = hass.states.get('light.light_group')
|
||||||
assert set(state.attributes['effect_list']) == {
|
assert set(state.attributes['effect_list']) == {
|
||||||
'None', 'Random', 'Colorloop'}
|
'None', 'Random', 'Colorloop'}
|
||||||
|
|
||||||
hass.states.async_set('light.test2', 'on',
|
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()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get('light.light_group')
|
state = hass.states.get('light.light_group')
|
||||||
assert set(state.attributes['effect_list']) == {
|
assert set(state.attributes['effect_list']) == {
|
||||||
'None', 'Random', 'Colorloop', 'Rainbow'}
|
'None', 'Random', 'Colorloop', 'Rainbow'}
|
||||||
|
|
||||||
hass.states.async_set('light.test1', 'off',
|
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()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get('light.light_group')
|
state = hass.states.get('light.light_group')
|
||||||
assert set(state.attributes['effect_list']) == {
|
assert set(state.attributes['effect_list']) == {
|
||||||
|
@ -229,27 +232,27 @@ async def test_effect(hass):
|
||||||
}})
|
}})
|
||||||
|
|
||||||
hass.states.async_set('light.test1', 'on',
|
hass.states.async_set('light.test1', 'on',
|
||||||
{'effect': 'None', 'supported_features': 2})
|
{'effect': 'None', 'supported_features': 6})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get('light.light_group')
|
state = hass.states.get('light.light_group')
|
||||||
assert state.attributes['effect'] == 'None'
|
assert state.attributes['effect'] == 'None'
|
||||||
|
|
||||||
hass.states.async_set('light.test2', 'on',
|
hass.states.async_set('light.test2', 'on',
|
||||||
{'effect': 'None', 'supported_features': 2})
|
{'effect': 'None', 'supported_features': 6})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get('light.light_group')
|
state = hass.states.get('light.light_group')
|
||||||
assert state.attributes['effect'] == 'None'
|
assert state.attributes['effect'] == 'None'
|
||||||
|
|
||||||
hass.states.async_set('light.test3', 'on',
|
hass.states.async_set('light.test3', 'on',
|
||||||
{'effect': 'Random', 'supported_features': 2})
|
{'effect': 'Random', 'supported_features': 6})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get('light.light_group')
|
state = hass.states.get('light.light_group')
|
||||||
assert state.attributes['effect'] == 'None'
|
assert state.attributes['effect'] == 'None'
|
||||||
|
|
||||||
hass.states.async_set('light.test1', 'off',
|
hass.states.async_set('light.test1', 'off',
|
||||||
{'effect': 'None', 'supported_features': 2})
|
{'effect': 'None', 'supported_features': 6})
|
||||||
hass.states.async_set('light.test2', 'off',
|
hass.states.async_set('light.test2', 'off',
|
||||||
{'effect': 'None', 'supported_features': 2})
|
{'effect': 'None', 'supported_features': 6})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get('light.light_group')
|
state = hass.states.get('light.light_group')
|
||||||
assert state.attributes['effect'] == 'Random'
|
assert state.attributes['effect'] == 'Random'
|
||||||
|
|
|
@ -415,6 +415,12 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
'name': 'test',
|
'name': 'test',
|
||||||
'state_topic': 'test_light_rgb/status',
|
'state_topic': 'test_light_rgb/status',
|
||||||
'command_topic': 'test_light_rgb/set',
|
'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',
|
'brightness_state_topic': 'test_light_rgb/brightness/status',
|
||||||
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
|
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
|
||||||
'effect_state_topic': 'test_light_rgb/effect/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',
|
'effect_command_topic': 'test_light_rgb/effect/set',
|
||||||
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
||||||
'xy_command_topic': 'test_light_rgb/xy/set',
|
'xy_command_topic': 'test_light_rgb/xy/set',
|
||||||
|
'effect_list': ['colorloop', 'random'],
|
||||||
'qos': 2,
|
'qos': 2,
|
||||||
'payload_on': 'on',
|
'payload_on': 'on',
|
||||||
'payload_off': 'off'
|
'payload_off': 'off'
|
||||||
|
|
|
@ -228,6 +228,8 @@ class TestLightMQTTTemplate(unittest.TestCase):
|
||||||
'{{ green|d }}-'
|
'{{ green|d }}-'
|
||||||
'{{ blue|d }}',
|
'{{ blue|d }}',
|
||||||
'command_off_template': 'off',
|
'command_off_template': 'off',
|
||||||
|
'effect_list': ['colorloop', 'random'],
|
||||||
|
'effect_command_topic': 'test_light_rgb/effect/set',
|
||||||
'qos': 2
|
'qos': 2
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue