mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-12 23:04:03 +02:00
fix turning on and off, delay setup listeners until HA start
This commit is contained in:
parent
d18b2a9da6
commit
ee71742646
1 changed files with 46 additions and 36 deletions
|
|
@ -38,7 +38,7 @@ from homeassistant.const import (
|
|||
SUN_EVENT_SUNRISE,
|
||||
SUN_EVENT_SUNSET,
|
||||
)
|
||||
from homeassistant.core import Event
|
||||
from homeassistant.core import Context, Event
|
||||
from homeassistant.helpers import entity_platform
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.event import (
|
||||
|
|
@ -208,6 +208,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
# Set other attributes
|
||||
self._icon = ICON
|
||||
self._entity_id = f"switch.{DOMAIN}_{slugify(self._name)}"
|
||||
self._state = None
|
||||
|
||||
# Tracks 'off' → 'on' state changes
|
||||
self._on_to_off_event: Dict[str, Event] = {}
|
||||
|
|
@ -249,7 +250,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
@property
|
||||
def is_on(self):
|
||||
"""Return true if adaptive lighting is on."""
|
||||
return bool(self.unsub_trackers)
|
||||
return self._state
|
||||
|
||||
def _supported_features(self, light):
|
||||
state = self.hass.states.get(light)
|
||||
|
|
@ -269,50 +270,56 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
)
|
||||
last_state = await self.async_get_last_state()
|
||||
if last_state and last_state.state == STATE_ON:
|
||||
await self.async_turn_on(adjust_lights=False, setup_listeners=False)
|
||||
self._state = True
|
||||
await self.async_turn_on(
|
||||
adjust_lights=not self._only_once,
|
||||
setup_listeners=False,
|
||||
)
|
||||
else:
|
||||
self._state = False
|
||||
|
||||
def _unpack_light_groups(self) -> None:
|
||||
all_lights = []
|
||||
all_lights = set()
|
||||
for light in self._lights:
|
||||
state = self.hass.states.get(light)
|
||||
if state is None:
|
||||
_LOGGER.debug("%s: State of %s is None", self._name, light)
|
||||
all_lights.append(light)
|
||||
all_lights.add(light)
|
||||
elif "entity_id" in state.attributes: # it's a light group
|
||||
group = state.attributes["entity_id"]
|
||||
all_lights.extend(group)
|
||||
all_lights.update(group)
|
||||
_LOGGER.debug("%s: Unpacked %s to %s", self._name, light, group)
|
||||
else:
|
||||
all_lights.append(light)
|
||||
self._lights = all_lights
|
||||
all_lights.add(light)
|
||||
self.turn_on_off_listener.lights.update(all_lights)
|
||||
self._lights = list(all_lights)
|
||||
|
||||
async def _setup_listeners(self, _=None):
|
||||
if self.unsub_trackers:
|
||||
_LOGGER.error(
|
||||
"%s: Calling '_setup_listeners' when they are already set up", self.name
|
||||
)
|
||||
return
|
||||
|
||||
self._unpack_light_groups()
|
||||
for light in self._lights:
|
||||
self.turn_on_off_listener.lights.add(light)
|
||||
self.unsub_trackers.append(
|
||||
async_track_state_change_event(self.hass, self._lights, self._light_event)
|
||||
rm_interval = async_track_time_interval(
|
||||
self.hass, self._async_update_at_interval, self._interval
|
||||
)
|
||||
rm_state = async_track_state_change_event(
|
||||
self.hass, self._lights, self._light_event
|
||||
)
|
||||
self.unsub_trackers.extend([rm_interval, rm_state])
|
||||
track_kwargs = dict(hass=self.hass, action=self._state_changed)
|
||||
if self._sleep_entity is not None:
|
||||
sleep_kwargs = dict(track_kwargs, entity_ids=self._sleep_entity)
|
||||
self.unsub_trackers.append(
|
||||
async_track_state_change(**sleep_kwargs, to_state=self._sleep_state)
|
||||
)
|
||||
self.unsub_trackers.append(
|
||||
async_track_state_change(**sleep_kwargs, from_state=self._sleep_state)
|
||||
)
|
||||
|
||||
kwgs = dict(track_kwargs, entity_ids=self._sleep_entity)
|
||||
rm_from = async_track_state_change(**kwgs, from_state=self._sleep_state)
|
||||
rm_to = async_track_state_change(**kwgs, to_state=self._sleep_state)
|
||||
self.unsub_trackers.extend([rm_from, rm_to])
|
||||
if self._disable_entity is not None:
|
||||
disable_kwargs = dict(track_kwargs, entity_ids=self._disable_entity)
|
||||
self.unsub_trackers.append(
|
||||
async_track_state_change(
|
||||
**disable_kwargs, from_state=self._disable_state
|
||||
)
|
||||
)
|
||||
self.unsub_trackers.append(
|
||||
async_track_state_change(**disable_kwargs, to_state=self._disable_state)
|
||||
)
|
||||
kwgs = dict(track_kwargs, entity_ids=self._disable_entity)
|
||||
rm_from = async_track_state_change(**kwgs, from_state=self._disable_state)
|
||||
rm_to = async_track_state_change(**kwgs, to_state=self._disable_state)
|
||||
self.unsub_trackers.extend([rm_from, rm_to])
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
|
|
@ -339,11 +346,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
"""Turn on adaptive lighting."""
|
||||
if self.is_on:
|
||||
return
|
||||
self.unsub_trackers.append(
|
||||
async_track_time_interval(
|
||||
self.hass, self._async_update_at_interval, self._interval
|
||||
)
|
||||
)
|
||||
self._state = True
|
||||
if setup_listeners:
|
||||
self._setup_listeners()
|
||||
if adjust_lights:
|
||||
|
|
@ -353,6 +356,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
"""Turn off adaptive lighting."""
|
||||
if not self.is_on:
|
||||
return
|
||||
self._state = False
|
||||
while self.unsub_trackers:
|
||||
unsub = self.unsub_trackers.pop()
|
||||
unsub()
|
||||
|
|
@ -511,8 +515,12 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
self._name,
|
||||
service_data,
|
||||
)
|
||||
|
||||
return self.hass.services.async_call(
|
||||
LIGHT_DOMAIN, SERVICE_TURN_ON, service_data
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
service_data,
|
||||
context=Context(),
|
||||
)
|
||||
|
||||
def _should_adjust(self):
|
||||
|
|
@ -559,7 +567,9 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
_LOGGER.debug(
|
||||
"%s: Detected an 'off' → 'on' event for '%s'", self._name, entity_id
|
||||
)
|
||||
lock = self._locks.setdefault(entity_id, asyncio.Lock())
|
||||
lock = self._locks.get(entity_id)
|
||||
if lock is None:
|
||||
lock = asyncio.Lock()
|
||||
async with lock:
|
||||
if await self.turn_on_off_listener.maybe_cancel_adjusting(
|
||||
entity_id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue