diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index 2c2754fb..a31d556e 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -20,7 +20,7 @@ jobs: - name: Install Home Assistant uses: ./.github/workflows/install_dependencies with: - python-version: "3.10" + python-version: "3.11" - name: Install markdown-code-runner and README code dependencies run: | diff --git a/custom_components/adaptive_lighting/__init__.py b/custom_components/adaptive_lighting/__init__.py index f985e8c5..c4187fa7 100755 --- a/custom_components/adaptive_lighting/__init__.py +++ b/custom_components/adaptive_lighting/__init__.py @@ -10,7 +10,7 @@ import voluptuous as vol from .const import ( _DOMAIN_SCHEMA, - ATTR_TURN_ON_OFF_LISTENER, + ATTR_ADAPTIVE_LIGHTING_MANAGER, CONF_NAME, DOMAIN, UNDO_UPDATE_LISTENER, @@ -86,10 +86,10 @@ async def async_unload_entry(hass, config_entry: ConfigEntry) -> bool: if unload_ok: data.pop(config_entry.entry_id) - if len(data) == 1 and ATTR_TURN_ON_OFF_LISTENER in data: + if len(data) == 1 and ATTR_ADAPTIVE_LIGHTING_MANAGER in data: # no more config_entries - turn_on_off_listener = data.pop(ATTR_TURN_ON_OFF_LISTENER) - turn_on_off_listener.disable() + manager = data.pop(ATTR_ADAPTIVE_LIGHTING_MANAGER) + manager.disable() if not data: hass.data.pop(DOMAIN) diff --git a/custom_components/adaptive_lighting/const.py b/custom_components/adaptive_lighting/const.py index 241689fc..15ce097b 100644 --- a/custom_components/adaptive_lighting/const.py +++ b/custom_components/adaptive_lighting/const.py @@ -190,7 +190,7 @@ DOCS[CONF_SKIP_REDUNDANT_COMMANDS] = ( SLEEP_MODE_SWITCH = "sleep_mode_switch" ADAPT_COLOR_SWITCH = "adapt_color_switch" ADAPT_BRIGHTNESS_SWITCH = "adapt_brightness_switch" -ATTR_TURN_ON_OFF_LISTENER = "turn_on_off_listener" +ATTR_ADAPTIVE_LIGHTING_MANAGER = "manager" UNDO_UPDATE_LISTENER = "undo_update_listener" NONE_STR = "None" ATTR_ADAPT_COLOR = "adapt_color" diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index fbf6c79c..7deddcd8 100644 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -102,7 +102,7 @@ from .const import ( ADAPT_COLOR_SWITCH, ATTR_ADAPT_BRIGHTNESS, ATTR_ADAPT_COLOR, - ATTR_TURN_ON_OFF_LISTENER, + ATTR_ADAPTIVE_LIGHTING_MANAGER, CONF_ADAPT_DELAY, CONF_ADAPT_UNTIL_SLEEP, CONF_AUTORESET_CONTROL, @@ -390,7 +390,7 @@ async def handle_change_switch_settings( ) all_lights = switch.lights # pylint: disable=protected-access - switch.turn_on_off_listener.reset(*all_lights, reset_manual_control=False) + switch.manager.reset(*all_lights, reset_manual_control=False) if switch.is_on: await switch._update_attrs_and_maybe_adapt_lights( # pylint: disable=protected-access all_lights, @@ -412,7 +412,7 @@ def _fire_manual_control_event( switch.entity_id, light, ) - switch.turn_on_off_listener.mark_as_manual_control(light) + switch.manager.mark_as_manual_control(light) fire( f"{DOMAIN}.manual_control", {ATTR_ENTITY_ID: light, SWITCH_DOMAIN: switch.entity_id}, @@ -427,9 +427,11 @@ async def async_setup_entry( data = hass.data[DOMAIN] assert config_entry.entry_id in data - if ATTR_TURN_ON_OFF_LISTENER not in data: - data[ATTR_TURN_ON_OFF_LISTENER] = TurnOnOffListener(hass, config_entry) - turn_on_off_listener: TurnOnOffListener = data[ATTR_TURN_ON_OFF_LISTENER] + if ATTR_ADAPTIVE_LIGHTING_MANAGER not in data: + data[ATTR_ADAPTIVE_LIGHTING_MANAGER] = AdaptiveLightingManager( + hass, config_entry + ) + manager: AdaptiveLightingManager = data[ATTR_ADAPTIVE_LIGHTING_MANAGER] sleep_mode_switch = SimpleSwitch( "Sleep Mode", False, hass, config_entry, ICON_SLEEP ) @@ -442,7 +444,7 @@ async def async_setup_entry( switch = AdaptiveSwitch( hass, config_entry, - turn_on_off_listener, + manager, sleep_mode_switch, adapt_color_switch, adapt_brightness_switch, @@ -476,7 +478,7 @@ async def async_setup_entry( all_lights = switch.lights else: all_lights = _expand_light_groups(switch.hass, lights) - switch.turn_on_off_listener.lights.update(all_lights) + switch.manager.lights.update(all_lights) for light in all_lights: if data[CONF_TURN_ON_LIGHTS] or is_on(hass, light): await switch._adapt_light( # pylint: disable=protected-access @@ -509,7 +511,7 @@ async def async_setup_entry( for light in all_lights: _fire_manual_control_event(switch, light, service_call.context) else: - switch.turn_on_off_listener.reset(*all_lights) + switch.manager.reset(*all_lights) if switch.is_on: # pylint: disable=protected-access await switch._update_attrs_and_maybe_adapt_lights( @@ -594,7 +596,7 @@ def match_switch_state_event(event: Event, from_or_to_state: list[str]): def _expand_light_groups(hass: HomeAssistant, lights: list[str]) -> list[str]: all_lights = set() - turn_on_off_listener = hass.data[DOMAIN][ATTR_TURN_ON_OFF_LISTENER] + manager = hass.data[DOMAIN][ATTR_ADAPTIVE_LIGHTING_MANAGER] for light in lights: state = hass.states.get(light) if state is None: @@ -602,7 +604,7 @@ def _expand_light_groups(hass: HomeAssistant, lights: list[str]) -> list[str]: all_lights.add(light) elif "entity_id" in state.attributes: # it's a light group group = state.attributes["entity_id"] - turn_on_off_listener.lights.discard(light) + manager.lights.discard(light) all_lights.update(group) _LOGGER.debug("Expanded %s to %s", light, group) else: @@ -773,7 +775,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): self, hass, config_entry: ConfigEntry, - turn_on_off_listener: TurnOnOffListener, + manager: AdaptiveLightingManager, sleep_mode_switch: SimpleSwitch, adapt_color_switch: SimpleSwitch, adapt_brightness_switch: SimpleSwitch, @@ -781,7 +783,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): """Initialize the Adaptive Lighting switch.""" # Set attributes that can't be modified during runtime self.hass = hass - self.turn_on_off_listener = turn_on_off_listener + self.manager = manager self.sleep_mode_switch = sleep_mode_switch self.adapt_color_switch = adapt_color_switch self.adapt_brightness_switch = adapt_brightness_switch @@ -951,8 +953,8 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): def _expand_light_groups(self) -> None: all_lights = _expand_light_groups(self.hass, self.lights) - self.turn_on_off_listener.lights.update(all_lights) - self.turn_on_off_listener.set_auto_reset_manual_control_times( + self.manager.lights.update(all_lights) + self.manager.set_auto_reset_manual_control_times( all_lights, self._auto_reset_manual_control_time ) self.lights = list(all_lights) @@ -1030,12 +1032,10 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): extra_state_attributes[key] = None return extra_state_attributes extra_state_attributes["manual_control"] = [ - light - for light in self.lights - if self.turn_on_off_listener.manual_control.get(light) + light for light in self.lights if self.manager.manual_control.get(light) ] extra_state_attributes.update(self._settings) - timers = self.turn_on_off_listener.auto_reset_manual_control_timers + timers = self.manager.auto_reset_manual_control_timers extra_state_attributes["autoreset_time_remaining"] = { light: time for light in self.lights @@ -1047,16 +1047,6 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): self, which: str = "default", parent: Context | None = None ) -> Context: """Create a context that identifies this Adaptive Lighting instance.""" - # Right now the highest number of each context_id it can create is - # 'adapt_lgt:XXXX:turn_on:*************' - # 'adapt_lgt:XXXX:interval:************' - # 'adapt_lgt:XXXX:adapt_lights:********' - # 'adapt_lgt:XXXX:sleep:***************' - # 'adapt_lgt:XXXX:light_event:*********' - # 'adapt_lgt:XXXX:service:*************' - # The smallest space we have is for adapt_lights, which has - # 8 characters. In base85 encoding, that's enough space to hold values - # up to 2**48 - 1, which should give us plenty of calls before we wrap. context = create_context(self._name, which, self._context_cnt, parent=parent) self._context_cnt += 1 return context @@ -1071,7 +1061,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): if self.is_on: return self._state = True - self.turn_on_off_listener.reset(*self.lights) + self.manager.reset(*self.lights) await self._setup_listeners() if adapt_lights: await self._update_attrs_and_maybe_adapt_lights( @@ -1086,7 +1076,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): return self._state = False self._remove_listeners() - self.turn_on_off_listener.reset(*self.lights) + self.manager.reset(*self.lights) async def _async_update_at_interval(self, now=None) -> None: await self._update_attrs_and_maybe_adapt_lights( @@ -1162,7 +1152,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): context = context or self.create_context("adapt_lights") - self.turn_on_off_listener.last_service_data[light] = service_data + self.manager.last_service_data[light] = service_data return prepare_adaptation_data( self.hass, @@ -1189,7 +1179,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): _LOGGER.debug("%s: '%s' is locked", self._name, light) return - if self.turn_on_off_listener.is_proactively_adapting(context.parent_id): + if self.manager.is_proactively_adapting(context.parent_id): # Skip if adaptation was already executed by the service call interceptor _LOGGER.debug( "%s: Skipping reactive adaptation of %s", self._name, context.parent_id @@ -1252,7 +1242,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): to cancel an ongoing adaptation when a light is turned off. """ # Prevent overlap of multiple adaptation sequences - listener = self.turn_on_off_listener + listener = self.manager listener.cancel_ongoing_adaptation_calls(data.entity_id, which=data.which) _LOGGER.debug( "%s: execute_cancellable_adaptation_calls with data: %s", @@ -1309,7 +1299,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): return for light in lights: # Don't adapt lights that haven't finished prior transitions. - timer = self.turn_on_off_listener.transition_timers.get(light) + timer = self.manager.transition_timers.get(light) if timer is not None and timer.is_running(): _LOGGER.debug( "%s: Light '%s' is still transitioning", @@ -1352,7 +1342,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): if not is_on(self.hass, light): continue - manually_controlled = self.turn_on_off_listener.is_manually_controlled( + manually_controlled = self.manager.is_manually_controlled( self, light, force, @@ -1363,7 +1353,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): significant_change = ( self._detect_non_ha_changes and not force - and await self.turn_on_off_listener.significant_change( + and await self.manager.significant_change( self, light, adapt_brightness, @@ -1393,7 +1383,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): "%s: _sleep_mode_switch_state_event, event: '%s'", self._name, event ) # Reset the manually controlled status when the "sleep mode" changes - self.turn_on_off_listener.reset(*self.lights) + self.manager.reset(*self.lights) await self._update_attrs_and_maybe_adapt_lights( transition=self._sleep_transition, force=True, @@ -1417,13 +1407,10 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): event.context.id, ) - if ( - event.context.parent_id - and not self.turn_on_off_listener.is_proactively_adapting( - event.context.id - ) + if event.context.parent_id and not self.manager.is_proactively_adapting( + event.context.id ): - self.turn_on_off_listener.reset(entity_id, reset_manual_control=False) + self.manager.reset(entity_id, reset_manual_control=False) # Tracks 'off' → 'on' state changes self._off_to_on_event[entity_id] = event @@ -1431,7 +1418,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): if lock is None: lock = self._locks[entity_id] = asyncio.Lock() async with lock: - if await self.turn_on_off_listener.maybe_cancel_adjusting( + if await self.manager.maybe_cancel_adjusting( entity_id, off_to_on_event=event, on_to_off_event=self._on_to_off_event.get(entity_id), @@ -1471,7 +1458,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): ): # Tracks 'off' → 'on' state changes self._on_to_off_event[entity_id] = event - self.turn_on_off_listener.reset(entity_id) + self.manager.reset(entity_id) class SimpleSwitch(SwitchEntity, RestoreEntity): @@ -1737,11 +1724,11 @@ class SunLightSettings: } -class TurnOnOffListener: +class AdaptiveLightingManager: """Track 'light.turn_off' and 'light.turn_on' service calls.""" def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry): - """Initialize the TurnOnOffListener that is shared among all switches.""" + """Initialize the AdaptiveLightingManager that is shared among all switches.""" self.hass = hass data = validate(config_entry) self.lights = set() @@ -2177,7 +2164,7 @@ class TurnOnOffListener: and old_state[0].context.id == new_state.context.id ): _LOGGER.debug( - "TurnOnOffListener: State change event of '%s' is already" + "AdaptiveLightingManager: State change event of '%s' is already" " in 'self.last_state_change' (%s)" " adding this state also", entity_id, @@ -2186,7 +2173,7 @@ class TurnOnOffListener: self.last_state_change[entity_id].append(new_state) else: _LOGGER.debug( - "TurnOnOffListener: New adapt '%s' found for %s", + "AdaptiveLightingManager: New adapt '%s' found for %s", new_state, entity_id, ) diff --git a/tests/test_switch.py b/tests/test_switch.py index 0c42b74d..f356c10a 100644 --- a/tests/test_switch.py +++ b/tests/test_switch.py @@ -55,7 +55,7 @@ from custom_components.adaptive_lighting.adaptation_utils import ( from custom_components.adaptive_lighting.const import ( ADAPT_BRIGHTNESS_SWITCH, ADAPT_COLOR_SWITCH, - ATTR_TURN_ON_OFF_LISTENER, + ATTR_ADAPTIVE_LIGHTING_MANAGER, CONF_AUTORESET_CONTROL, CONF_DETECT_NON_HA_CHANGES, CONF_INITIAL_TRANSITION, @@ -321,7 +321,7 @@ async def test_adaptive_lighting_switches(hass): ENTITY_ADAPT_COLOR_SWITCH, ENTITY_ADAPT_BRIGHTNESS_SWITCH, } - assert ATTR_TURN_ON_OFF_LISTENER in hass.data[DOMAIN] + assert ATTR_ADAPTIVE_LIGHTING_MANAGER in hass.data[DOMAIN] assert entry.entry_id in hass.data[DOMAIN] assert len(hass.data[DOMAIN].keys()) == 2 @@ -446,9 +446,7 @@ async def test_light_settings(hass): assert state.attributes[ATTR_BRIGHTNESS] == round( 255 * switch._settings[ATTR_BRIGHTNESS_PCT] / 100 ) - last_service_data = switch.turn_on_off_listener.last_service_data[ - state.entity_id - ] + last_service_data = switch.manager.last_service_data[state.entity_id] assert state.attributes[ATTR_BRIGHTNESS] == last_service_data[ATTR_BRIGHTNESS] assert ( state.attributes[ATTR_COLOR_TEMP_KELVIN] @@ -483,9 +481,7 @@ async def test_light_settings(hass): return [hass.states.get(light) for light in lights] def assert_expected_color_temp(state): - last_service_data = switch.turn_on_off_listener.last_service_data[ - state.entity_id - ] + last_service_data = switch.manager.last_service_data[state.entity_id] assert ( state.attributes[ATTR_COLOR_TEMP_KELVIN] == last_service_data[ATTR_COLOR_TEMP_KELVIN] @@ -531,7 +527,7 @@ async def test_light_settings(hass): @pytest.mark.dependency(depends=GLOBAL_TEST_DEPENDENCIES) -async def test_turn_on_off_listener_not_tracking_untracked_lights(hass): +async def test_manager_not_tracking_untracked_lights(hass): """Test that lights that are not in a Adaptive Lighting switch aren't tracked.""" switch, _ = await setup_lights_and_switch(hass) light = "light.kitchen_lights" @@ -547,7 +543,7 @@ async def test_turn_on_off_listener_not_tracking_untracked_lights(hass): context=switch.create_context("test") ) await hass.async_block_till_done() - assert light not in switch.turn_on_off_listener.lights + assert light not in switch.manager.lights @pytest.mark.dependency(depends=GLOBAL_TEST_DEPENDENCIES) @@ -555,7 +551,7 @@ async def test_manual_control(hass): """Test the 'manual control' tracking.""" switch, (light, *_) = await setup_lights_and_switch(hass) context = switch.create_context("test") # needs to be passed to update method - manual_control = switch.turn_on_off_listener.manual_control + manual_control = switch.manager.manual_control async def update(): await switch._update_attrs_and_maybe_adapt_lights(transition=0, context=context) @@ -707,7 +703,7 @@ async def test_auto_reset_manual_control(hass): hass, {CONF_AUTORESET_CONTROL: 0.1} ) context = switch.create_context("test") # needs to be passed to update method - manual_control = switch.turn_on_off_listener.manual_control + manual_control = switch.manager.manual_control async def update(): await switch._update_attrs_and_maybe_adapt_lights(transition=0, context=context) @@ -846,7 +842,7 @@ async def test_switch_off_on_off(hass): # Turn light off with transition await turn_light(False, transition=1) - assert not switch.turn_on_off_listener.manual_control[ENTITY_LIGHT] + assert not switch.manager.manual_control[ENTITY_LIGHT] # Set state to on after a second (like happens IRL) await asyncio.sleep(1e-3) hass.states.async_set(ENTITY_LIGHT, STATE_ON) @@ -855,8 +851,8 @@ async def test_switch_off_on_off(hass): hass.states.async_set(ENTITY_LIGHT, STATE_OFF) # Now we test whether the sleep task is there - assert ENTITY_LIGHT in switch.turn_on_off_listener.sleep_tasks - sleep_task = switch.turn_on_off_listener.sleep_tasks[ENTITY_LIGHT] + assert ENTITY_LIGHT in switch.manager.sleep_tasks + sleep_task = switch.manager.sleep_tasks[ENTITY_LIGHT] assert not sleep_task.cancelled() # A 'light.turn_on' event should cancel that task @@ -936,7 +932,7 @@ def test_attributes_have_changed(): @pytest.mark.dependency(depends=GLOBAL_TEST_DEPENDENCIES) async def test_state_change_handlers(hass): """ - Test TurnOnOffListener's EVENT_STATE_CHANGED listener. + Test AdaptiveLightingManager's EVENT_STATE_CHANGED listener. ====================== Sequence of events: 1. Transition from sleep mode to normal. @@ -958,7 +954,7 @@ async def test_state_change_handlers(hass): ENTITY_LIGHT, "on", {ATTR_BRIGHTNESS: val, ATTR_SUPPORTED_FEATURES: 1} ) await hass.async_block_till_done() - # Call code in TurnOnOffListener + # Call code in AdaptiveLightingManager hass.bus.async_fire( EVENT_STATE_CHANGED, { @@ -996,10 +992,10 @@ async def test_state_change_handlers(hass): blocking=True, ) await hass.async_block_till_done() - assert switch.turn_on_off_listener.last_state_change.get(ENTITY_LIGHT) - assert len(switch.turn_on_off_listener.last_state_change[ENTITY_LIGHT]) == 1 - assert not switch.turn_on_off_listener.transition_timers.get(ENTITY_LIGHT) - last_service_data = deepcopy(switch.turn_on_off_listener.last_service_data) + assert switch.manager.last_state_change.get(ENTITY_LIGHT) + assert len(switch.manager.last_state_change[ENTITY_LIGHT]) == 1 + assert not switch.manager.transition_timers.get(ENTITY_LIGHT) + last_service_data = deepcopy(switch.manager.last_service_data) assert last_service_data.get(ENTITY_LIGHT) # 2 Adapt from sleep with a 'transition'. @@ -1008,7 +1004,7 @@ async def test_state_change_handlers(hass): force=False, transition=0, context=context ) await hass.async_block_till_done() - current_service_data = switch.turn_on_off_listener.last_service_data + current_service_data = switch.manager.last_service_data assert current_service_data != last_service_data for light in switch.lights: @@ -1029,7 +1025,7 @@ async def test_state_change_handlers(hass): ), }, ) - assert not switch.turn_on_off_listener.transition_timers.get(light) + assert not switch.manager.transition_timers.get(light) # 2.3 Refire and overwrite the original state_changed event with our 'transition' hass.bus.async_fire( @@ -1048,7 +1044,7 @@ async def test_state_change_handlers(hass): ) await hass.async_block_till_done() # Assert our transition timer was created. - assert switch.turn_on_off_listener.transition_timers.get(light) + assert switch.manager.transition_timers.get(light) # 2.5 Simulate a transition. There's no other way to do this in the demo. events = create_transition_events( light=light, @@ -1057,7 +1053,7 @@ async def test_state_change_handlers(hass): current=current_service_data[light], total_events=total_events, ) - # 3. Fire simulated events for our TurnOnOffListener + # 3. Fire simulated events for our AdaptiveLightingManager for event in events: _LOGGER.debug("Test EVENT_STATE_CHANGED listener") hass.bus.async_fire(EVENT_STATE_CHANGED, event) @@ -1065,7 +1061,7 @@ async def test_state_change_handlers(hass): # On real systems HA fires transition state changes every ~3 seconds. # asyncio.sleep(3) # 4. Assert the transition timer started and everything was filled. - listener = switch.turn_on_off_listener + listener = switch.manager assert listener.last_state_change.get(ENTITY_LIGHT) assert len(listener.last_state_change[ENTITY_LIGHT]) == total_events assert listener.transition_timers.get(ENTITY_LIGHT) @@ -1082,9 +1078,9 @@ async def test_state_change_handlers(hass): assert timer and timer.is_running() last_service_data = deepcopy(current_service_data) await update() - assert not switch.turn_on_off_listener.manual_control[ENTITY_LIGHT] + assert not switch.manager.manual_control[ENTITY_LIGHT] await update() - assert not switch.turn_on_off_listener.manual_control[ENTITY_LIGHT] + assert not switch.manager.manual_control[ENTITY_LIGHT] timer = listener.transition_timers.get(ENTITY_LIGHT) assert timer and timer.is_running() # Ensure the light did not adapt during the transition. @@ -1106,23 +1102,23 @@ async def test_state_change_handlers(hass): await turn_light(True, brightness=40) await turn_light(True, brightness=20) await update(force=False) - assert switch.turn_on_off_listener.manual_control[ENTITY_LIGHT] + assert switch.manager.manual_control[ENTITY_LIGHT] await update(force=True) - assert switch.turn_on_off_listener.manual_control[ENTITY_LIGHT] + assert switch.manager.manual_control[ENTITY_LIGHT] # turn light off then on should reset manual control. await turn_light(False) await turn_light(True) - assert not switch.turn_on_off_listener.manual_control[ENTITY_LIGHT] + assert not switch.manager.manual_control[ENTITY_LIGHT] await turn_light(True, brightness=50) _LOGGER.debug("Test: Brightness set to %s", 50) # On next update ENTITY_LIGHT should be marked as manually controlled await update(force=False) - assert switch.turn_on_off_listener.last_service_data.get(ENTITY_LIGHT) is not None - assert switch.turn_on_off_listener.last_state_change.get(ENTITY_LIGHT) is not None - assert switch.turn_on_off_listener.manual_control[ENTITY_LIGHT] + assert switch.manager.last_service_data.get(ENTITY_LIGHT) is not None + assert switch.manager.last_state_change.get(ENTITY_LIGHT) is not None + assert switch.manager.manual_control[ENTITY_LIGHT] @pytest.mark.dependency( @@ -1275,7 +1271,7 @@ async def test_area(hass): blocking=True, ) await hass.async_block_till_done() - assert light.entity_id in switch.turn_on_off_listener.last_service_data + assert light.entity_id in switch.manager.last_service_data await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, @@ -1285,10 +1281,10 @@ async def test_area(hass): await hass.async_block_till_done() _LOGGER.debug( - "switch.turn_on_off_listener.last_service_data: %s", - switch.turn_on_off_listener.last_service_data, + "switch.manager.last_service_data: %s", + switch.manager.last_service_data, ) - assert light.entity_id not in switch.turn_on_off_listener.last_service_data + assert light.entity_id not in switch.manager.last_service_data @pytest.mark.dependency(depends=GLOBAL_TEST_DEPENDENCIES) @@ -1351,9 +1347,7 @@ async def test_cancellable_service_calls_task(hass): _, switch = await setup_switch(hass, {CONF_SEPARATE_TURN_ON_COMMANDS: True}) context = switch.create_context("test") - assert ( - switch.turn_on_off_listener.adaptation_tasks_color.get(light.entity_id) is None - ) + assert switch.manager.adaptation_tasks_color.get(light.entity_id) is None service_data = { ATTR_BRIGHTNESS: 10, @@ -1370,8 +1364,8 @@ async def test_cancellable_service_calls_task(hass): ) await switch.execute_cancellable_adaptation_calls(adaptation_data) - task = switch.turn_on_off_listener.adaptation_tasks_brightness.get(light.entity_id) - task2 = switch.turn_on_off_listener.adaptation_tasks_color.get(light.entity_id) + task = switch.manager.adaptation_tasks_brightness.get(light.entity_id) + task2 = switch.manager.adaptation_tasks_color.get(light.entity_id) assert task is task2 assert task is not None assert task.done() @@ -1384,9 +1378,9 @@ async def test_service_calls_task_cancellation(hass): entity_id = "test_id" task = asyncio.ensure_future(asyncio.sleep(1)) - switch.turn_on_off_listener.adaptation_tasks_brightness[entity_id] = task + switch.manager.adaptation_tasks_brightness[entity_id] = task - switch.turn_on_off_listener.cancel_ongoing_adaptation_calls(entity_id) + switch.manager.cancel_ongoing_adaptation_calls(entity_id) try: await task @@ -1507,7 +1501,7 @@ async def test_proactive_adaptation_toggle(hass): context=Context(id="test1"), ) - assert switch.turn_on_off_listener.is_proactively_adapting("test1") + assert switch.manager.is_proactively_adapting("test1") # Toggle OFF await hass.services.async_call( @@ -1518,7 +1512,7 @@ async def test_proactive_adaptation_toggle(hass): context=Context(id="test2"), ) - assert not switch.turn_on_off_listener.is_proactively_adapting("test2") + assert not switch.manager.is_proactively_adapting("test2") async def test_proactive_adaptation_transition_override(hass): @@ -1558,7 +1552,7 @@ async def test_proactive_adaptation_transition_override(hass): assert set({ATTR_TRANSITION: 456}.items()).issubset(kwargs.items()) # Cleanup - switch.turn_on_off_listener.cancel_ongoing_adaptation_calls(ENTITY_LIGHT3) + switch.manager.cancel_ongoing_adaptation_calls(ENTITY_LIGHT3) async def test_two_switches_for_single_light(hass):