From b18f1ac265460c83da1c394d519143aefbfea12d Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 18 Apr 2024 09:45:06 -0500 Subject: [PATCH] Migrate device_sun_light_trigger to use async_track_state_change_event (#115555) * Migrate device_sun_light_trigger to use async_track_state_change_event async_track_state_change is legacy and will eventually be deprecated after all core usage is removed. There are only two places left * coverage --- .../device_sun_light_trigger/__init__.py | 31 ++++++++++++------- .../device_sun_light_trigger/test_init.py | 17 ++++++++-- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/device_sun_light_trigger/__init__.py b/homeassistant/components/device_sun_light_trigger/__init__.py index 861a634eda7..6781b9afaf7 100644 --- a/homeassistant/components/device_sun_light_trigger/__init__.py +++ b/homeassistant/components/device_sun_light_trigger/__init__.py @@ -1,6 +1,7 @@ """Support to turn on lights based on the states.""" from datetime import timedelta +from functools import partial import logging import voluptuous as vol @@ -27,11 +28,11 @@ from homeassistant.const import ( SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET, ) -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback import homeassistant.helpers.config_validation as cv from homeassistant.helpers.event import ( async_track_point_in_utc_time, - async_track_state_change, + async_track_state_change_event, ) from homeassistant.helpers.sun import get_astral_event_next, is_up from homeassistant.helpers.typing import ConfigType @@ -195,8 +196,20 @@ async def activate_automation( # noqa: C901 schedule_light_turn_on(None) @callback - def check_light_on_dev_state_change(entity, old_state, new_state): + def check_light_on_dev_state_change( + from_state: str, to_state: str, event: Event[EventStateChangedData] + ) -> None: """Handle tracked device state changes.""" + event_data = event.data + if ( + (old_state := event_data["old_state"]) is None + or (new_state := event_data["new_state"]) is None + or old_state.state != from_state + or new_state.state != to_state + ): + return + + entity = event_data["entity_id"] lights_are_on = any_light_on() light_needed = not (lights_are_on or is_up(hass)) @@ -237,12 +250,10 @@ async def activate_automation( # noqa: C901 # will all the following then, break. break - async_track_state_change( + async_track_state_change_event( hass, device_entity_ids, - check_light_on_dev_state_change, - STATE_NOT_HOME, - STATE_HOME, + partial(check_light_on_dev_state_change, STATE_NOT_HOME, STATE_HOME), ) if disable_turn_off: @@ -266,12 +277,10 @@ async def activate_automation( # noqa: C901 ) ) - async_track_state_change( + async_track_state_change_event( hass, device_entity_ids, - turn_off_lights_when_all_leave, - STATE_HOME, - STATE_NOT_HOME, + partial(turn_off_lights_when_all_leave, STATE_HOME, STATE_NOT_HOME), ) return diff --git a/tests/components/device_sun_light_trigger/test_init.py b/tests/components/device_sun_light_trigger/test_init.py index b373bd4401f..5f44593aabe 100644 --- a/tests/components/device_sun_light_trigger/test_init.py +++ b/tests/components/device_sun_light_trigger/test_init.py @@ -22,6 +22,7 @@ from homeassistant.const import ( STATE_NOT_HOME, STATE_OFF, STATE_ON, + STATE_UNKNOWN, ) from homeassistant.core import CoreState, HomeAssistant from homeassistant.setup import async_setup_component @@ -150,10 +151,22 @@ async def test_lights_turn_on_when_coming_home_after_sun_set( hass, device_sun_light_trigger.DOMAIN, {device_sun_light_trigger.DOMAIN: {}} ) - hass.states.async_set(f"{DOMAIN}.device_2", STATE_HOME) - + hass.states.async_set(f"{DOMAIN}.device_2", STATE_UNKNOWN) await hass.async_block_till_done() + assert all( + hass.states.get(ent_id).state == STATE_OFF + for ent_id in hass.states.async_entity_ids("light") + ) + hass.states.async_set(f"{DOMAIN}.device_2", STATE_NOT_HOME) + await hass.async_block_till_done() + assert all( + hass.states.get(ent_id).state == STATE_OFF + for ent_id in hass.states.async_entity_ids("light") + ) + + hass.states.async_set(f"{DOMAIN}.device_2", STATE_HOME) + await hass.async_block_till_done() assert all( hass.states.get(ent_id).state == light.STATE_ON for ent_id in hass.states.async_entity_ids("light")