Fix for Hue sending effect None at turn_on command while no effect is active (#125377)

* Fix for Hue sending effect None at turn_on command while no effect is active

* typo

* update tests
pull/125420/head
Marcel van der Veldt 2024-09-06 14:06:46 +02:00 committed by Paulus Schoutsen
parent 61ee3a9412
commit 6c640d2abe
2 changed files with 49 additions and 11 deletions

View File

@ -226,7 +226,11 @@ class HueLight(HueBaseEntity, LightEntity):
flash = kwargs.get(ATTR_FLASH) flash = kwargs.get(ATTR_FLASH)
effect = effect_str = kwargs.get(ATTR_EFFECT) effect = effect_str = kwargs.get(ATTR_EFFECT)
if effect_str in (EFFECT_NONE, EFFECT_NONE.lower()): if effect_str in (EFFECT_NONE, EFFECT_NONE.lower()):
effect = EffectStatus.NO_EFFECT # ignore effect if set to "None" and we have no effect active
# the special effect "None" is only used to stop an active effect
# but sending it while no effect is active can actually result in issues
# https://github.com/home-assistant/core/issues/122165
effect = None if self.effect == EFFECT_NONE else EffectStatus.NO_EFFECT
elif effect_str is not None: elif effect_str is not None:
# work out if we got a regular effect or timed effect # work out if we got a regular effect or timed effect
effect = EffectStatus(effect_str) effect = EffectStatus(effect_str)

View File

@ -175,7 +175,7 @@ async def test_light_turn_on_service(
assert len(mock_bridge_v2.mock_requests) == 6 assert len(mock_bridge_v2.mock_requests) == 6
assert mock_bridge_v2.mock_requests[5]["json"]["color_temperature"]["mirek"] == 500 assert mock_bridge_v2.mock_requests[5]["json"]["color_temperature"]["mirek"] == 500
# test enable effect # test enable an effect
await hass.services.async_call( await hass.services.async_call(
"light", "light",
"turn_on", "turn_on",
@ -184,8 +184,20 @@ async def test_light_turn_on_service(
) )
assert len(mock_bridge_v2.mock_requests) == 7 assert len(mock_bridge_v2.mock_requests) == 7
assert mock_bridge_v2.mock_requests[6]["json"]["effects"]["effect"] == "candle" assert mock_bridge_v2.mock_requests[6]["json"]["effects"]["effect"] == "candle"
# fire event to update effect in HA state
event = {
"id": "3a6710fa-4474-4eba-b533-5e6e72968feb",
"type": "light",
"effects": {"status": "candle"},
}
mock_bridge_v2.api.emit_event("update", event)
await hass.async_block_till_done()
test_light = hass.states.get(test_light_id)
assert test_light is not None
assert test_light.attributes["effect"] == "candle"
# test disable effect # test disable effect
# it should send a request with effect set to "no_effect"
await hass.services.async_call( await hass.services.async_call(
"light", "light",
"turn_on", "turn_on",
@ -194,6 +206,28 @@ async def test_light_turn_on_service(
) )
assert len(mock_bridge_v2.mock_requests) == 8 assert len(mock_bridge_v2.mock_requests) == 8
assert mock_bridge_v2.mock_requests[7]["json"]["effects"]["effect"] == "no_effect" assert mock_bridge_v2.mock_requests[7]["json"]["effects"]["effect"] == "no_effect"
# fire event to update effect in HA state
event = {
"id": "3a6710fa-4474-4eba-b533-5e6e72968feb",
"type": "light",
"effects": {"status": "no_effect"},
}
mock_bridge_v2.api.emit_event("update", event)
await hass.async_block_till_done()
test_light = hass.states.get(test_light_id)
assert test_light is not None
assert test_light.attributes["effect"] == "None"
# test turn on with useless effect
# it should send a effect in the request if the device has no effect active
await hass.services.async_call(
"light",
"turn_on",
{"entity_id": test_light_id, "effect": "None"},
blocking=True,
)
assert len(mock_bridge_v2.mock_requests) == 9
assert "effects" not in mock_bridge_v2.mock_requests[8]["json"]
# test timed effect # test timed effect
await hass.services.async_call( await hass.services.async_call(
@ -202,11 +236,11 @@ async def test_light_turn_on_service(
{"entity_id": test_light_id, "effect": "sunrise", "transition": 6}, {"entity_id": test_light_id, "effect": "sunrise", "transition": 6},
blocking=True, blocking=True,
) )
assert len(mock_bridge_v2.mock_requests) == 9 assert len(mock_bridge_v2.mock_requests) == 10
assert ( assert (
mock_bridge_v2.mock_requests[8]["json"]["timed_effects"]["effect"] == "sunrise" mock_bridge_v2.mock_requests[9]["json"]["timed_effects"]["effect"] == "sunrise"
) )
assert mock_bridge_v2.mock_requests[8]["json"]["timed_effects"]["duration"] == 6000 assert mock_bridge_v2.mock_requests[9]["json"]["timed_effects"]["duration"] == 6000
# test enabling effect should ignore color temperature # test enabling effect should ignore color temperature
await hass.services.async_call( await hass.services.async_call(
@ -215,9 +249,9 @@ async def test_light_turn_on_service(
{"entity_id": test_light_id, "effect": "candle", "color_temp": 500}, {"entity_id": test_light_id, "effect": "candle", "color_temp": 500},
blocking=True, blocking=True,
) )
assert len(mock_bridge_v2.mock_requests) == 10 assert len(mock_bridge_v2.mock_requests) == 11
assert mock_bridge_v2.mock_requests[9]["json"]["effects"]["effect"] == "candle" assert mock_bridge_v2.mock_requests[10]["json"]["effects"]["effect"] == "candle"
assert "color_temperature" not in mock_bridge_v2.mock_requests[9]["json"] assert "color_temperature" not in mock_bridge_v2.mock_requests[10]["json"]
# test enabling effect should ignore xy color # test enabling effect should ignore xy color
await hass.services.async_call( await hass.services.async_call(
@ -226,9 +260,9 @@ async def test_light_turn_on_service(
{"entity_id": test_light_id, "effect": "candle", "xy_color": [0.123, 0.123]}, {"entity_id": test_light_id, "effect": "candle", "xy_color": [0.123, 0.123]},
blocking=True, blocking=True,
) )
assert len(mock_bridge_v2.mock_requests) == 11 assert len(mock_bridge_v2.mock_requests) == 12
assert mock_bridge_v2.mock_requests[10]["json"]["effects"]["effect"] == "candle" assert mock_bridge_v2.mock_requests[11]["json"]["effects"]["effect"] == "candle"
assert "xy_color" not in mock_bridge_v2.mock_requests[9]["json"] assert "xy_color" not in mock_bridge_v2.mock_requests[11]["json"]
async def test_light_turn_off_service( async def test_light_turn_off_service(