test: cover repeated bare turn-on after physical dim

This commit is contained in:
Bas Nijholt 2026-09-06 13:31:41 -07:00
commit 1be265c722

View file

@ -5099,7 +5099,28 @@ async def test_adapt_only_on_bare_turn_on_respects_pause_changed_mode(hass, inte
)
async def test_detect_non_ha_changes_with_separate_turn_on_commands(hass):
@pytest.mark.parametrize(
("repeat_bare_turn_on", "mode", "intercept", "expected_color_temp"),
[
(False, TakeOverControlMode.PAUSE_ALL, False, 3000),
(False, TakeOverControlMode.PAUSE_CHANGED, False, 4000),
(True, TakeOverControlMode.PAUSE_ALL, True, 3000),
(True, TakeOverControlMode.PAUSE_CHANGED, True, 4000),
],
ids=[
"direct-pause-all-reactive",
"direct-pause-changed-reactive",
"bare-turn-on-pause-all-intercept",
"bare-turn-on-pause-changed-intercept",
],
)
async def test_detect_non_ha_changes_with_separate_turn_on_commands(
hass,
repeat_bare_turn_on,
mode,
intercept,
expected_color_temp,
):
"""Regression test for detect_non_ha_changes with separate_turn_on_commands.
With separate_turn_on_commands=True, each adaptation cycle makes two sequential
@ -5107,6 +5128,9 @@ async def test_detect_non_ha_changes_with_separate_turn_on_commands(hass):
last_service_data instead of merging, brightness is dropped and
_attributes_have_changed silently skips the brightness comparison, so a direct
Zigbee brightness change is never detected as manual control.
A repeated bare light.turn_on from an automation must not hide the physical
change before the periodic adaptation path runs.
"""
switch, (light, *_) = await setup_lights_and_switch(
hass,
@ -5114,10 +5138,21 @@ async def test_detect_non_ha_changes_with_separate_turn_on_commands(hass):
CONF_SEPARATE_TURN_ON_COMMANDS: True,
CONF_DETECT_NON_HA_CHANGES: True,
CONF_TAKE_OVER_CONTROL: True,
CONF_TAKE_OVER_CONTROL_MODE: mode,
CONF_INTERCEPT: intercept,
},
)
context = switch.create_context("test")
_mock_sun_light_settings(
switch,
{
ATTR_BRIGHTNESS_PCT: 50,
ATTR_COLOR_TEMP_KELVIN: 3000,
"force_rgb_color": False,
},
)
context = switch.create_context("interval")
async def update(force: bool = False):
await switch._update_attrs_and_maybe_adapt_lights(
@ -5129,15 +5164,6 @@ async def test_detect_non_ha_changes_with_separate_turn_on_commands(hass):
await update(force=True)
last_sd = switch.manager.last_service_data.get(ENTITY_LIGHT_1)
assert last_sd is not None, "last_service_data not set after force adapt"
assert (
ATTR_BRIGHTNESS in last_sd
), f"brightness missing from last_service_data after split calls: {last_sd}"
assert (
ATTR_COLOR_TEMP_KELVIN in last_sd or ATTR_RGB_COLOR in last_sd
), f"color missing from last_service_data after split calls: {last_sd}"
al_brightness = light.brightness
assert al_brightness is not None
switch.manager.manual_control[ENTITY_LIGHT_1] = LightControlAttributes.NONE
@ -5147,6 +5173,24 @@ async def test_detect_non_ha_changes_with_separate_turn_on_commands(hass):
)
set_light_brightness(light, manual_brightness)
if repeat_bare_turn_on:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: light.entity_id},
blocking=True,
)
await hass.async_block_till_done()
_mock_sun_light_settings(
switch,
{
ATTR_BRIGHTNESS_PCT: 50,
ATTR_COLOR_TEMP_KELVIN: 4000,
"force_rgb_color": False,
},
)
async def _flush_attr_state(hass, entity_id):
"""Mimic a ZHA attribute report: write current hardware state to HA."""
light.async_write_ha_state()
@ -5156,20 +5200,12 @@ async def test_detect_non_ha_changes_with_separate_turn_on_commands(hass):
new=AsyncMock(side_effect=_flush_attr_state),
):
await update(force=False)
assert LightControlAttributes.BRIGHTNESS in switch.manager.manual_control.get(
ENTITY_LIGHT_1,
LightControlAttributes.NONE,
), (
f"manual_control={switch.manager.manual_control.get(ENTITY_LIGHT_1)}, "
f"last_service_data={switch.manager.last_service_data.get(ENTITY_LIGHT_1)}"
)
await update(force=False)
assert (
light.brightness == manual_brightness
), f"AL overrode manual brightness {manual_brightness} with {al_brightness}"
), f"AL overrode manual brightness {manual_brightness} with {light.brightness}"
assert light.color_temp_kelvin == expected_color_temp
async def test_fresh_install_entity_ids(hass):