From 760b2dc6660e6da798c1d9ed1c95db9cceb22c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20C=C3=A1ceres?= Date: Tue, 19 Nov 2024 19:01:03 +0100 Subject: [PATCH 1/5] light using delay when command is sent --- custom_components/smartir/light.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/custom_components/smartir/light.py b/custom_components/smartir/light.py index 1f976bf9..c555d4be 100644 --- a/custom_components/smartir/light.py +++ b/custom_components/smartir/light.py @@ -47,7 +47,7 @@ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Required(CONF_DEVICE_CODE): cv.positive_int, vol.Required(CONF_CONTROLLER_DATA): get_controller_schema(vol, cv), - vol.Optional(CONF_DELAY, default=DEFAULT_DELAY): cv.string, + vol.Optional(CONF_DELAY, default=DEFAULT_DELAY): cv.positive_float, vol.Optional(CONF_POWER_SENSOR): cv.entity_id, vol.Optional( CONF_POWER_SENSOR_DELAY, default=DEFAULT_POWER_SENSOR_DELAY @@ -322,6 +322,7 @@ async def send_command(self, cmd, count=1): try: for _ in range(count): await self._controller.send(remote_cmd) + await asyncio.sleep(self._delay) except Exception as e: _LOGGER.exception(e) From c70c60d89c114e69a04fa4fbb1bdd7f32ee12a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20C=C3=A1ceres?= Date: Tue, 19 Nov 2024 19:03:04 +0100 Subject: [PATCH 2/5] fix brightness step --- custom_components/smartir/light.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/smartir/light.py b/custom_components/smartir/light.py index c555d4be..30c378bd 100644 --- a/custom_components/smartir/light.py +++ b/custom_components/smartir/light.py @@ -286,7 +286,7 @@ async def async_turn_on(self, **params): new_brightness == len(self._brightnesses) - 1 or new_brightness == 0 ): - steps = len(self._colortemps) + steps = len(self._brightnesses) did_something = True self._brightness = self._brightnesses[new_brightness] await self.send_command(cmd, steps) From 9d6a303da1cd4c1e148f3afac1856a09cfddd23f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20C=C3=A1ceres?= Date: Tue, 19 Nov 2024 19:13:14 +0100 Subject: [PATCH 3/5] allowing commands per brightness or color values instead of up/down steps --- custom_components/smartir/light.py | 118 ++++++++++++++++++----------- 1 file changed, 75 insertions(+), 43 deletions(-) diff --git a/custom_components/smartir/light.py b/custom_components/smartir/light.py index 30c378bd..29abb073 100644 --- a/custom_components/smartir/light.py +++ b/custom_components/smartir/light.py @@ -40,6 +40,8 @@ CMD_POWER_ON = "on" CMD_POWER_OFF = "off" CMD_NIGHTLIGHT = "night" +CMD_COLORTEMPERATURE = "colorTemperature" +CMD_BRIGHTNESS = "brightness" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { @@ -105,13 +107,13 @@ def __init__(self, hass, config, device_data): self._colortemps = device_data["colorTemperature"] self._commands = device_data["commands"] - if ( + if CMD_COLORTEMPERATURE in self._commands or ( CMD_COLORMODE_COLDER in self._commands and CMD_COLORMODE_WARMER in self._commands ): self._colortemp = self.max_color_temp_kelvin - if CMD_NIGHTLIGHT in self._commands or ( + if CMD_NIGHTLIGHT in self._commands or CMD_BRIGHTNESS in self._commands or ( CMD_BRIGHTNESS_INCREASE in self._commands and CMD_BRIGHTNESS_DECREASE in self._commands ): @@ -231,26 +233,40 @@ async def async_turn_on(self, **params): target = params.get(ATTR_COLOR_TEMP_KELVIN) old_color_temp = DeviceData.closest_match(self._colortemp, self._colortemps) new_color_temp = DeviceData.closest_match(target, self._colortemps) - _LOGGER.debug( - f"Changing color temp from {self._colortemp}K step {old_color_temp} to {target}K step {new_color_temp}" - ) - - steps = new_color_temp - old_color_temp - did_something = True - if steps < 0: - cmd = CMD_COLORMODE_WARMER - steps = abs(steps) - else: - cmd = CMD_COLORMODE_COLDER - - if steps > 0 and cmd: - # If we are heading for the highest or lowest value, - # take the opportunity to resync by issuing enough - # commands to go the full range. - if new_color_temp == len(self._colortemps) - 1 or new_color_temp == 0: - steps = len(self._colortemps) + final_color_temp = f"{self._colortemps[new_color_temp]}" + if ( + CMD_COLORTEMPERATURE in self._commands + and isinstance(self._commands[CMD_COLORTEMPERATURE], dict) + and final_color_temp in self._commands[CMD_COLORTEMPERATURE] + ): + _LOGGER.debug( + f"Changing color temp from {self._colortemp}K to {target}K using found remote command for {final_color_temp}K" + ) + did_something = True + found_command = self._commands[CMD_COLORTEMPERATURE][final_color_temp] self._colortemp = self._colortemps[new_color_temp] - await self.send_command(cmd, steps) + await self.send_remote_command(found_command) + else: + _LOGGER.debug( + f"Changing color temp from {self._colortemp}K step {old_color_temp} to {target}K step {new_color_temp}" + ) + + steps = new_color_temp - old_color_temp + if steps < 0: + cmd = CMD_COLORMODE_WARMER + steps = abs(steps) + else: + cmd = CMD_COLORMODE_COLDER + + if steps > 0 and cmd: + # If we are heading for the highest or lowest value, + # take the opportunity to resync by issuing enough + # commands to go the full range. + if new_color_temp == len(self._colortemps) - 1 or new_color_temp == 0: + steps = len(self._colortemps) + did_something = True + self._colortemp = self._colortemps[new_color_temp] + await self.send_command(cmd, steps) if ATTR_BRIGHTNESS in params and self._support_brightness: # before checking the supported brightnesses, make a special case @@ -266,30 +282,43 @@ async def async_turn_on(self, **params): old_brightness = DeviceData.closest_match( self._brightness, self._brightnesses ) - new_brightness = DeviceData.closest_match(target, self._brightnesses) - did_something = True - _LOGGER.debug( - f"Changing brightness from {self._brightness} step {old_brightness} to {target} step {new_brightness}" - ) - steps = new_brightness - old_brightness - if steps < 0: - cmd = CMD_BRIGHTNESS_DECREASE - steps = abs(steps) - else: - cmd = CMD_BRIGHTNESS_INCREASE - - if steps > 0 and cmd: - # If we are heading for the highest or lowest value, - # take the opportunity to resync by issuing enough - # commands to go the full range. - if ( - new_brightness == len(self._brightnesses) - 1 - or new_brightness == 0 - ): - steps = len(self._brightnesses) + new_brightness = DeviceData.closest_match(target, self._brightnesses) + final_brightness = f"{self._brightnesses[new_brightness]}" + if ( + CMD_BRIGHTNESS in self._commands + and isinstance(self._commands[CMD_BRIGHTNESS], dict) + and final_brightness in self._commands[CMD_BRIGHTNESS] + ): + _LOGGER.debug( + f"Changing brightness from {self._brightness} to {target} using found remote command for {final_brightness}" + ) did_something = True + found_command = self._commands[CMD_BRIGHTNESS][final_brightness] self._brightness = self._brightnesses[new_brightness] - await self.send_command(cmd, steps) + await self.send_remote_command(found_command) + else: + _LOGGER.debug( + f"Changing brightness from {self._brightness} step {old_brightness} to {target} step {new_brightness}" + ) + steps = new_brightness - old_brightness + if steps < 0: + cmd = CMD_BRIGHTNESS_DECREASE + steps = abs(steps) + else: + cmd = CMD_BRIGHTNESS_INCREASE + + if steps > 0 and cmd: + # If we are heading for the highest or lowest value, + # take the opportunity to resync by issuing enough + # commands to go the full range. + if ( + new_brightness == len(self._brightnesses) - 1 + or new_brightness == 0 + ): + steps = len(self._brightnesses) + did_something = True + self._brightness = self._brightnesses[new_brightness] + await self.send_command(cmd, steps) # If we did nothing above, and the light is not detected as on # already issue the on command, even though we think the light @@ -317,6 +346,9 @@ async def send_command(self, cmd, count=1): return _LOGGER.debug(f"Sending {cmd} remote command {count} times.") remote_cmd = self._commands.get(cmd) + await self.send_remote_command(remote_cmd, count) + + async def send_remote_command(self, remote_cmd, count=1): async with self._temp_lock: self._on_by_remote = False try: From 814993ac0ad810f2ebf4e73af3122ad6c93fd233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20C=C3=A1ceres?= Date: Tue, 19 Nov 2024 19:19:27 +0100 Subject: [PATCH 4/5] turning on the device without on command setting the last values --- custom_components/smartir/light.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/custom_components/smartir/light.py b/custom_components/smartir/light.py index 29abb073..7d0f2f72 100644 --- a/custom_components/smartir/light.py +++ b/custom_components/smartir/light.py @@ -223,8 +223,20 @@ async def async_turn_on(self, **params): # Turn the light on if off if self._state != STATE_ON and not self._on_by_remote: self._state = STATE_ON - did_something = True - await self.send_command(CMD_POWER_ON) + if CMD_POWER_ON in self._commands: + did_something = True + await self.send_command(CMD_POWER_ON) + else: + if ATTR_COLOR_TEMP_KELVIN not in params: + _LOGGER.debug( + f"No power on command found, setting last color {self._colortemp}K" + ) + params[ATTR_COLOR_TEMP_KELVIN] = self._colortemp + if ATTR_BRIGHTNESS not in params: + _LOGGER.debug( + f"No power on command found, setting last brightness {self._brightness}" + ) + params[ATTR_BRIGHTNESS] = self._brightness if ( ATTR_COLOR_TEMP_KELVIN in params From 4175073e206af31e018dbe831d94b1ea02d2aa3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20C=C3=A1ceres?= Date: Tue, 19 Nov 2024 19:20:00 +0100 Subject: [PATCH 5/5] avoiding to emit the off command when the state is off --- custom_components/smartir/light.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/custom_components/smartir/light.py b/custom_components/smartir/light.py index 7d0f2f72..768e5109 100644 --- a/custom_components/smartir/light.py +++ b/custom_components/smartir/light.py @@ -345,9 +345,10 @@ async def async_turn_on(self, **params): self.async_write_ha_state() async def async_turn_off(self): - self._state = STATE_OFF - await self.send_command(CMD_POWER_OFF) - self.async_write_ha_state() + if self._state != STATE_OFF: + self._state = STATE_OFF + await self.send_command(CMD_POWER_OFF) + self.async_write_ha_state() async def async_toggle(self): await (self.async_turn_on() if not self.is_on else self.async_turn_off())