mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 17:27:52 +00:00
Philips Hue restore brightness after transition (#101293)
This commit is contained in:
parent
4bf475185e
commit
93a8b60c2b
@ -96,6 +96,8 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
|
||||
self.api: HueBridgeV2 = bridge.api
|
||||
self._attr_supported_features |= LightEntityFeature.FLASH
|
||||
self._attr_supported_features |= LightEntityFeature.TRANSITION
|
||||
self._restore_brightness: float | None = None
|
||||
self._brightness_pct: float = 0
|
||||
# we create a virtual service/device for Hue zones/rooms
|
||||
# so we have a parent for grouped lights and scenes
|
||||
self._attr_device_info = DeviceInfo(
|
||||
@ -153,6 +155,18 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
|
||||
brightness = normalize_hue_brightness(kwargs.get(ATTR_BRIGHTNESS))
|
||||
flash = kwargs.get(ATTR_FLASH)
|
||||
|
||||
if self._restore_brightness and brightness is None:
|
||||
# The Hue bridge sets the brightness to 1% when turning on a bulb
|
||||
# when a transition was used to turn off the bulb.
|
||||
# This issue has been reported on the Hue forum several times:
|
||||
# https://developers.meethue.com/forum/t/brightness-turns-down-to-1-automatically-shortly-after-sending-off-signal-hue-bug/5692
|
||||
# https://developers.meethue.com/forum/t/lights-turn-on-with-lowest-brightness-via-siri-if-turned-off-via-api/6700
|
||||
# https://developers.meethue.com/forum/t/using-transitiontime-with-on-false-resets-bri-to-1/4585
|
||||
# https://developers.meethue.com/forum/t/bri-value-changing-in-switching-lights-on-off/6323
|
||||
# https://developers.meethue.com/forum/t/fade-in-fade-out/6673
|
||||
brightness = self._restore_brightness
|
||||
self._restore_brightness = None
|
||||
|
||||
if flash is not None:
|
||||
await self.async_set_flash(flash)
|
||||
return
|
||||
@ -170,6 +184,8 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the light off."""
|
||||
transition = normalize_hue_transition(kwargs.get(ATTR_TRANSITION))
|
||||
if transition is not None:
|
||||
self._restore_brightness = self._brightness_pct
|
||||
flash = kwargs.get(ATTR_FLASH)
|
||||
|
||||
if flash is not None:
|
||||
@ -244,6 +260,7 @@ class GroupedHueLight(HueBaseEntity, LightEntity):
|
||||
if len(supported_color_modes) == 0:
|
||||
# only add color mode brightness if no color variants
|
||||
supported_color_modes.add(ColorMode.BRIGHTNESS)
|
||||
self._brightness_pct = total_brightness / lights_with_dimming_support
|
||||
self._attr_brightness = round(
|
||||
((total_brightness / lights_with_dimming_support) / 100) * 255
|
||||
)
|
||||
|
@ -94,6 +94,7 @@ class HueLight(HueBaseEntity, LightEntity):
|
||||
self._supported_color_modes.add(ColorMode.BRIGHTNESS)
|
||||
# support transition if brightness control
|
||||
self._attr_supported_features |= LightEntityFeature.TRANSITION
|
||||
self._last_brightness: float | None = None
|
||||
self._color_temp_active: bool = False
|
||||
# get list of supported effects (combine effects and timed_effects)
|
||||
self._attr_effect_list = []
|
||||
@ -209,6 +210,17 @@ class HueLight(HueBaseEntity, LightEntity):
|
||||
xy_color = kwargs.get(ATTR_XY_COLOR)
|
||||
color_temp = normalize_hue_colortemp(kwargs.get(ATTR_COLOR_TEMP))
|
||||
brightness = normalize_hue_brightness(kwargs.get(ATTR_BRIGHTNESS))
|
||||
if self._last_brightness and brightness is None:
|
||||
# The Hue bridge sets the brightness to 1% when turning on a bulb
|
||||
# when a transition was used to turn off the bulb.
|
||||
# This issue has been reported on the Hue forum several times:
|
||||
# https://developers.meethue.com/forum/t/brightness-turns-down-to-1-automatically-shortly-after-sending-off-signal-hue-bug/5692
|
||||
# https://developers.meethue.com/forum/t/lights-turn-on-with-lowest-brightness-via-siri-if-turned-off-via-api/6700
|
||||
# https://developers.meethue.com/forum/t/using-transitiontime-with-on-false-resets-bri-to-1/4585
|
||||
# https://developers.meethue.com/forum/t/bri-value-changing-in-switching-lights-on-off/6323
|
||||
# https://developers.meethue.com/forum/t/fade-in-fade-out/6673
|
||||
brightness = self._last_brightness
|
||||
self._last_brightness = None
|
||||
self._color_temp_active = color_temp is not None
|
||||
flash = kwargs.get(ATTR_FLASH)
|
||||
effect = effect_str = kwargs.get(ATTR_EFFECT)
|
||||
@ -245,6 +257,8 @@ class HueLight(HueBaseEntity, LightEntity):
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the light off."""
|
||||
transition = normalize_hue_transition(kwargs.get(ATTR_TRANSITION))
|
||||
if transition is not None and self.resource.dimming:
|
||||
self._last_brightness = self.resource.dimming.brightness
|
||||
flash = kwargs.get(ATTR_FLASH)
|
||||
|
||||
if flash is not None:
|
||||
|
@ -217,6 +217,7 @@ async def test_light_turn_off_service(
|
||||
|
||||
# verify the light is on before we start
|
||||
assert hass.states.get(test_light_id).state == "on"
|
||||
brightness_pct = hass.states.get(test_light_id).attributes["brightness"] / 255 * 100
|
||||
|
||||
# now call the HA turn_off service
|
||||
await hass.services.async_call(
|
||||
@ -256,6 +257,23 @@ async def test_light_turn_off_service(
|
||||
assert mock_bridge_v2.mock_requests[1]["json"]["on"]["on"] is False
|
||||
assert mock_bridge_v2.mock_requests[1]["json"]["dynamics"]["duration"] == 200
|
||||
|
||||
# test turn_on resets brightness
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": test_light_id},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(mock_bridge_v2.mock_requests) == 3
|
||||
assert mock_bridge_v2.mock_requests[2]["json"]["on"]["on"] is True
|
||||
assert (
|
||||
round(
|
||||
mock_bridge_v2.mock_requests[2]["json"]["dimming"]["brightness"]
|
||||
- brightness_pct
|
||||
)
|
||||
== 0
|
||||
)
|
||||
|
||||
# test again with sending long flash
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
@ -263,8 +281,8 @@ async def test_light_turn_off_service(
|
||||
{"entity_id": test_light_id, "flash": "long"},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(mock_bridge_v2.mock_requests) == 3
|
||||
assert mock_bridge_v2.mock_requests[2]["json"]["alert"]["action"] == "breathe"
|
||||
assert len(mock_bridge_v2.mock_requests) == 4
|
||||
assert mock_bridge_v2.mock_requests[3]["json"]["alert"]["action"] == "breathe"
|
||||
|
||||
# test again with sending short flash
|
||||
await hass.services.async_call(
|
||||
@ -273,8 +291,8 @@ async def test_light_turn_off_service(
|
||||
{"entity_id": test_light_id, "flash": "short"},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(mock_bridge_v2.mock_requests) == 4
|
||||
assert mock_bridge_v2.mock_requests[3]["json"]["identify"]["action"] == "identify"
|
||||
assert len(mock_bridge_v2.mock_requests) == 5
|
||||
assert mock_bridge_v2.mock_requests[4]["json"]["identify"]["action"] == "identify"
|
||||
|
||||
|
||||
async def test_light_added(hass: HomeAssistant, mock_bridge_v2) -> None:
|
||||
@ -481,6 +499,17 @@ async def test_grouped_lights(
|
||||
assert mock_bridge_v2.mock_requests[0]["json"]["on"]["on"] is False
|
||||
assert mock_bridge_v2.mock_requests[0]["json"]["dynamics"]["duration"] == 200
|
||||
|
||||
# Test turn_on resets brightness
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": test_light_id},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(mock_bridge_v2.mock_requests) == 2
|
||||
assert mock_bridge_v2.mock_requests[1]["json"]["on"]["on"] is True
|
||||
assert mock_bridge_v2.mock_requests[1]["json"]["dimming"]["brightness"] == 100
|
||||
|
||||
# Test sending short flash effect to a grouped light
|
||||
mock_bridge_v2.mock_requests.clear()
|
||||
test_light_id = "light.test_zone"
|
||||
|
Loading…
x
Reference in New Issue
Block a user