mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Enable emulated_hue setting XY color and transition time by client (#45844)
* Enable setting XY color and transition time by client * New test for setting XY color value * Correct block outdent * New test for setting transition time value * Fixed commented out code
This commit is contained in:
parent
5a0715d388
commit
14d914e300
@ -43,9 +43,12 @@ from homeassistant.components.light import (
|
|||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_COLOR_TEMP,
|
ATTR_COLOR_TEMP,
|
||||||
ATTR_HS_COLOR,
|
ATTR_HS_COLOR,
|
||||||
|
ATTR_TRANSITION,
|
||||||
|
ATTR_XY_COLOR,
|
||||||
SUPPORT_BRIGHTNESS,
|
SUPPORT_BRIGHTNESS,
|
||||||
SUPPORT_COLOR,
|
SUPPORT_COLOR,
|
||||||
SUPPORT_COLOR_TEMP,
|
SUPPORT_COLOR_TEMP,
|
||||||
|
SUPPORT_TRANSITION,
|
||||||
)
|
)
|
||||||
from homeassistant.components.media_player.const import (
|
from homeassistant.components.media_player.const import (
|
||||||
ATTR_MEDIA_VOLUME_LEVEL,
|
ATTR_MEDIA_VOLUME_LEVEL,
|
||||||
@ -82,6 +85,8 @@ STATE_COLORMODE = "colormode"
|
|||||||
STATE_HUE = "hue"
|
STATE_HUE = "hue"
|
||||||
STATE_SATURATION = "sat"
|
STATE_SATURATION = "sat"
|
||||||
STATE_COLOR_TEMP = "ct"
|
STATE_COLOR_TEMP = "ct"
|
||||||
|
STATE_TRANSITON = "tt"
|
||||||
|
STATE_XY = "xy"
|
||||||
|
|
||||||
# Hue API states, defined separately in case they change
|
# Hue API states, defined separately in case they change
|
||||||
HUE_API_STATE_ON = "on"
|
HUE_API_STATE_ON = "on"
|
||||||
@ -90,7 +95,9 @@ HUE_API_STATE_COLORMODE = "colormode"
|
|||||||
HUE_API_STATE_HUE = "hue"
|
HUE_API_STATE_HUE = "hue"
|
||||||
HUE_API_STATE_SAT = "sat"
|
HUE_API_STATE_SAT = "sat"
|
||||||
HUE_API_STATE_CT = "ct"
|
HUE_API_STATE_CT = "ct"
|
||||||
|
HUE_API_STATE_XY = "xy"
|
||||||
HUE_API_STATE_EFFECT = "effect"
|
HUE_API_STATE_EFFECT = "effect"
|
||||||
|
HUE_API_STATE_TRANSITION = "transitiontime"
|
||||||
|
|
||||||
# Hue API min/max values - https://developers.meethue.com/develop/hue-api/lights-api/
|
# Hue API min/max values - https://developers.meethue.com/develop/hue-api/lights-api/
|
||||||
HUE_API_STATE_BRI_MIN = 1 # Brightness
|
HUE_API_STATE_BRI_MIN = 1 # Brightness
|
||||||
@ -357,6 +364,8 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||||||
STATE_HUE: None,
|
STATE_HUE: None,
|
||||||
STATE_SATURATION: None,
|
STATE_SATURATION: None,
|
||||||
STATE_COLOR_TEMP: None,
|
STATE_COLOR_TEMP: None,
|
||||||
|
STATE_XY: None,
|
||||||
|
STATE_TRANSITON: None,
|
||||||
}
|
}
|
||||||
|
|
||||||
if HUE_API_STATE_ON in request_json:
|
if HUE_API_STATE_ON in request_json:
|
||||||
@ -372,6 +381,7 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||||||
(HUE_API_STATE_HUE, STATE_HUE),
|
(HUE_API_STATE_HUE, STATE_HUE),
|
||||||
(HUE_API_STATE_SAT, STATE_SATURATION),
|
(HUE_API_STATE_SAT, STATE_SATURATION),
|
||||||
(HUE_API_STATE_CT, STATE_COLOR_TEMP),
|
(HUE_API_STATE_CT, STATE_COLOR_TEMP),
|
||||||
|
(HUE_API_STATE_TRANSITION, STATE_TRANSITON),
|
||||||
):
|
):
|
||||||
if key in request_json:
|
if key in request_json:
|
||||||
try:
|
try:
|
||||||
@ -379,6 +389,17 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
_LOGGER.error("Unable to parse data (2): %s", request_json)
|
_LOGGER.error("Unable to parse data (2): %s", request_json)
|
||||||
return self.json_message("Bad request", HTTP_BAD_REQUEST)
|
return self.json_message("Bad request", HTTP_BAD_REQUEST)
|
||||||
|
if HUE_API_STATE_XY in request_json:
|
||||||
|
try:
|
||||||
|
parsed[STATE_XY] = tuple(
|
||||||
|
(
|
||||||
|
float(request_json[HUE_API_STATE_XY][0]),
|
||||||
|
float(request_json[HUE_API_STATE_XY][1]),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
_LOGGER.error("Unable to parse data (2): %s", request_json)
|
||||||
|
return self.json_message("Bad request", HTTP_BAD_REQUEST)
|
||||||
|
|
||||||
if HUE_API_STATE_BRI in request_json:
|
if HUE_API_STATE_BRI in request_json:
|
||||||
if entity.domain == light.DOMAIN:
|
if entity.domain == light.DOMAIN:
|
||||||
@ -444,10 +465,17 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||||||
|
|
||||||
data[ATTR_HS_COLOR] = (hue, sat)
|
data[ATTR_HS_COLOR] = (hue, sat)
|
||||||
|
|
||||||
|
if parsed[STATE_XY] is not None:
|
||||||
|
data[ATTR_XY_COLOR] = parsed[STATE_XY]
|
||||||
|
|
||||||
if entity_features & SUPPORT_COLOR_TEMP:
|
if entity_features & SUPPORT_COLOR_TEMP:
|
||||||
if parsed[STATE_COLOR_TEMP] is not None:
|
if parsed[STATE_COLOR_TEMP] is not None:
|
||||||
data[ATTR_COLOR_TEMP] = parsed[STATE_COLOR_TEMP]
|
data[ATTR_COLOR_TEMP] = parsed[STATE_COLOR_TEMP]
|
||||||
|
|
||||||
|
if entity_features & SUPPORT_TRANSITION:
|
||||||
|
if parsed[STATE_TRANSITON] is not None:
|
||||||
|
data[ATTR_TRANSITION] = parsed[STATE_TRANSITON] / 10
|
||||||
|
|
||||||
# If the requested entity is a script, add some variables
|
# If the requested entity is a script, add some variables
|
||||||
elif entity.domain == script.DOMAIN:
|
elif entity.domain == script.DOMAIN:
|
||||||
data["variables"] = {
|
data["variables"] = {
|
||||||
@ -557,6 +585,8 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||||||
(STATE_HUE, HUE_API_STATE_HUE),
|
(STATE_HUE, HUE_API_STATE_HUE),
|
||||||
(STATE_SATURATION, HUE_API_STATE_SAT),
|
(STATE_SATURATION, HUE_API_STATE_SAT),
|
||||||
(STATE_COLOR_TEMP, HUE_API_STATE_CT),
|
(STATE_COLOR_TEMP, HUE_API_STATE_CT),
|
||||||
|
(STATE_XY, HUE_API_STATE_XY),
|
||||||
|
(STATE_TRANSITON, HUE_API_STATE_TRANSITION),
|
||||||
):
|
):
|
||||||
if parsed[key] is not None:
|
if parsed[key] is not None:
|
||||||
json_response.append(
|
json_response.append(
|
||||||
|
@ -28,6 +28,8 @@ from homeassistant.components.emulated_hue.hue_api import (
|
|||||||
HUE_API_STATE_HUE,
|
HUE_API_STATE_HUE,
|
||||||
HUE_API_STATE_ON,
|
HUE_API_STATE_ON,
|
||||||
HUE_API_STATE_SAT,
|
HUE_API_STATE_SAT,
|
||||||
|
HUE_API_STATE_TRANSITION,
|
||||||
|
HUE_API_STATE_XY,
|
||||||
HUE_API_USERNAME,
|
HUE_API_USERNAME,
|
||||||
HueAllGroupsStateView,
|
HueAllGroupsStateView,
|
||||||
HueAllLightsStateView,
|
HueAllLightsStateView,
|
||||||
@ -39,6 +41,7 @@ from homeassistant.components.emulated_hue.hue_api import (
|
|||||||
)
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
|
ATTR_SUPPORTED_FEATURES,
|
||||||
CONTENT_TYPE_JSON,
|
CONTENT_TYPE_JSON,
|
||||||
HTTP_NOT_FOUND,
|
HTTP_NOT_FOUND,
|
||||||
HTTP_OK,
|
HTTP_OK,
|
||||||
@ -51,7 +54,11 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed, get_test_instance_port
|
from tests.common import (
|
||||||
|
async_fire_time_changed,
|
||||||
|
async_mock_service,
|
||||||
|
get_test_instance_port,
|
||||||
|
)
|
||||||
|
|
||||||
HTTP_SERVER_PORT = get_test_instance_port()
|
HTTP_SERVER_PORT = get_test_instance_port()
|
||||||
BRIDGE_SERVER_PORT = get_test_instance_port()
|
BRIDGE_SERVER_PORT = get_test_instance_port()
|
||||||
@ -663,6 +670,25 @@ async def test_put_light_state(hass, hass_hue, hue_client):
|
|||||||
assert ceiling_json["state"][HUE_API_STATE_HUE] == 4369
|
assert ceiling_json["state"][HUE_API_STATE_HUE] == 4369
|
||||||
assert ceiling_json["state"][HUE_API_STATE_SAT] == 127
|
assert ceiling_json["state"][HUE_API_STATE_SAT] == 127
|
||||||
|
|
||||||
|
# update light state through api
|
||||||
|
await perform_put_light_state(
|
||||||
|
hass_hue,
|
||||||
|
hue_client,
|
||||||
|
"light.ceiling_lights",
|
||||||
|
True,
|
||||||
|
brightness=100,
|
||||||
|
xy=((0.488, 0.48)),
|
||||||
|
)
|
||||||
|
|
||||||
|
# go through api to get the state back
|
||||||
|
ceiling_json = await perform_get_light_state(
|
||||||
|
hue_client, "light.ceiling_lights", HTTP_OK
|
||||||
|
)
|
||||||
|
assert ceiling_json["state"][HUE_API_STATE_BRI] == 100
|
||||||
|
assert hass.states.get("light.ceiling_lights").attributes[light.ATTR_XY_COLOR] == (
|
||||||
|
(0.488, 0.48)
|
||||||
|
)
|
||||||
|
|
||||||
# Go through the API to turn it off
|
# Go through the API to turn it off
|
||||||
ceiling_result = await perform_put_light_state(
|
ceiling_result = await perform_put_light_state(
|
||||||
hass_hue, hue_client, "light.ceiling_lights", False
|
hass_hue, hue_client, "light.ceiling_lights", False
|
||||||
@ -714,6 +740,30 @@ async def test_put_light_state(hass, hass_hue, hue_client):
|
|||||||
== 50
|
== 50
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# mock light.turn_on call
|
||||||
|
hass.states.async_set(
|
||||||
|
"light.ceiling_lights", STATE_ON, {ATTR_SUPPORTED_FEATURES: 55}
|
||||||
|
)
|
||||||
|
call_turn_on = async_mock_service(hass, "light", "turn_on")
|
||||||
|
|
||||||
|
# update light state through api
|
||||||
|
await perform_put_light_state(
|
||||||
|
hass_hue,
|
||||||
|
hue_client,
|
||||||
|
"light.ceiling_lights",
|
||||||
|
True,
|
||||||
|
brightness=99,
|
||||||
|
xy=((0.488, 0.48)),
|
||||||
|
transitiontime=60,
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert call_turn_on[0]
|
||||||
|
assert call_turn_on[0].data[ATTR_ENTITY_ID] == ["light.ceiling_lights"]
|
||||||
|
assert call_turn_on[0].data[light.ATTR_BRIGHTNESS] == 99
|
||||||
|
assert call_turn_on[0].data[light.ATTR_XY_COLOR] == ((0.488, 0.48))
|
||||||
|
assert call_turn_on[0].data[light.ATTR_TRANSITION] == 6
|
||||||
|
|
||||||
|
|
||||||
async def test_put_light_state_script(hass, hass_hue, hue_client):
|
async def test_put_light_state_script(hass, hass_hue, hue_client):
|
||||||
"""Test the setting of script variables."""
|
"""Test the setting of script variables."""
|
||||||
@ -1173,6 +1223,8 @@ async def perform_put_light_state(
|
|||||||
saturation=None,
|
saturation=None,
|
||||||
color_temp=None,
|
color_temp=None,
|
||||||
with_state=True,
|
with_state=True,
|
||||||
|
xy=None,
|
||||||
|
transitiontime=None,
|
||||||
):
|
):
|
||||||
"""Test the setting of a light state."""
|
"""Test the setting of a light state."""
|
||||||
req_headers = {"Content-Type": content_type}
|
req_headers = {"Content-Type": content_type}
|
||||||
@ -1188,8 +1240,12 @@ async def perform_put_light_state(
|
|||||||
data[HUE_API_STATE_HUE] = hue
|
data[HUE_API_STATE_HUE] = hue
|
||||||
if saturation is not None:
|
if saturation is not None:
|
||||||
data[HUE_API_STATE_SAT] = saturation
|
data[HUE_API_STATE_SAT] = saturation
|
||||||
|
if xy is not None:
|
||||||
|
data[HUE_API_STATE_XY] = xy
|
||||||
if color_temp is not None:
|
if color_temp is not None:
|
||||||
data[HUE_API_STATE_CT] = color_temp
|
data[HUE_API_STATE_CT] = color_temp
|
||||||
|
if transitiontime is not None:
|
||||||
|
data[HUE_API_STATE_TRANSITION] = transitiontime
|
||||||
|
|
||||||
entity_number = ENTITY_NUMBERS_BY_ID[entity_id]
|
entity_number = ENTITY_NUMBERS_BY_ID[entity_id]
|
||||||
result = await client.put(
|
result = await client.put(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user