""" White LimitlessLED group. """ import time from limitlessled import util from limitlessled.group import Group, rate from limitlessled.util import steps WHITE = 'white' class WhiteGroup(Group): """ White LimitlessLED group. """ def __init__(self, bridge, number, name): """ Initialize white group. Brightness and temperature must be initialized to some value. :param bridge: Associated bridge. :param number: Group number (1-4). :param name: Group name. """ super().__init__(bridge, number, name, WHITE) self._temperature = 0.5 def night_light(self): """ Set night light mode. """ cmd = self.command_set.night_light() self.send(cmd) @property def brightness(self): """ Brightness property. :returns: Brightness. """ return self._brightness @brightness.setter def brightness(self, brightness): """ Set the brightness. :param brightness: Value to set (0.0-1.0). """ try: cmd = self.command_set.brightness(brightness) self.send(cmd) self._brightness = brightness except AttributeError: self._setter('_brightness', brightness, self._dimmest, self._brightest, self._to_brightness) @property def temperature(self): """ Temperature property. :returns: Temperature (0.0-1.0) """ return self._temperature @temperature.setter def temperature(self, temperature): """ Set the temperature. :param temperature: Value to set (0.0-1.0). """ try: cmd = self.command_set.temperature(temperature) self.send(cmd) self._temperature = temperature except AttributeError: self._setter('_temperature', temperature, self._warmest, self._coolest, self._to_temperature) def transition(self, duration, brightness=None, temperature=None): """ Transition wrapper. Short-circuit transition if necessary. :param duration: Duration of transition. :param brightness: Transition to this brightness. :param temperature: Transition to this temperature. """ # Transition immediately if duration is zero. if duration == 0: if brightness is not None: self.brightness = brightness if temperature is not None: self.temperature = temperature return if brightness != self.brightness or temperature != self.temperature: self._transition(duration, brightness, temperature) @rate(reps=1) def _transition(self, duration, brightness, temperature): """ Complete a transition. :param duration: Duration of transition. :param brightness: Transition to this brightness. :param temperature: Transition to this temperature. """ # Set initial value. b_start = self.brightness t_start = self.temperature # Compute ideal step amount. b_steps = 0 if brightness is not None: b_steps = steps(self.brightness, brightness, self.command_set.brightness_steps) t_steps = 0 if temperature is not None: t_steps = steps(self.temperature, temperature, self.command_set.temperature_steps) # Compute ideal step amount (at least one). total_steps = max(b_steps, t_steps, 1) total_commands = b_steps + t_steps # Calculate wait. wait = self._wait(duration, total_steps, total_commands) # Scale down steps if no wait time. if wait == 0: b_steps, t_steps = self._scale_steps(duration, total_commands, b_steps, t_steps) total_steps = max(b_steps, t_steps, 1) # Perform transition. for i in range(total_steps): # Brightness. if b_steps > 0 and i % (total_steps / b_steps) == 0: self.brightness = util.transition(i, total_steps, b_start, brightness) # Temperature. elif t_steps > 0: self.temperature = util.transition(i, total_steps, t_start, temperature) # Wait. time.sleep(wait) def _setter(self, attr, value, bottom, top, to_step): """ Set a value. :param attr: Attribute to set. :param value: Value to use. :param bottom: Get to bottom value. :param top: Get to top value. :param to_step: Get to intermediary value. """ if value < 0 or value > 1: raise ValueError("out of range") if value == 0.0: bottom() elif value == 1.0: top() else: to_step(value) setattr(self, attr, value) def _to_brightness(self, brightness): """ Step to a given brightness. :param brightness: Get to this brightness. """ self._to_value(self._brightness, brightness, self.command_set.brightness_steps, self._dimmer, self._brighter) def _to_temperature(self, temperature): """ Step to a given temperature. :param temperature: Get to this temperature. """ self._to_value(self._temperature, temperature, self.command_set.temperature_steps, self._warmer, self._cooler) @rate(reps=1) def _to_value(self, current, target, max_steps, step_down, step_up): """ Step to a value :param current: Current value. :param target: Target value. :param max_steps: Maximum number of steps. :param step_down: Down function. :param step_up: Up function. """ for _ in range(steps(current, target, max_steps)): if (current - target) > 0: step_down() else: step_up() @rate(wait=0.025, reps=2) def _brightest(self): """ Group as bright as possible. """ for _ in range(steps(self.brightness, 1.0, self.command_set.brightness_steps)): self._brighter() @rate(wait=0.025, reps=2) def _dimmest(self): """ Group brightness as dim as possible. """ for _ in range(steps(self.brightness, 0.0, self.command_set.brightness_steps)): self._dimmer() @rate(wait=0.025, reps=2) def _warmest(self): """ Group temperature as warm as possible. """ for _ in range(steps(self.temperature, 0.0, self.command_set.temperature_steps)): self._warmer() @rate(wait=0.025, reps=2) def _coolest(self): """ Group temperature as cool as possible. """ for _ in range(steps(self.temperature, 1.0, self.command_set.temperature_steps)): self._cooler() def _brighter(self): """ One step brighter. """ self.send(self.command_set.brighter()) def _dimmer(self): """ One step dimmer. """ self.send(self.command_set.dimmer()) def _warmer(self): """ One step warmer. """ self.send(self.command_set.warmer()) def _cooler(self): """ One step cooler. """ self.send(self.command_set.cooler())