mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-11 14:24:03 +02:00
Rename TurnOnOffListener to AdaptiveLightingManager (#654)
* Rename TurnOnOffListener to AdaptiveLightingManager * Bump Python version
This commit is contained in:
parent
fee90250ee
commit
69592938db
5 changed files with 85 additions and 104 deletions
2
.github/workflows/update-readme.yml
vendored
2
.github/workflows/update-readme.yml
vendored
|
|
@ -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: |
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue