mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-15 08:14:04 +02:00
merge with alt_detect_method
required for this PR
This commit is contained in:
parent
dced97b5ca
commit
2db675a434
2 changed files with 125 additions and 23 deletions
|
|
@ -33,6 +33,12 @@ DOCS[CONF_DETECT_NON_HA_CHANGES] = (
|
|||
"Requires `take_over_control`. 🕵️"
|
||||
)
|
||||
|
||||
CONF_ALT_DETECT_METHOD, DEFAULT_ALT_DETECT_METHOD = "alt_detect_method", False
|
||||
DOCS[CONF_ALT_DETECT_METHOD] = (
|
||||
"alt_detect_method: When true, will check for any significant changes in the opposite direction"
|
||||
" of where adaptive-lighting tried to adapt last."
|
||||
" This is an alternative to 'detect_non_ha_changes' (default: false)"
|
||||
)
|
||||
CONF_INCLUDE_CONFIG_IN_ATTRIBUTES, DEFAULT_INCLUDE_CONFIG_IN_ATTRIBUTES = (
|
||||
"include_config_in_attributes",
|
||||
False,
|
||||
|
|
@ -262,6 +268,7 @@ VALIDATION_TUPLES = [
|
|||
(CONF_SUNSET_OFFSET, DEFAULT_SUNSET_OFFSET, int),
|
||||
(CONF_ONLY_ONCE, DEFAULT_ONLY_ONCE, bool),
|
||||
(CONF_TAKE_OVER_CONTROL, DEFAULT_TAKE_OVER_CONTROL, bool),
|
||||
(CONF_ALT_DETECT_METHOD, DEFAULT_ALT_DETECT_METHOD, bool),
|
||||
(CONF_DETECT_NON_HA_CHANGES, DEFAULT_DETECT_NON_HA_CHANGES, bool),
|
||||
(CONF_SEPARATE_TURN_ON_COMMANDS, DEFAULT_SEPARATE_TURN_ON_COMMANDS, bool),
|
||||
(CONF_SEND_SPLIT_DELAY, DEFAULT_SEND_SPLIT_DELAY, int_between(0, 10000)),
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ from .const import (
|
|||
ATTR_TURN_ON_OFF_LISTENER,
|
||||
CONF_ADAPT_DELAY,
|
||||
CONF_ADAPT_UNTIL_SLEEP,
|
||||
CONF_ALT_DETECT_METHOD,
|
||||
CONF_AUTORESET_CONTROL,
|
||||
CONF_DETECT_NON_HA_CHANGES,
|
||||
CONF_INCLUDE_CONFIG_IN_ATTRIBUTES,
|
||||
|
|
@ -671,6 +672,15 @@ def color_difference_redmean(
|
|||
return math.sqrt(red_term + green_term + blue_term)
|
||||
|
||||
|
||||
def check_direction_change(last: int, current: int, last_adapt_value: int) -> bool:
|
||||
_LOGGER.debug("compare direction: current value %s to last value %s", current, last)
|
||||
if last_adapt_value < last: # Value adapting down
|
||||
return current > last or current < last_adapt_value
|
||||
elif last_adapt_value > last: # Value adapting up
|
||||
return current < last or current > last_adapt_value
|
||||
return False
|
||||
|
||||
|
||||
# All comparisons should be done with RGB since
|
||||
# converting anything to color temp is inaccurate.
|
||||
def _convert_attributes(attributes: dict[str, Any]) -> dict[str, Any]:
|
||||
|
|
@ -713,6 +723,7 @@ def _attributes_have_changed(
|
|||
adapt_brightness: bool,
|
||||
adapt_color: bool,
|
||||
context: Context,
|
||||
last_adapt_attempt=None,
|
||||
) -> bool:
|
||||
if adapt_color:
|
||||
old_attributes, new_attributes = _add_missing_attributes(
|
||||
|
|
@ -727,15 +738,33 @@ def _attributes_have_changed(
|
|||
last_brightness = old_attributes[ATTR_BRIGHTNESS]
|
||||
current_brightness = new_attributes[ATTR_BRIGHTNESS]
|
||||
if abs(current_brightness - last_brightness) > BRIGHTNESS_CHANGE:
|
||||
_LOGGER.debug(
|
||||
"Brightness of '%s' significantly changed from %s to %s with"
|
||||
" context.id='%s'",
|
||||
light,
|
||||
last_brightness,
|
||||
current_brightness,
|
||||
context.id,
|
||||
)
|
||||
return True
|
||||
if last_adapt_attempt:
|
||||
changed = check_direction_change(
|
||||
last_brightness,
|
||||
current_brightness,
|
||||
last_adapt_attempt[ATTR_BRIGHTNESS],
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"altdetect: Brightness of '%s' changed from %s to %s intended %s with"
|
||||
" context.id='%s' Significant? %s",
|
||||
light,
|
||||
last_brightness,
|
||||
current_brightness,
|
||||
last_adapt_attempt[ATTR_BRIGHTNESS],
|
||||
context.id,
|
||||
changed,
|
||||
)
|
||||
return changed
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"Brightness of '%s' significantly changed from %s to %s with"
|
||||
" context.id='%s'",
|
||||
light,
|
||||
last_brightness,
|
||||
current_brightness,
|
||||
context.id,
|
||||
)
|
||||
return True
|
||||
|
||||
if (
|
||||
adapt_color
|
||||
|
|
@ -745,15 +774,33 @@ def _attributes_have_changed(
|
|||
last_color_temp = old_attributes[ATTR_COLOR_TEMP_KELVIN]
|
||||
current_color_temp = new_attributes[ATTR_COLOR_TEMP_KELVIN]
|
||||
if abs(current_color_temp - last_color_temp) > COLOR_TEMP_CHANGE:
|
||||
_LOGGER.debug(
|
||||
"Color temperature of '%s' significantly changed from %s to %s with"
|
||||
" context.id='%s'",
|
||||
light,
|
||||
last_color_temp,
|
||||
current_color_temp,
|
||||
context.id,
|
||||
)
|
||||
return True
|
||||
if last_adapt_attempt:
|
||||
changed = check_direction_change(
|
||||
last_color_temp,
|
||||
current_color_temp,
|
||||
last_adapt_attempt[ATTR_COLOR_TEMP_KELVIN],
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"altdetect: Color temperature of '%s' changed from %s to %s intended %s with"
|
||||
" context.id='%s' Significant? %s",
|
||||
light,
|
||||
last_color_temp,
|
||||
current_color_temp,
|
||||
last_adapt_attempt[ATTR_COLOR_TEMP_KELVIN],
|
||||
context.id,
|
||||
changed,
|
||||
)
|
||||
return changed
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"Color temperature of '%s' significantly changed from %s to %s with"
|
||||
" context.id='%s'",
|
||||
light,
|
||||
last_color_temp,
|
||||
current_color_temp,
|
||||
context.id,
|
||||
)
|
||||
return True
|
||||
|
||||
if (
|
||||
adapt_color
|
||||
|
|
@ -874,12 +921,18 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
self._adapt_delay = data[CONF_ADAPT_DELAY]
|
||||
self._send_split_delay = data[CONF_SEND_SPLIT_DELAY]
|
||||
self._take_over_control = data[CONF_TAKE_OVER_CONTROL]
|
||||
self._alt_detect_method = data[CONF_ALT_DETECT_METHOD]
|
||||
self._detect_non_ha_changes = data[CONF_DETECT_NON_HA_CHANGES]
|
||||
if not data[CONF_TAKE_OVER_CONTROL] and data[CONF_DETECT_NON_HA_CHANGES]:
|
||||
_LOGGER.warning(
|
||||
"%s: Config mismatch: 'detect_non_ha_changes: true' "
|
||||
"requires 'take_over_control' to be enabled. Adjusting config "
|
||||
"and continuing setup with `take_over_control: true`.",
|
||||
if not data[CONF_TAKE_OVER_CONTROL] and (
|
||||
data[CONF_ALT_DETECT_METHOD] or data[CONF_DETECT_NON_HA_CHANGES]
|
||||
):
|
||||
_LOGGER.warn(
|
||||
"%s: Config mismatch: 'alt_detect_method: true'"
|
||||
" OR 'detect_non_ha_changes: true' are set in config, however required"
|
||||
" variable 'take_over_control' is turned off. Please check your"
|
||||
" configuration to ensure desired functionality. We will now"
|
||||
" enable 'take_over_control' and continue setting up the"
|
||||
" adaptive-lighting integration normally.",
|
||||
self._name,
|
||||
)
|
||||
self._take_over_control = True
|
||||
|
|
@ -1234,6 +1287,8 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
transition: int | None,
|
||||
force: bool,
|
||||
context: Context | None,
|
||||
adapt_brightness: bool | None = None,
|
||||
adapt_color: bool | None = None,
|
||||
) -> None:
|
||||
assert context is not None
|
||||
_LOGGER.debug(
|
||||
|
|
@ -1946,6 +2001,46 @@ class TurnOnOffListener:
|
|||
adapt_color=adapt_color,
|
||||
context=context,
|
||||
)
|
||||
if switch._alt_detect_method:
|
||||
old_states: list[State] = self.last_state_change[light]
|
||||
_LOGGER.debug("Total state changes detected: %s", len(old_states))
|
||||
_LOGGER.debug(
|
||||
"%s: 'alt_detect_method: true', check all state changes made to light %s",
|
||||
switch._name,
|
||||
light,
|
||||
)
|
||||
for index, old_state in enumerate(old_states):
|
||||
# The first entry of old_states should always be the
|
||||
# same as last_service_data[light], and can be ignored.
|
||||
if index <= 1:
|
||||
continue
|
||||
_LOGGER.debug(
|
||||
"%s: checking for a manual change between index %s and %s...",
|
||||
switch._name,
|
||||
index,
|
||||
index - 1,
|
||||
)
|
||||
prior_state = old_states[index - 1]
|
||||
if compare_to(
|
||||
old_attributes=prior_state.attributes,
|
||||
new_attributes=old_state.attributes,
|
||||
last_adapt_attempt=last_service_data,
|
||||
):
|
||||
_LOGGER.info(
|
||||
"Found unexpected state_change event for %s nr. %s (context.id=%s)"
|
||||
" old_state=%s\nprior_state=%s",
|
||||
light,
|
||||
index,
|
||||
context.id,
|
||||
old_state,
|
||||
prior_state,
|
||||
)
|
||||
_LOGGER.info(
|
||||
"We will now set %s as manually controlled. (context.id=%s)",
|
||||
light,
|
||||
context.id,
|
||||
)
|
||||
return True
|
||||
# Update state and check for a manual change not done in HA.
|
||||
# Ensure HASS is correctly updating your light's state with
|
||||
# light.turn_on calls if any problems arise. This
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue