Convert color temperature to visible color in lights (#55219)
This commit is contained in:
parent
59d401e7b7
commit
e6e8d7eded
12 changed files with 49 additions and 24 deletions
|
@ -412,10 +412,11 @@ class ColorSettingTrait(_Trait):
|
||||||
|
|
||||||
def query_attributes(self):
|
def query_attributes(self):
|
||||||
"""Return color temperature query attributes."""
|
"""Return color temperature query attributes."""
|
||||||
color_modes = self.state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES)
|
color_mode = self.state.attributes.get(light.ATTR_COLOR_MODE)
|
||||||
|
|
||||||
color = {}
|
color = {}
|
||||||
|
|
||||||
if light.color_supported(color_modes):
|
if light.color_supported([color_mode]):
|
||||||
color_hs = self.state.attributes.get(light.ATTR_HS_COLOR)
|
color_hs = self.state.attributes.get(light.ATTR_HS_COLOR)
|
||||||
brightness = self.state.attributes.get(light.ATTR_BRIGHTNESS, 1)
|
brightness = self.state.attributes.get(light.ATTR_BRIGHTNESS, 1)
|
||||||
if color_hs is not None:
|
if color_hs is not None:
|
||||||
|
@ -425,7 +426,7 @@ class ColorSettingTrait(_Trait):
|
||||||
"value": brightness / 255,
|
"value": brightness / 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
if light.color_temp_supported(color_modes):
|
if light.color_temp_supported([color_mode]):
|
||||||
temp = self.state.attributes.get(light.ATTR_COLOR_TEMP)
|
temp = self.state.attributes.get(light.ATTR_COLOR_TEMP)
|
||||||
# Some faulty integrations might put 0 in here, raising exception.
|
# Some faulty integrations might put 0 in here, raising exception.
|
||||||
if temp == 0:
|
if temp == 0:
|
||||||
|
|
|
@ -829,6 +829,13 @@ class LightEntity(ToggleEntity):
|
||||||
data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3])
|
data[ATTR_RGB_COLOR] = tuple(int(x) for x in rgb_color[0:3])
|
||||||
data[ATTR_RGBWW_COLOR] = tuple(int(x) for x in rgbww_color[0:5])
|
data[ATTR_RGBWW_COLOR] = tuple(int(x) for x in rgbww_color[0:5])
|
||||||
data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
|
data[ATTR_XY_COLOR] = color_util.color_RGB_to_xy(*rgb_color)
|
||||||
|
elif color_mode == COLOR_MODE_COLOR_TEMP and self.color_temp:
|
||||||
|
hs_color = color_util.color_temperature_to_hs(
|
||||||
|
color_util.color_temperature_mired_to_kelvin(self.color_temp)
|
||||||
|
)
|
||||||
|
data[ATTR_HS_COLOR] = (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
|
return data
|
||||||
|
|
||||||
@final
|
@final
|
||||||
|
@ -863,7 +870,7 @@ class LightEntity(ToggleEntity):
|
||||||
if color_mode == COLOR_MODE_COLOR_TEMP:
|
if color_mode == COLOR_MODE_COLOR_TEMP:
|
||||||
data[ATTR_COLOR_TEMP] = self.color_temp
|
data[ATTR_COLOR_TEMP] = self.color_temp
|
||||||
|
|
||||||
if color_mode in COLOR_MODES_COLOR:
|
if color_mode in COLOR_MODES_COLOR or color_mode == COLOR_MODE_COLOR_TEMP:
|
||||||
data.update(self._light_internal_convert_color(color_mode))
|
data.update(self._light_internal_convert_color(color_mode))
|
||||||
|
|
||||||
if supported_features & SUPPORT_COLOR_TEMP and not self.supported_color_modes:
|
if supported_features & SUPPORT_COLOR_TEMP and not self.supported_color_modes:
|
||||||
|
|
|
@ -45,7 +45,7 @@ async def test_light_state_temperature(
|
||||||
assert state
|
assert state
|
||||||
assert state.attributes.get(ATTR_BRIGHTNESS) == 54
|
assert state.attributes.get(ATTR_BRIGHTNESS) == 54
|
||||||
assert state.attributes.get(ATTR_COLOR_TEMP) == 297
|
assert state.attributes.get(ATTR_COLOR_TEMP) == 297
|
||||||
assert state.attributes.get(ATTR_HS_COLOR) is None
|
assert state.attributes.get(ATTR_HS_COLOR) == (27.316, 47.743)
|
||||||
assert state.attributes.get(ATTR_COLOR_MODE) == COLOR_MODE_COLOR_TEMP
|
assert state.attributes.get(ATTR_COLOR_MODE) == COLOR_MODE_COLOR_TEMP
|
||||||
assert state.attributes.get(ATTR_MIN_MIREDS) == 143
|
assert state.attributes.get(ATTR_MIN_MIREDS) == 143
|
||||||
assert state.attributes.get(ATTR_MAX_MIREDS) == 344
|
assert state.attributes.get(ATTR_MAX_MIREDS) == 344
|
||||||
|
|
|
@ -576,6 +576,7 @@ async def test_color_setting_color_light(hass, supported_color_modes):
|
||||||
{
|
{
|
||||||
light.ATTR_HS_COLOR: (20, 94),
|
light.ATTR_HS_COLOR: (20, 94),
|
||||||
light.ATTR_BRIGHTNESS: 200,
|
light.ATTR_BRIGHTNESS: 200,
|
||||||
|
light.ATTR_COLOR_MODE: "hs",
|
||||||
"supported_color_modes": supported_color_modes,
|
"supported_color_modes": supported_color_modes,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -634,6 +635,7 @@ async def test_color_setting_temperature_light(hass):
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
{
|
{
|
||||||
light.ATTR_MIN_MIREDS: 200,
|
light.ATTR_MIN_MIREDS: 200,
|
||||||
|
light.ATTR_COLOR_MODE: "color_temp",
|
||||||
light.ATTR_COLOR_TEMP: 300,
|
light.ATTR_COLOR_TEMP: 300,
|
||||||
light.ATTR_MAX_MIREDS: 500,
|
light.ATTR_MAX_MIREDS: 500,
|
||||||
"supported_color_modes": ["color_temp"],
|
"supported_color_modes": ["color_temp"],
|
||||||
|
|
|
@ -618,12 +618,12 @@ async def test_emulated_color_temp_group(hass, enable_custom_integrations):
|
||||||
state = hass.states.get("light.test1")
|
state = hass.states.get("light.test1")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes[ATTR_COLOR_TEMP] == 200
|
assert state.attributes[ATTR_COLOR_TEMP] == 200
|
||||||
assert ATTR_HS_COLOR not in state.attributes.keys()
|
assert ATTR_HS_COLOR in state.attributes.keys()
|
||||||
|
|
||||||
state = hass.states.get("light.test2")
|
state = hass.states.get("light.test2")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes[ATTR_COLOR_TEMP] == 200
|
assert state.attributes[ATTR_COLOR_TEMP] == 200
|
||||||
assert ATTR_HS_COLOR not in state.attributes.keys()
|
assert ATTR_HS_COLOR in state.attributes.keys()
|
||||||
|
|
||||||
state = hass.states.get("light.test3")
|
state = hass.states.get("light.test3")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
|
|
|
@ -260,7 +260,7 @@ async def test_lights_color_mode(hass, mock_bridge):
|
||||||
assert lamp_1.state == "on"
|
assert lamp_1.state == "on"
|
||||||
assert lamp_1.attributes["brightness"] == 145
|
assert lamp_1.attributes["brightness"] == 145
|
||||||
assert lamp_1.attributes["color_temp"] == 467
|
assert lamp_1.attributes["color_temp"] == 467
|
||||||
assert "hs_color" not in lamp_1.attributes
|
assert "hs_color" in lamp_1.attributes
|
||||||
|
|
||||||
|
|
||||||
async def test_groups(hass, mock_bridge):
|
async def test_groups(hass, mock_bridge):
|
||||||
|
|
|
@ -1161,6 +1161,9 @@ async def test_light_backwards_compatibility_color_mode(
|
||||||
state = hass.states.get(entity2.entity_id)
|
state = hass.states.get(entity2.entity_id)
|
||||||
assert state.attributes["supported_color_modes"] == [light.COLOR_MODE_COLOR_TEMP]
|
assert state.attributes["supported_color_modes"] == [light.COLOR_MODE_COLOR_TEMP]
|
||||||
assert state.attributes["color_mode"] == light.COLOR_MODE_COLOR_TEMP
|
assert state.attributes["color_mode"] == light.COLOR_MODE_COLOR_TEMP
|
||||||
|
assert state.attributes["rgb_color"] == (201, 218, 255)
|
||||||
|
assert state.attributes["hs_color"] == (221.575, 20.9)
|
||||||
|
assert state.attributes["xy_color"] == (0.277, 0.287)
|
||||||
|
|
||||||
state = hass.states.get(entity3.entity_id)
|
state = hass.states.get(entity3.entity_id)
|
||||||
assert state.attributes["supported_color_modes"] == [light.COLOR_MODE_HS]
|
assert state.attributes["supported_color_modes"] == [light.COLOR_MODE_HS]
|
||||||
|
|
|
@ -393,7 +393,7 @@ async def test_legacy_controlling_state_via_topic(hass, mqtt_mock):
|
||||||
async_fire_mqtt_message(hass, "test_light_rgb/rgb/status", "125,125,125")
|
async_fire_mqtt_message(hass, "test_light_rgb/rgb/status", "125,125,125")
|
||||||
|
|
||||||
light_state = hass.states.get("light.test")
|
light_state = hass.states.get("light.test")
|
||||||
assert light_state.attributes.get("rgb_color") is None
|
assert light_state.attributes.get("rgb_color") == (255, 187, 131)
|
||||||
assert light_state.attributes.get(light.ATTR_COLOR_MODE) == "color_temp"
|
assert light_state.attributes.get(light.ATTR_COLOR_MODE) == "color_temp"
|
||||||
assert light_state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) == color_modes
|
assert light_state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) == color_modes
|
||||||
|
|
||||||
|
@ -636,13 +636,13 @@ async def test_legacy_invalid_state_via_topic(hass, mqtt_mock, caplog):
|
||||||
|
|
||||||
state = hass.states.get("light.test")
|
state = hass.states.get("light.test")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes.get("rgb_color") is None
|
assert state.attributes.get("rgb_color") == (255, 254, 250)
|
||||||
assert state.attributes.get("brightness") == 255
|
assert state.attributes.get("brightness") == 255
|
||||||
assert state.attributes.get("color_temp") == 153
|
assert state.attributes.get("color_temp") == 153
|
||||||
assert state.attributes.get("effect") == "none"
|
assert state.attributes.get("effect") == "none"
|
||||||
assert state.attributes.get("hs_color") is None
|
assert state.attributes.get("hs_color") == (54.768, 1.6)
|
||||||
assert state.attributes.get("white_value") == 255
|
assert state.attributes.get("white_value") == 255
|
||||||
assert state.attributes.get("xy_color") is None
|
assert state.attributes.get("xy_color") == (0.326, 0.333)
|
||||||
|
|
||||||
async_fire_mqtt_message(hass, "test_light_rgb/color_temp/status", "")
|
async_fire_mqtt_message(hass, "test_light_rgb/color_temp/status", "")
|
||||||
assert "Ignoring empty color temp message" in caplog.text
|
assert "Ignoring empty color temp message" in caplog.text
|
||||||
|
@ -776,12 +776,12 @@ async def test_invalid_state_via_topic(hass, mqtt_mock, caplog):
|
||||||
|
|
||||||
state = hass.states.get("light.test")
|
state = hass.states.get("light.test")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes.get("rgb_color") is None
|
assert state.attributes.get("rgb_color") == (255, 254, 250)
|
||||||
assert state.attributes.get("brightness") == 255
|
assert state.attributes.get("brightness") == 255
|
||||||
assert state.attributes.get("color_temp") == 153
|
assert state.attributes.get("color_temp") == 153
|
||||||
assert state.attributes.get("effect") == "none"
|
assert state.attributes.get("effect") == "none"
|
||||||
assert state.attributes.get("hs_color") is None
|
assert state.attributes.get("hs_color") == (54.768, 1.6)
|
||||||
assert state.attributes.get("xy_color") is None
|
assert state.attributes.get("xy_color") == (0.326, 0.333)
|
||||||
|
|
||||||
async_fire_mqtt_message(hass, "test_light_rgb/color_temp/status", "")
|
async_fire_mqtt_message(hass, "test_light_rgb/color_temp/status", "")
|
||||||
assert "Ignoring empty color temp message" in caplog.text
|
assert "Ignoring empty color temp message" in caplog.text
|
||||||
|
@ -988,7 +988,7 @@ async def test_legacy_controlling_state_via_topic_with_templates(hass, mqtt_mock
|
||||||
state = hass.states.get("light.test")
|
state = hass.states.get("light.test")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes.get("brightness") == 50
|
assert state.attributes.get("brightness") == 50
|
||||||
assert state.attributes.get("rgb_color") is None
|
assert state.attributes.get("rgb_color") == (255, 187, 131)
|
||||||
assert state.attributes.get("color_temp") == 300
|
assert state.attributes.get("color_temp") == 300
|
||||||
assert state.attributes.get("effect") == "rainbow"
|
assert state.attributes.get("effect") == "rainbow"
|
||||||
assert state.attributes.get("white_value") == 75
|
assert state.attributes.get("white_value") == 75
|
||||||
|
@ -1260,11 +1260,11 @@ async def test_legacy_sending_mqtt_commands_and_optimistic(hass, mqtt_mock):
|
||||||
|
|
||||||
state = hass.states.get("light.test")
|
state = hass.states.get("light.test")
|
||||||
assert state.state == STATE_ON
|
assert state.state == STATE_ON
|
||||||
assert state.attributes.get("rgb_color") is None
|
assert state.attributes.get("rgb_color") == (221, 229, 255)
|
||||||
assert state.attributes["brightness"] == 50
|
assert state.attributes["brightness"] == 50
|
||||||
assert state.attributes.get("hs_color") is None
|
assert state.attributes.get("hs_color") == (224.772, 13.249)
|
||||||
assert state.attributes["white_value"] == 80
|
assert state.attributes["white_value"] == 80
|
||||||
assert state.attributes.get("xy_color") is None
|
assert state.attributes.get("xy_color") == (0.296, 0.301)
|
||||||
assert state.attributes["color_temp"] == 125
|
assert state.attributes["color_temp"] == 125
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -392,7 +392,7 @@ async def test_controlling_state_via_topic(hass, mqtt_mock):
|
||||||
async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON", "color":null}')
|
async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON", "color":null}')
|
||||||
|
|
||||||
light_state = hass.states.get("light.test")
|
light_state = hass.states.get("light.test")
|
||||||
assert "hs_color" not in light_state.attributes
|
assert "hs_color" in light_state.attributes
|
||||||
|
|
||||||
async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON", "color_temp":155}')
|
async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON", "color_temp":155}')
|
||||||
|
|
||||||
|
|
|
@ -525,7 +525,7 @@ async def test_light(hass: HomeAssistant, light_mock_data: LightMockData) -> Non
|
||||||
assert state.state == "on"
|
assert state.state == "on"
|
||||||
assert state.attributes["brightness"] == 51
|
assert state.attributes["brightness"] == 51
|
||||||
assert state.attributes["color_temp"] == 222
|
assert state.attributes["color_temp"] == 222
|
||||||
assert "hs_color" not in state.attributes
|
assert "hs_color" in state.attributes
|
||||||
assert light_state["on_off"] == 1
|
assert light_state["on_off"] == 1
|
||||||
|
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
|
@ -582,7 +582,7 @@ async def test_light(hass: HomeAssistant, light_mock_data: LightMockData) -> Non
|
||||||
assert state.state == "on"
|
assert state.state == "on"
|
||||||
assert state.attributes["brightness"] == 168
|
assert state.attributes["brightness"] == 168
|
||||||
assert state.attributes["color_temp"] == 156
|
assert state.attributes["color_temp"] == 156
|
||||||
assert "hs_color" not in state.attributes
|
assert "hs_color" in state.attributes
|
||||||
assert light_state["brightness"] == 66
|
assert light_state["brightness"] == 66
|
||||||
assert light_state["hue"] == 77
|
assert light_state["hue"] == 77
|
||||||
assert light_state["saturation"] == 78
|
assert light_state["saturation"] == 78
|
||||||
|
|
|
@ -673,6 +673,9 @@ async def test_device_types(hass: HomeAssistant, caplog):
|
||||||
"color_temp": ct,
|
"color_temp": ct,
|
||||||
"color_mode": "color_temp",
|
"color_mode": "color_temp",
|
||||||
"supported_color_modes": ["color_temp", "hs", "rgb"],
|
"supported_color_modes": ["color_temp", "hs", "rgb"],
|
||||||
|
"hs_color": (26.812, 34.87),
|
||||||
|
"rgb_color": (255, 205, 166),
|
||||||
|
"xy_color": (0.421, 0.364),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"supported_features": 0,
|
"supported_features": 0,
|
||||||
|
@ -837,6 +840,9 @@ async def test_device_types(hass: HomeAssistant, caplog):
|
||||||
"color_temp": ct,
|
"color_temp": ct,
|
||||||
"color_mode": "color_temp",
|
"color_mode": "color_temp",
|
||||||
"supported_color_modes": ["color_temp"],
|
"supported_color_modes": ["color_temp"],
|
||||||
|
"hs_color": (26.812, 34.87),
|
||||||
|
"rgb_color": (255, 205, 166),
|
||||||
|
"xy_color": (0.421, 0.364),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST,
|
"effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST,
|
||||||
|
@ -870,6 +876,9 @@ async def test_device_types(hass: HomeAssistant, caplog):
|
||||||
"color_temp": ct,
|
"color_temp": ct,
|
||||||
"color_mode": "color_temp",
|
"color_mode": "color_temp",
|
||||||
"supported_color_modes": ["color_temp"],
|
"supported_color_modes": ["color_temp"],
|
||||||
|
"hs_color": (26.812, 34.87),
|
||||||
|
"rgb_color": (255, 205, 166),
|
||||||
|
"xy_color": (0.421, 0.364),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST,
|
"effect_list": YEELIGHT_TEMP_ONLY_EFFECT_LIST,
|
||||||
|
@ -893,6 +902,9 @@ async def test_device_types(hass: HomeAssistant, caplog):
|
||||||
"color_temp": bg_ct,
|
"color_temp": bg_ct,
|
||||||
"color_mode": "color_temp",
|
"color_mode": "color_temp",
|
||||||
"supported_color_modes": ["color_temp", "hs", "rgb"],
|
"supported_color_modes": ["color_temp", "hs", "rgb"],
|
||||||
|
"hs_color": (27.001, 19.243),
|
||||||
|
"rgb_color": (255, 228, 205),
|
||||||
|
"xy_color": (0.372, 0.35),
|
||||||
},
|
},
|
||||||
name=f"{UNIQUE_FRIENDLY_NAME} Ambilight",
|
name=f"{UNIQUE_FRIENDLY_NAME} Ambilight",
|
||||||
entity_id=f"{ENTITY_LIGHT}_ambilight",
|
entity_id=f"{ENTITY_LIGHT}_ambilight",
|
||||||
|
|
|
@ -129,7 +129,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
||||||
assert state.attributes[ATTR_COLOR_MODE] == "color_temp"
|
assert state.attributes[ATTR_COLOR_MODE] == "color_temp"
|
||||||
assert state.attributes[ATTR_BRIGHTNESS] == 255
|
assert state.attributes[ATTR_BRIGHTNESS] == 255
|
||||||
assert state.attributes[ATTR_COLOR_TEMP] == 370
|
assert state.attributes[ATTR_COLOR_TEMP] == 370
|
||||||
assert ATTR_RGB_COLOR not in state.attributes
|
assert ATTR_RGB_COLOR in state.attributes
|
||||||
|
|
||||||
# Test turning on with same brightness
|
# Test turning on with same brightness
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
|
@ -387,7 +387,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
||||||
assert state.attributes[ATTR_COLOR_MODE] == "color_temp"
|
assert state.attributes[ATTR_COLOR_MODE] == "color_temp"
|
||||||
assert state.attributes[ATTR_BRIGHTNESS] == 255
|
assert state.attributes[ATTR_BRIGHTNESS] == 255
|
||||||
assert state.attributes[ATTR_COLOR_TEMP] == 170
|
assert state.attributes[ATTR_COLOR_TEMP] == 170
|
||||||
assert ATTR_RGB_COLOR not in state.attributes
|
assert ATTR_RGB_COLOR in state.attributes
|
||||||
|
|
||||||
# Test turning on with same color temp
|
# Test turning on with same color temp
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue