From 36115d4fce1078f349af9ecb99b52893b104a5f9 Mon Sep 17 00:00:00 2001 From: Clayton Nummer Date: Tue, 30 Jul 2019 16:46:28 -0400 Subject: [PATCH 1/8] Check light values before setting them Hopefully this eliminates possible "infinite loop" of adjustment, where the SERVICE_TURN_ON call triggers CL to adjust and so on. --- .../circadian_lighting/switch.py | 56 +++++++++++++------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index 07153680..759eaa91 100644 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -267,7 +267,7 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): if transition == None: transition = self._cl.data['transition'] - brightness = (self._attributes['brightness'] / 100) * 255 if self._attributes['brightness'] is not None else None + brightness = int((self._attributes['brightness'] / 100) * 255) if self._attributes['brightness'] is not None else None for light in lights: """Set color of array of ct light.""" @@ -276,18 +276,23 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): if is_on(self.hass, light): service_data = {ATTR_ENTITY_ID: light} if mired is not None: - service_data[ATTR_COLOR_TEMP] = int(mired) + service_data[ATTR_COLOR_TEMP] = mired if brightness is not None: service_data[ATTR_BRIGHTNESS] = brightness if transition is not None: service_data[ATTR_TRANSITION] = transition - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " CT Adjusted - color_temp: " + str(mired) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) + lightAttrs = self.hass.states.get(light).attributes + if ( (ATTR_COLOR_TEMP in lightAttrs and lightAttrs[ATTR_COLOR_TEMP] == mired) and + (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) ): + _LOGGER.debug(light + " already set to the proper values, not adjusting") + else: + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " CT Adjusted - color_temp: " + str(mired) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) """Set color of array of rgb light.""" if self._lights_rgb is not None and light in self._lights_rgb: - rgb = self.calc_rgb() + rgb = tuple(map(int, self.calc_rgb())) if is_on(self.hass, light): service_data = {ATTR_ENTITY_ID: light} if rgb is not None: @@ -296,25 +301,36 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): service_data[ATTR_BRIGHTNESS] = brightness if transition is not None: service_data[ATTR_TRANSITION] = transition - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " RGB Adjusted - rgb_color: " + str(rgb) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) + lightAttrs = self.hass.states.get(light).attributes + if ( (ATTR_RGB_COLOR in lightAttrs and lightAttrs[ATTR_RGB_COLOR] == rgb) and + (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) ): + _LOGGER.debug(light + " already set to the proper values, not adjusting") + else: + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " RGB Adjusted - rgb_color: " + str(rgb) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) """Set color of array of xy light.""" if self._lights_xy is not None and light in self._lights_xy: - x_val, y_val = self.calc_xy() + xy = self.calc_xy() if is_on(self.hass, light): service_data = {ATTR_ENTITY_ID: light} - if x_val is not None and y_val is not None: - service_data[ATTR_XY_COLOR] = [x_val, y_val] + if xy is not None: + service_data[ATTR_XY_COLOR] = xy if brightness is not None: service_data[ATTR_BRIGHTNESS] = brightness service_data[ATTR_WHITE_VALUE] = brightness if transition is not None: service_data[ATTR_TRANSITION] = transition - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " XY Adjusted - xy_color: [" + str(x_val) + ", " + str(y_val) + "], brightness: " + str(brightness) + ", transition: " + str(transition) + ", white_value: " + str(brightness)) + lightAttrs = self.hass.states.get(light).attributes + if ( (ATTR_XY_COLOR in lightAttrs and lightAttrs[ATTR_XY_COLOR] == xy) and + (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) and + (ATTR_WHITE_VALUE in lightAttrs and lightAttrs[ATTR_WHITE_VALUE] == brightness) ): + _LOGGER.debug(light + " already set to the proper values, not adjusting") + else: + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " XY Adjusted - xy_color: " + str(xy) + ", brightness: " + str(brightness) + ", transition: " + str(transition) + ", white_value: " + str(brightness)) """Set color of array of brightness light.""" if self._lights_brightness is not None and light in self._lights_brightness: @@ -324,9 +340,13 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): service_data[ATTR_BRIGHTNESS] = brightness if transition is not None: service_data[ATTR_TRANSITION] = transition - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " Brightness Adjusted - brightness: " + str(brightness) + ", transition: " + str(transition)) + lightAttrs = self.hass.states.get(light).attributes + if (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness): + _LOGGER.debug(light + " already set to the proper values, not adjusting") + else: + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " Brightness Adjusted - brightness: " + str(brightness) + ", transition: " + str(transition)) def light_state_changed(self, entity_id, from_state, to_state): self.adjust_lights([entity_id], 1) From 40568296ed9e26b5a75caba701145e41292eb257 Mon Sep 17 00:00:00 2001 From: Clayton Nummer Date: Tue, 30 Jul 2019 17:15:46 -0400 Subject: [PATCH 2/8] Slight efficiency tweaks Don't calculate values for every light, and only set service_data if it's going to be used --- .../circadian_lighting/switch.py | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index 759eaa91..8264fc49 100644 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -268,12 +268,19 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): transition = self._cl.data['transition'] brightness = int((self._attributes['brightness'] / 100) * 255) if self._attributes['brightness'] is not None else None + mired = int(self.calc_ct()) if self._lights_ct is not None else None + rgb = tuple(map(int, self.calc_rgb())) if self._lights_rgb is not None else None + xy = self.calc_xy() if self._lights_xy is not None else None for light in lights: - """Set color of array of ct light.""" - if self._lights_ct is not None and light in self._lights_ct: - mired = int(self.calc_ct()) - if is_on(self.hass, light): + """Set color of array of ct light if on.""" + if self._lights_ct is not None and light in self._lights_ct and is_on(self.hass, light): + """Check to see if light is already set properly""" + lightAttrs = self.hass.states.get(light).attributes + if ( (ATTR_COLOR_TEMP in lightAttrs and lightAttrs[ATTR_COLOR_TEMP] == mired) and + (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) ): + _LOGGER.debug(light + " already set to the proper values, not adjusting") + else: service_data = {ATTR_ENTITY_ID: light} if mired is not None: service_data[ATTR_COLOR_TEMP] = mired @@ -281,19 +288,18 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): service_data[ATTR_BRIGHTNESS] = brightness if transition is not None: service_data[ATTR_TRANSITION] = transition - lightAttrs = self.hass.states.get(light).attributes - if ( (ATTR_COLOR_TEMP in lightAttrs and lightAttrs[ATTR_COLOR_TEMP] == mired) and - (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) ): - _LOGGER.debug(light + " already set to the proper values, not adjusting") - else: - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " CT Adjusted - color_temp: " + str(mired) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " CT Adjusted - color_temp: " + str(mired) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) - """Set color of array of rgb light.""" - if self._lights_rgb is not None and light in self._lights_rgb: - rgb = tuple(map(int, self.calc_rgb())) - if is_on(self.hass, light): + """Set color of array of rgb light if on.""" + if self._lights_rgb is not None and light in self._lights_rgb and is_on(self.hass, light): + """Check to see if light is already set properly""" + lightAttrs = self.hass.states.get(light).attributes + if ( (ATTR_RGB_COLOR in lightAttrs and lightAttrs[ATTR_RGB_COLOR] == rgb) and + (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) ): + _LOGGER.debug(light + " already set to the proper values, not adjusting") + else: service_data = {ATTR_ENTITY_ID: light} if rgb is not None: service_data[ATTR_RGB_COLOR] = rgb @@ -301,19 +307,19 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): service_data[ATTR_BRIGHTNESS] = brightness if transition is not None: service_data[ATTR_TRANSITION] = transition - lightAttrs = self.hass.states.get(light).attributes - if ( (ATTR_RGB_COLOR in lightAttrs and lightAttrs[ATTR_RGB_COLOR] == rgb) and - (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) ): - _LOGGER.debug(light + " already set to the proper values, not adjusting") - else: - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " RGB Adjusted - rgb_color: " + str(rgb) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " RGB Adjusted - rgb_color: " + str(rgb) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) - """Set color of array of xy light.""" - if self._lights_xy is not None and light in self._lights_xy: - xy = self.calc_xy() - if is_on(self.hass, light): + """Set color of array of xy light if on.""" + if self._lights_xy is not None and light in self._lights_xy and is_on(self.hass, light): + """Check to see if light is already set properly""" + lightAttrs = self.hass.states.get(light).attributes + if ( (ATTR_XY_COLOR in lightAttrs and lightAttrs[ATTR_XY_COLOR] == xy) and + (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) and + (ATTR_WHITE_VALUE in lightAttrs and lightAttrs[ATTR_WHITE_VALUE] == brightness) ): + _LOGGER.debug(light + " already set to the proper values, not adjusting") + else: service_data = {ATTR_ENTITY_ID: light} if xy is not None: service_data[ATTR_XY_COLOR] = xy @@ -322,31 +328,25 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): service_data[ATTR_WHITE_VALUE] = brightness if transition is not None: service_data[ATTR_TRANSITION] = transition - lightAttrs = self.hass.states.get(light).attributes - if ( (ATTR_XY_COLOR in lightAttrs and lightAttrs[ATTR_XY_COLOR] == xy) and - (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) and - (ATTR_WHITE_VALUE in lightAttrs and lightAttrs[ATTR_WHITE_VALUE] == brightness) ): - _LOGGER.debug(light + " already set to the proper values, not adjusting") - else: - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " XY Adjusted - xy_color: " + str(xy) + ", brightness: " + str(brightness) + ", transition: " + str(transition) + ", white_value: " + str(brightness)) + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " XY Adjusted - xy_color: " + str(xy) + ", brightness: " + str(brightness) + ", transition: " + str(transition) + ", white_value: " + str(brightness)) - """Set color of array of brightness light.""" - if self._lights_brightness is not None and light in self._lights_brightness: - if is_on(self.hass, light): + """Set color of array of brightness light if on.""" + if self._lights_brightness is not None and light in self._lights_brightness and is_on(self.hass, light): + """Check to see if light is already set properly""" + lightAttrs = self.hass.states.get(light).attributes + if (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness): + _LOGGER.debug(light + " already set to the proper values, not adjusting") + else: service_data = {ATTR_ENTITY_ID: light} if brightness is not None: service_data[ATTR_BRIGHTNESS] = brightness if transition is not None: service_data[ATTR_TRANSITION] = transition - lightAttrs = self.hass.states.get(light).attributes - if (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness): - _LOGGER.debug(light + " already set to the proper values, not adjusting") - else: - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " Brightness Adjusted - brightness: " + str(brightness) + ", transition: " + str(transition)) + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " Brightness Adjusted - brightness: " + str(brightness) + ", transition: " + str(transition)) def light_state_changed(self, entity_id, from_state, to_state): self.adjust_lights([entity_id], 1) From 14f272e8cd197ecfd347d85abe201d03d616b88b Mon Sep 17 00:00:00 2001 From: Clayton Nummer Date: Tue, 30 Jul 2019 18:25:02 -0400 Subject: [PATCH 3/8] Change brightness scale to max at 254 Supposedly the max light brightness is 255, but my Hue and Lightify lights both max at 254. 0 turns off the light, so the range is probably (0, 255) not [0, 255] --- custom_components/circadian_lighting/switch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index 8264fc49..8186d346 100644 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -267,7 +267,7 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): if transition == None: transition = self._cl.data['transition'] - brightness = int((self._attributes['brightness'] / 100) * 255) if self._attributes['brightness'] is not None else None + brightness = int((self._attributes['brightness'] / 100) * 254) if self._attributes['brightness'] is not None else None mired = int(self.calc_ct()) if self._lights_ct is not None else None rgb = tuple(map(int, self.calc_rgb())) if self._lights_rgb is not None else None xy = self.calc_xy() if self._lights_xy is not None else None From 6dcd192f4eaa1814854681a5b589100ba04c895d Mon Sep 17 00:00:00 2001 From: Clayton Nummer Date: Tue, 30 Jul 2019 18:25:42 -0400 Subject: [PATCH 4/8] Bump version number --- custom_components/circadian_lighting/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/circadian_lighting/__init__.py b/custom_components/circadian_lighting/__init__.py index 6458e57c..4a9cea2e 100644 --- a/custom_components/circadian_lighting/__init__.py +++ b/custom_components/circadian_lighting/__init__.py @@ -48,7 +48,7 @@ from homeassistant.util.dt import utcnow as dt_utcnow, as_local from datetime import datetime, timedelta -VERSION = '1.0.6' +VERSION = '1.0.7' _LOGGER = logging.getLogger(__name__) From 7185fe3febbf45b1ca2b486c3df27328b837a00e Mon Sep 17 00:00:00 2001 From: Clayton Nummer Date: Wed, 31 Jul 2019 14:53:34 -0400 Subject: [PATCH 5/8] Only react to light state change to 'on' And only when light isn't already on. This should allow for users to disable CL when they adjust a light from the frontend, without CL immediately readjusting. This also should remove the need for checking state of each light before adjusting, because infinite loops should no longer trigger. --- .../circadian_lighting/__init__.py | 2 +- .../circadian_lighting/switch.py | 107 +++++++----------- 2 files changed, 44 insertions(+), 65 deletions(-) diff --git a/custom_components/circadian_lighting/__init__.py b/custom_components/circadian_lighting/__init__.py index 4a9cea2e..95f19301 100644 --- a/custom_components/circadian_lighting/__init__.py +++ b/custom_components/circadian_lighting/__init__.py @@ -48,7 +48,7 @@ from homeassistant.util.dt import utcnow as dt_utcnow, as_local from datetime import datetime, timedelta -VERSION = '1.0.7' +VERSION = '1.0.8' _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index 8186d346..8c5b25a5 100644 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -275,82 +275,61 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): for light in lights: """Set color of array of ct light if on.""" if self._lights_ct is not None and light in self._lights_ct and is_on(self.hass, light): - """Check to see if light is already set properly""" - lightAttrs = self.hass.states.get(light).attributes - if ( (ATTR_COLOR_TEMP in lightAttrs and lightAttrs[ATTR_COLOR_TEMP] == mired) and - (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) ): - _LOGGER.debug(light + " already set to the proper values, not adjusting") - else: - service_data = {ATTR_ENTITY_ID: light} - if mired is not None: - service_data[ATTR_COLOR_TEMP] = mired - if brightness is not None: - service_data[ATTR_BRIGHTNESS] = brightness - if transition is not None: - service_data[ATTR_TRANSITION] = transition - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " CT Adjusted - color_temp: " + str(mired) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) + service_data = {ATTR_ENTITY_ID: light} + if mired is not None: + service_data[ATTR_COLOR_TEMP] = mired + if brightness is not None: + service_data[ATTR_BRIGHTNESS] = brightness + if transition is not None: + service_data[ATTR_TRANSITION] = transition + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " CT Adjusted - color_temp: " + str(mired) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) """Set color of array of rgb light if on.""" if self._lights_rgb is not None and light in self._lights_rgb and is_on(self.hass, light): - """Check to see if light is already set properly""" - lightAttrs = self.hass.states.get(light).attributes - if ( (ATTR_RGB_COLOR in lightAttrs and lightAttrs[ATTR_RGB_COLOR] == rgb) and - (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) ): - _LOGGER.debug(light + " already set to the proper values, not adjusting") - else: - service_data = {ATTR_ENTITY_ID: light} - if rgb is not None: - service_data[ATTR_RGB_COLOR] = rgb - if brightness is not None: - service_data[ATTR_BRIGHTNESS] = brightness - if transition is not None: - service_data[ATTR_TRANSITION] = transition - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " RGB Adjusted - rgb_color: " + str(rgb) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) + service_data = {ATTR_ENTITY_ID: light} + if rgb is not None: + service_data[ATTR_RGB_COLOR] = rgb + if brightness is not None: + service_data[ATTR_BRIGHTNESS] = brightness + if transition is not None: + service_data[ATTR_TRANSITION] = transition + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " RGB Adjusted - rgb_color: " + str(rgb) + ", brightness: " + str(brightness) + ", transition: " + str(transition)) """Set color of array of xy light if on.""" if self._lights_xy is not None and light in self._lights_xy and is_on(self.hass, light): - """Check to see if light is already set properly""" - lightAttrs = self.hass.states.get(light).attributes - if ( (ATTR_XY_COLOR in lightAttrs and lightAttrs[ATTR_XY_COLOR] == xy) and - (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness) and - (ATTR_WHITE_VALUE in lightAttrs and lightAttrs[ATTR_WHITE_VALUE] == brightness) ): - _LOGGER.debug(light + " already set to the proper values, not adjusting") - else: - service_data = {ATTR_ENTITY_ID: light} - if xy is not None: - service_data[ATTR_XY_COLOR] = xy - if brightness is not None: - service_data[ATTR_BRIGHTNESS] = brightness - service_data[ATTR_WHITE_VALUE] = brightness - if transition is not None: - service_data[ATTR_TRANSITION] = transition - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " XY Adjusted - xy_color: " + str(xy) + ", brightness: " + str(brightness) + ", transition: " + str(transition) + ", white_value: " + str(brightness)) + service_data = {ATTR_ENTITY_ID: light} + if xy is not None: + service_data[ATTR_XY_COLOR] = xy + if brightness is not None: + service_data[ATTR_BRIGHTNESS] = brightness + service_data[ATTR_WHITE_VALUE] = brightness + if transition is not None: + service_data[ATTR_TRANSITION] = transition + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " XY Adjusted - xy_color: " + str(xy) + ", brightness: " + str(brightness) + ", transition: " + str(transition) + ", white_value: " + str(brightness)) """Set color of array of brightness light if on.""" if self._lights_brightness is not None and light in self._lights_brightness and is_on(self.hass, light): - """Check to see if light is already set properly""" - lightAttrs = self.hass.states.get(light).attributes - if (ATTR_BRIGHTNESS in lightAttrs and lightAttrs[ATTR_BRIGHTNESS] == brightness): - _LOGGER.debug(light + " already set to the proper values, not adjusting") - else: - service_data = {ATTR_ENTITY_ID: light} - if brightness is not None: - service_data[ATTR_BRIGHTNESS] = brightness - if transition is not None: - service_data[ATTR_TRANSITION] = transition - self.hass.services.call( - LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) - _LOGGER.debug(light + " Brightness Adjusted - brightness: " + str(brightness) + ", transition: " + str(transition)) + service_data = {ATTR_ENTITY_ID: light} + if brightness is not None: + service_data[ATTR_BRIGHTNESS] = brightness + if transition is not None: + service_data[ATTR_TRANSITION] = transition + self.hass.services.call( + LIGHT_DOMAIN, SERVICE_TURN_ON, service_data) + _LOGGER.debug(light + " Brightness Adjusted - brightness: " + str(brightness) + ", transition: " + str(transition)) def light_state_changed(self, entity_id, from_state, to_state): - self.adjust_lights([entity_id], 1) + _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) + if to_state.state == 'on' and from_state.state != 'on': + self.adjust_lights([entity_id], 1) def sleep_state_changed(self, entity_id, from_state, to_state): + _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) if to_state.state == self._sleep_state or from_state.state == self._sleep_state: self.update_switch(1) \ No newline at end of file From be01be243dd011e5d23f4b92c2a882e77717da9f Mon Sep 17 00:00:00 2001 From: Clayton Nummer Date: Sun, 4 Aug 2019 14:16:59 -0400 Subject: [PATCH 6/8] Define "initial transition" and use it when CL switch is turned on A 1 sec transition was used when a light is turned on or when sleep state changes. The short transition should also be used when the CL switch is turned on. Also, because this is used in multiple spots, better to define it in one spot (this will also make it easier to make it configurable, if desired) --- custom_components/circadian_lighting/__init__.py | 2 +- custom_components/circadian_lighting/switch.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/custom_components/circadian_lighting/__init__.py b/custom_components/circadian_lighting/__init__.py index 95f19301..c3f993ba 100644 --- a/custom_components/circadian_lighting/__init__.py +++ b/custom_components/circadian_lighting/__init__.py @@ -48,7 +48,7 @@ from homeassistant.util.dt import utcnow as dt_utcnow, as_local from datetime import datetime, timedelta -VERSION = '1.0.8' +VERSION = '1.0.9' _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index 8c5b25a5..420a3d90 100644 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -45,6 +45,7 @@ CONF_SLEEP_CT = 'sleep_colortemp' CONF_SLEEP_BRIGHT = 'sleep_brightness' CONF_DISABLE_ENTITY = 'disable_entity' CONF_DISABLE_STATE = 'disable_state' +DEFAULT_INITIAL_TRANSITION = 1 PLATFORM_SCHEMA = vol.Schema({ vol.Required(CONF_PLATFORM): 'circadian_lighting', @@ -192,7 +193,7 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): self._state = True # Make initial update - self.update_switch() + self.update_switch(DEFAULT_INITIAL_TRANSITION) self.schedule_update_ha_state() @@ -327,9 +328,9 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): def light_state_changed(self, entity_id, from_state, to_state): _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) if to_state.state == 'on' and from_state.state != 'on': - self.adjust_lights([entity_id], 1) + self.adjust_lights([entity_id], DEFAULT_INITIAL_TRANSITION) def sleep_state_changed(self, entity_id, from_state, to_state): _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) if to_state.state == self._sleep_state or from_state.state == self._sleep_state: - self.update_switch(1) \ No newline at end of file + self.update_switch(DEFAULT_INITIAL_TRANSITION) \ No newline at end of file From abc151601b43c7df213bcf319413dcdba9b29163 Mon Sep 17 00:00:00 2001 From: Clayton Nummer Date: Sun, 4 Aug 2019 14:49:14 -0400 Subject: [PATCH 7/8] Adjust lights immediately when disable entity state changes I'm thinking about removing the disable entity option, but while it remains this is the proper behavior --- custom_components/circadian_lighting/switch.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index 420a3d90..9aa6c3a9 100644 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -148,6 +148,8 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): track_state_change(hass, self._lights, self.light_state_changed) if self._sleep_entity is not None: track_state_change(hass, self._sleep_entity, self.sleep_state_changed) + if self._disable_entity is not None: + track_state_change(hass, self._disable_entity, self.disable_state_changed) @property def entity_id(self): @@ -333,4 +335,9 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): def sleep_state_changed(self, entity_id, from_state, to_state): _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) if to_state.state == self._sleep_state or from_state.state == self._sleep_state: + self.update_switch(DEFAULT_INITIAL_TRANSITION) + + def disable_state_changed(self, entity_id, from_state, to_state): + _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) + if from_state.state == self._disable_state: self.update_switch(DEFAULT_INITIAL_TRANSITION) \ No newline at end of file From ca4b4fc7bd9f7eab51dee9d2d5861f3df66b99ff Mon Sep 17 00:00:00 2001 From: Clayton Nummer Date: Sun, 4 Aug 2019 15:15:33 -0400 Subject: [PATCH 8/8] Exemption handling Handles some unexpected state behavior --- .../circadian_lighting/switch.py | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index 9aa6c3a9..6fef883b 100644 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -328,16 +328,25 @@ class CircadianSwitch(SwitchDevice, RestoreEntity): _LOGGER.debug(light + " Brightness Adjusted - brightness: " + str(brightness) + ", transition: " + str(transition)) def light_state_changed(self, entity_id, from_state, to_state): - _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) - if to_state.state == 'on' and from_state.state != 'on': - self.adjust_lights([entity_id], DEFAULT_INITIAL_TRANSITION) + try: + _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) + if to_state.state == 'on' and from_state.state != 'on': + self.adjust_lights([entity_id], DEFAULT_INITIAL_TRANSITION) + except: + pass def sleep_state_changed(self, entity_id, from_state, to_state): - _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) - if to_state.state == self._sleep_state or from_state.state == self._sleep_state: - self.update_switch(DEFAULT_INITIAL_TRANSITION) + try: + _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) + if to_state.state == self._sleep_state or from_state.state == self._sleep_state: + self.update_switch(DEFAULT_INITIAL_TRANSITION) + except: + pass def disable_state_changed(self, entity_id, from_state, to_state): - _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) - if from_state.state == self._disable_state: - self.update_switch(DEFAULT_INITIAL_TRANSITION) \ No newline at end of file + try: + _LOGGER.debug(entity_id + " change from " + str(from_state) + " to " + str(to_state)) + if from_state.state == self._disable_state: + self.update_switch(DEFAULT_INITIAL_TRANSITION) + except: + pass \ No newline at end of file