Compare commits

...

42 commits

Author SHA1 Message Date
Benjamin Auquite
317ae3af13 remove bad merge conflict 2023-04-08 20:08:35 -05:00
Benjamin Auquite
96a28072f6 Update switch.py 2023-04-08 18:59:39 -05:00
Benjamin Auquite
b9273d2d06 Revert "Revert "cleaned up""
This reverts commit 11b268148b.
2023-04-08 13:26:39 -05:00
Bas Nijholt
29eecc4698
Possible refactor of _update_attrs_and_maybe_adapt_lights (#537)
Co-authored-by: Benjamin Auquite <halomastar@gmail.com>
2023-04-08 13:22:10 -05:00
Benjamin Auquite
b36b17ac03 update from reformat_adapt_lights 2023-04-08 13:19:30 -05:00
Benjamin Auquite
11b268148b Revert "cleaned up"
This reverts commit 441cb1ff5c.
2023-04-08 13:11:54 -05:00
Benjamin Auquite
441cb1ff5c cleaned up 2023-04-08 13:06:28 -05:00
Benjamin Auquite
8afd13e8f4
Merge branch 'main' into reformat_adapt_lights 2023-04-08 05:40:13 -05:00
Benjamin Auquite
331f485ef9 update from main 2023-04-08 01:13:19 -05:00
Benjamin Auquite
99473406ea
Merge branch 'main' into reformat_adapt_lights 2023-04-04 13:56:38 -05:00
Bas Nijholt
8285564015 Possible refactor of _update_attrs_and_maybe_adapt_lights 2023-04-03 23:43:09 -07:00
Benjamin Auquite
20854f1dc0 Update switch.py 2023-04-03 20:09:43 -05:00
Benjamin Auquite
c3c0eaac2e Update switch.py 2023-04-03 20:07:36 -05:00
Benjamin Auquite
5da2c85fea Merge branch 'reformat_adapt_lights' of https://github.com/basnijholt/adaptive-lighting into reformat_adapt_lights 2023-04-03 20:05:03 -05:00
Benjamin Auquite
21f8beac8d slight refactor 2023-04-03 20:04:53 -05:00
github-actions[bot]
9c8d322135 Update README.md, strings.json, and services.yaml 2023-04-04 00:59:20 +00:00
Benjamin Auquite
4b605706ef
Merge 46d5563697 into 981287edb9 2023-04-04 00:57:48 +00:00
Benjamin Auquite
46d5563697 merge upstream\main 2023-04-03 19:57:39 -05:00
Benjamin Auquite
5524c75b42 Update switch.py 2023-04-03 01:52:34 -05:00
Benjamin Auquite
4479761ad7 Update switch.py 2023-04-03 01:50:52 -05:00
Benjamin Auquite
2f0bad82ff Update switch.py 2023-04-03 01:40:29 -05:00
Benjamin Auquite
6b2fbf7c9b Update switch.py 2023-04-03 01:38:28 -05:00
Benjamin Auquite
cebf31a203 Update switch.py 2023-04-03 01:35:53 -05:00
Benjamin Auquite
6e9fb0cc0d not in this pr yet 2023-04-03 01:32:46 -05:00
Benjamin Auquite
f453968258 0.1 sometimes fails the test 2023-04-03 01:04:05 -05:00
Benjamin Auquite
b221eed1a0 Merge branch 'wait_for_transitions' into reformat_adapt_lights 2023-04-03 01:03:03 -05:00
Benjamin Auquite
836595051d Revert "cleanup"
This reverts commit 3aa2f3242b.
2023-04-03 01:02:42 -05:00
Benjamin Auquite
2a4acde1c0 Merge branch 'wait_for_transitions' into reformat_adapt_lights 2023-04-03 00:55:52 -05:00
Benjamin Auquite
3aa2f3242b cleanup 2023-04-03 00:55:21 -05:00
Benjamin Auquite
732fc17c7f merge related fix 2023-04-02 23:56:08 -05:00
Benjamin Auquite
a6641d0daf Update switch.py 2023-04-02 23:51:24 -05:00
Benjamin Auquite
9eb56463ec merge from working wait_for_transitions 2023-04-02 23:48:04 -05:00
Benjamin Auquite
1571dfaeda Update switch.py 2023-04-02 23:46:20 -05:00
Benjamin Auquite
120efff71e update tests 2023-04-02 23:43:30 -05:00
Benjamin Auquite
30c62bf759 Update switch.py 2023-04-02 23:28:58 -05:00
Benjamin Auquite
8e847e71eb not renamed in this branch yet. 2023-04-02 23:15:53 -05:00
Benjamin Auquite
ad04e39d4e Update switch.py 2023-04-02 23:14:04 -05:00
Benjamin Auquite
85eb85cab6 merge wait_for_transition 2023-04-02 23:09:21 -05:00
Benjamin Auquite
22bae9ed84 Update switch.py 2023-04-02 23:08:35 -05:00
Benjamin Auquite
8b2fcf93be cherry-pick wait for transition stuff 2023-04-02 23:04:26 -05:00
Benjamin Auquite
d7aecc9e7f
Merge branch 'main' into wait_for_transitions 2023-04-02 23:01:32 -05:00
Bas Nijholt
52275bfee3 Add auto_reset_manual_control with async timer 2023-03-28 00:19:35 -07:00
3 changed files with 52 additions and 42 deletions

0
custom_components/adaptive_lighting/services.yaml Normal file → Executable file
View file

View file

@ -424,6 +424,7 @@ def _fire_manual_control_event(
switch.entity_id, switch.entity_id,
light, light,
) )
switch.turn_on_off_listener.mark_as_manual_control(light)
fire( fire(
f"{DOMAIN}.manual_control", f"{DOMAIN}.manual_control",
{ATTR_ENTITY_ID: light, SWITCH_DOMAIN: switch.entity_id}, {ATTR_ENTITY_ID: light, SWITCH_DOMAIN: switch.entity_id},
@ -519,7 +520,6 @@ async def async_setup_entry(
all_lights = _expand_light_groups(switch.hass, lights) all_lights = _expand_light_groups(switch.hass, lights)
if service_call.data[CONF_MANUAL_CONTROL]: if service_call.data[CONF_MANUAL_CONTROL]:
for light in all_lights: for light in all_lights:
switch.turn_on_off_listener.mark_as_manual_control(light)
_fire_manual_control_event(switch, light, service_call.context) _fire_manual_control_event(switch, light, service_call.context)
else: else:
switch.turn_on_off_listener.reset(*all_lights) switch.turn_on_off_listener.reset(*all_lights)
@ -1088,9 +1088,6 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
if lock is not None and lock.locked(): if lock is not None and lock.locked():
_LOGGER.debug("%s: '%s' is locked", self._name, light) _LOGGER.debug("%s: '%s' is locked", self._name, light)
return return
service_data = {ATTR_ENTITY_ID: light}
features = _supported_features(self.hass, light)
if transition is None: if transition is None:
transition = self._transition transition = self._transition
if adapt_brightness is None: if adapt_brightness is None:
@ -1100,15 +1097,18 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
if prefer_rgb_color is None: if prefer_rgb_color is None:
prefer_rgb_color = self._prefer_rgb_color prefer_rgb_color = self._prefer_rgb_color
# Check transition == 0 to fix #378
if "transition" in features and transition > 0:
service_data[ATTR_TRANSITION] = transition
# The switch might be off and not have _settings set. # The switch might be off and not have _settings set.
self._settings = self._sun_light_settings.get_settings( self._settings = self._sun_light_settings.get_settings(
self.sleep_mode_switch.is_on, transition self.sleep_mode_switch.is_on, transition
) )
# Build service data.
service_data = {ATTR_ENTITY_ID: light}
features = _supported_features(self.hass, light)
# Check transition == 0 to fix #378
if "transition" in features and transition > 0:
service_data[ATTR_TRANSITION] = transition
if "brightness" in features and adapt_brightness: if "brightness" in features and adapt_brightness:
brightness = round(255 * self._settings["brightness_pct"] / 100) brightness = round(255 * self._settings["brightness_pct"] / 100)
service_data[ATTR_BRIGHTNESS] = brightness service_data[ATTR_BRIGHTNESS] = brightness
@ -1135,19 +1135,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
service_data[ATTR_RGB_COLOR] = self._settings["rgb_color"] service_data[ATTR_RGB_COLOR] = self._settings["rgb_color"]
context = context or self.create_context("adapt_lights") context = context or self.create_context("adapt_lights")
if (
self._take_over_control
and self._detect_non_ha_changes
and not force
and await self.turn_on_off_listener.significant_change(
self,
light,
adapt_brightness,
adapt_color,
context,
)
):
return
# See #80. Doesn't check if transitions differ but it does the job. # See #80. Doesn't check if transitions differ but it does the job.
last_service_data = self.turn_on_off_listener.last_service_data last_service_data = self.turn_on_off_listener.last_service_data
if not force and last_service_data.get(light) == service_data: if not force and last_service_data.get(light) == service_data:
@ -1236,9 +1224,11 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
if not filtered_lights: if not filtered_lights:
return return
await self._adapt_lights(filtered_lights, transition, force, context) await self._update_manual_control_and_maybe_adapt(
filtered_lights, transition, force, context
)
async def _adapt_lights( async def _update_manual_control_and_maybe_adapt(
self, self,
lights: list[str], lights: list[str],
transition: int | None, transition: int | None,
@ -1247,33 +1237,53 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
) -> None: ) -> None:
assert context is not None assert context is not None
_LOGGER.debug( _LOGGER.debug(
"%s: '_adapt_lights(%s, %s, force=%s, context.id=%s)' called", "%s: '_update_manual_control_and_maybe_adapt(%s, %s, force=%s, context.id=%s)' called",
self.name, self.name,
lights, lights,
transition, transition,
force, force,
context.id, context.id,
) )
adapt_brightness = self.adapt_brightness_switch.is_on
adapt_color = self.adapt_color_switch.is_on
for light in lights: for light in lights:
if not is_on(self.hass, light): if not is_on(self.hass, light):
continue continue
if (
self._take_over_control manually_controlled = self.turn_on_off_listener.is_manually_controlled(
and self.turn_on_off_listener.is_manually_controlled( self,
light,
force,
adapt_brightness,
adapt_color,
)
significant_change = (
self._detect_non_ha_changes
and not force
and await self.turn_on_off_listener.significant_change(
self, self,
light, light,
force, adapt_brightness,
self.adapt_brightness_switch.is_on, adapt_color,
self.adapt_color_switch.is_on, context,
)
):
_LOGGER.debug(
"%s: '%s' is being manually controlled, stop adapting, context.id=%s.",
self._name,
light,
context.id,
) )
)
if self._take_over_control and (manually_controlled or significant_change):
if manually_controlled:
_LOGGER.debug(
"%s: '%s' is being manually controlled, stop adapting, context.id=%s.",
self._name,
light,
context.id,
)
else:
_fire_manual_control_event(self, light, context)
continue continue
await self._adapt_light(light, transition, force=force, context=context) await self._adapt_light(light, transition, force=force, context=context)
async def _sleep_mode_switch_state_event(self, event: Event) -> None: async def _sleep_mode_switch_state_event(self, event: Event) -> None:
@ -1900,7 +1910,7 @@ class TurnOnOffListener:
): ):
# Light was already on and 'light.turn_on' was not called by # Light was already on and 'light.turn_on' was not called by
# the adaptive_lighting integration. # the adaptive_lighting integration.
manual_control = self.mark_as_manual_control(light) manual_control = True
_fire_manual_control_event(switch, light, turn_on_event.context) _fire_manual_control_event(switch, light, turn_on_event.context)
_LOGGER.debug( _LOGGER.debug(
"'%s' was already on and 'light.turn_on' was not called by the" "'%s' was already on and 'light.turn_on' was not called by the"
@ -1968,8 +1978,6 @@ class TurnOnOffListener:
light, light,
context.id, context.id,
) )
self.mark_as_manual_control(light)
_fire_manual_control_event(switch, light, context, is_async=False)
return True return True
_LOGGER.debug( _LOGGER.debug(
"%s: Light '%s' correctly matches our last adapt's service data, continuing..." "%s: Light '%s' correctly matches our last adapt's service data, continuing..."

View file

@ -22,6 +22,7 @@ from homeassistant.components.adaptive_lighting.const import (
CONF_SUNRISE_OFFSET, CONF_SUNRISE_OFFSET,
CONF_SUNRISE_TIME, CONF_SUNRISE_TIME,
CONF_SUNSET_TIME, CONF_SUNSET_TIME,
CONF_TAKE_OVER_CONTROL,
CONF_TRANSITION, CONF_TRANSITION,
CONF_TURN_ON_LIGHTS, CONF_TURN_ON_LIGHTS,
CONF_USE_DEFAULTS, CONF_USE_DEFAULTS,
@ -212,7 +213,8 @@ async def setup_lights_and_switch(hass, extra_conf=None):
CONF_SUNSET_TIME: datetime.time(SUNSET.hour), CONF_SUNSET_TIME: datetime.time(SUNSET.hour),
CONF_INITIAL_TRANSITION: 0, CONF_INITIAL_TRANSITION: 0,
CONF_TRANSITION: 0, CONF_TRANSITION: 0,
CONF_DETECT_NON_HA_CHANGES: True, CONF_DETECT_NON_HA_CHANGES: False,
CONF_TAKE_OVER_CONTROL: True,
CONF_PREFER_RGB_COLOR: False, CONF_PREFER_RGB_COLOR: False,
CONF_MIN_COLOR_TEMP: 2500, # to not coincide with sleep_color_temp CONF_MIN_COLOR_TEMP: 2500, # to not coincide with sleep_color_temp
**(extra_conf or {}), **(extra_conf or {}),
@ -666,7 +668,7 @@ async def test_manual_control(hass):
@pytest.mark.dependency(depends=[*GLOBAL_TEST_DEPENDENCIES, "test_manual_control"]) @pytest.mark.dependency(depends=[*GLOBAL_TEST_DEPENDENCIES, "test_manual_control"])
async def test_auto_reset_manual_control(hass): async def test_auto_reset_manual_control(hass):
switch, (light, *_) = await setup_lights_and_switch( switch, (light, *_) = await setup_lights_and_switch(
hass, {CONF_AUTORESET_CONTROL: 0.1} hass, {CONF_AUTORESET_CONTROL: 0.2}
) )
context = switch.create_context("test") # needs to be passed to update method context = switch.create_context("test") # needs to be passed to update method
manual_control = switch.turn_on_off_listener.manual_control manual_control = switch.turn_on_off_listener.manual_control