diff --git a/custom_components/adaptive_lighting/const.py b/custom_components/adaptive_lighting/const.py index 5b11e768..3d749503 100644 --- a/custom_components/adaptive_lighting/const.py +++ b/custom_components/adaptive_lighting/const.py @@ -15,6 +15,10 @@ CONF_LIGHTS, DEFAULT_LIGHTS = "lights", [] CONF_ADAPT_BRIGHTNESS, DEFAULT_ADAPT_BRIGHTNESS = "adapt_brightness", True CONF_ADAPT_COLOR_TEMP, DEFAULT_ADAPT_COLOR_TEMP = "adapt_color_temp", True CONF_ADAPT_RGB_COLOR, DEFAULT_ADAPT_RGB_COLOR = "adapt_rgb_color", True +CONF_DETECT_NON_HA_CHANGES, DEFAULT_DETECT_NON_HA_CHANGES = ( + "detect_non_ha_changes", + False, +) CONF_INITIAL_TRANSITION, DEFAULT_INITIAL_TRANSITION = "initial_transition", 1 CONF_INTERVAL, DEFAULT_INTERVAL = "interval", 90 CONF_MAX_BRIGHTNESS, DEFAULT_MAX_BRIGHTNESS = "max_brightness", 100 @@ -29,7 +33,7 @@ CONF_SUNRISE_OFFSET, DEFAULT_SUNRISE_OFFSET = "sunrise_offset", 0 CONF_SUNRISE_TIME = "sunrise_time" CONF_SUNSET_OFFSET, DEFAULT_SUNSET_OFFSET = "sunset_offset", 0 CONF_SUNSET_TIME = "sunset_time" -CONF_TAKE_OVER_CONTROL, DEFAULT_TAKE_OVER_CONTROL = "take_over_control", False +CONF_TAKE_OVER_CONTROL, DEFAULT_TAKE_OVER_CONTROL = "take_over_control", True CONF_TRANSITION, DEFAULT_TRANSITION = "transition", 60 ATTR_TURN_ON_OFF_LISTENER = "turn_on_off_listener" @@ -52,6 +56,7 @@ VALIDATION_TUPLES = [ (CONF_ADAPT_BRIGHTNESS, DEFAULT_ADAPT_BRIGHTNESS, bool), (CONF_ADAPT_COLOR_TEMP, DEFAULT_ADAPT_COLOR_TEMP, bool), (CONF_ADAPT_RGB_COLOR, DEFAULT_ADAPT_RGB_COLOR, bool), + (CONF_DETECT_NON_HA_CHANGES, DEFAULT_DETECT_NON_HA_CHANGES, bool), (CONF_INITIAL_TRANSITION, DEFAULT_INITIAL_TRANSITION, VALID_TRANSITION), (CONF_INTERVAL, DEFAULT_INTERVAL, cv.positive_int), (CONF_MAX_BRIGHTNESS, DEFAULT_MAX_BRIGHTNESS, int_between(1, 100)), diff --git a/custom_components/adaptive_lighting/strings.json b/custom_components/adaptive_lighting/strings.json index f9a82c98..d0ad5ce9 100644 --- a/custom_components/adaptive_lighting/strings.json +++ b/custom_components/adaptive_lighting/strings.json @@ -38,7 +38,8 @@ "sunrise_time": "sunrise_time, in 'HH:MM:SS' format", "sunset_offset": "sunset_offset, in +/- seconds", "sunset_time": "sunset_time, in 'HH:MM:SS' format", - "take_over_control": "take_over_control, (beta feature) if manually adjusting the lights when they are already on", + "take_over_control": "take_over_control, if manually adjusting the lights when they are already on", + "detect_non_ha_changes": "detect_non_ha_changes, detect changes to lights made outside of HA (calls 'homeassistant.update_entity'!)", "transition": "transition, in seconds" } } diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index aec93ff2..6867a59e 100755 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -13,6 +13,10 @@ from typing import Any, Dict, List, Optional, Tuple, Union import astral import voluptuous as vol +from homeassistant.components.homeassistant import ( + DOMAIN as HA_DOMAIN, + SERVICE_UPDATE_ENTITY, +) from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_BRIGHTNESS_PCT, @@ -66,6 +70,7 @@ from .const import ( CONF_ADAPT_BRIGHTNESS, CONF_ADAPT_COLOR_TEMP, CONF_ADAPT_RGB_COLOR, + CONF_DETECT_NON_HA_CHANGES, CONF_INITIAL_TRANSITION, CONF_INTERVAL, CONF_LIGHTS, @@ -240,6 +245,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): self._adapt_brightness = data[CONF_ADAPT_BRIGHTNESS] self._adapt_color_temp = data[CONF_ADAPT_COLOR_TEMP] self._adapt_rgb_color = data[CONF_ADAPT_RGB_COLOR] + self._detect_non_ha_changes = data[CONF_DETECT_NON_HA_CHANGES] self._initial_transition = data[CONF_INITIAL_TRANSITION] self._interval = data[CONF_INTERVAL] self._only_once = data[CONF_ONLY_ONCE] @@ -454,8 +460,9 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): if ( self._take_over_control + and self._detect_non_ha_changes and not force - and self.turn_on_off_listener.significant_change( + and await self.turn_on_off_listener.significant_change( light, self._adapt_brightness, self._adapt_color_temp, @@ -859,7 +866,7 @@ class TurnOnOffListener: ) return manually_controlled - def significant_change( + async def significant_change( self, light, adapt_brightness, adapt_color_temp, adapt_rgb_color, threshold=5 ): """Has the light made a significant change since last update. @@ -873,6 +880,12 @@ class TurnOnOffListener: return False changed = False service_data = self.last_service_data[light] + await self.hass.services.async_call( + HA_DOMAIN, + SERVICE_UPDATE_ENTITY, + {ATTR_ENTITY_ID: light}, + blocking=True, + ) attributes = self.hass.states.get(light).attributes if ( adapt_brightness @@ -913,6 +926,7 @@ class TurnOnOffListener: light, ) changed = True + break if (ATTR_RGB_COLOR in service_data and ATTR_RGB_COLOR not in attributes) or ( ATTR_COLOR_TEMP in service_data and ATTR_COLOR_TEMP not in attributes diff --git a/custom_components/adaptive_lighting/translations/en.json b/custom_components/adaptive_lighting/translations/en.json index f9a82c98..d0ad5ce9 100644 --- a/custom_components/adaptive_lighting/translations/en.json +++ b/custom_components/adaptive_lighting/translations/en.json @@ -38,7 +38,8 @@ "sunrise_time": "sunrise_time, in 'HH:MM:SS' format", "sunset_offset": "sunset_offset, in +/- seconds", "sunset_time": "sunset_time, in 'HH:MM:SS' format", - "take_over_control": "take_over_control, (beta feature) if manually adjusting the lights when they are already on", + "take_over_control": "take_over_control, if manually adjusting the lights when they are already on", + "detect_non_ha_changes": "detect_non_ha_changes, detect changes to lights made outside of HA (calls 'homeassistant.update_entity'!)", "transition": "transition, in seconds" } }