def step(self, value: Number, direction: str) -> StepperOutput:
        value = self.min_max.clip(value)
        max_ = self.min_max.max
        min_ = self.min_max.min
        step = (max_ - min_) / self.steps

        new_value = value + Stepper.apply_sign(step, direction)
        if self.min_max.is_between(new_value):
            return StepperOutput(round(new_value, 3), next_direction=direction)
        else:
            new_value = 2 * self.min_max.clip(new_value) - new_value
            return StepperOutput(
                round(new_value, 3),
                next_direction=Stepper.invert_direction(direction))
Exemple #2
0
    def step(self, value: Number, direction: str) -> StepperOutput:
        value = self.min_max.clip(value)
        # We add +1 to include `max`
        max_ = self.min_max.max
        min_ = self.min_max.min
        step = (max_ - min_) / self.steps

        new_value = (((value + Stepper.apply_sign(step, direction)) - min_) %
                     (max_ - min_)) + min_
        new_value = round(new_value, 3)
        return StepperOutput(new_value, next_direction=direction)
Exemple #3
0
 async def change_light_state(
     self,
     old: float,
     attribute: str,
     direction: str,
     stepper: Stepper,
     action_type: str,
 ) -> bool:
     """
     This functions changes the state of the light depending on the previous
     value and attribute. It returns True when no more changes will need to be done.
     Otherwise, it returns False.
     """
     attributes: Dict[str, Any]
     if attribute == LightController.ATTRIBUTE_XY_COLOR:
         index_color, _ = stepper.step(self.index_color, direction)
         self.index_color = int(index_color)
         xy_color = self.color_wheel[self.index_color]
         attributes = {attribute: xy_color}
         if action_type == "hold":
             attributes["transition"] = self.delay / 1000
         await self.on(**attributes, light_on=True)
         # In case of xy_color mode it never finishes the loop, the hold loop
         # will only stop if the hold action is called when releasing the button.
         # I haven't experimented any problems with it, but a future implementation
         # would be to force the loop to stop after 4 or 5 loops as a safety measure.
         return False
     if self.check_smooth_power_on(
         attribute, direction, await self.get_entity_state(self.entity.name)
     ):
         await self.on_min(attribute, light_on=False)
         # # After smooth power on, the light should not brighten up.
         return True
     new_state_attribute, exceeded = stepper.step(old, direction)
     new_state_attribute = round(new_state_attribute, 3)
     attributes = {attribute: new_state_attribute}
     if action_type == "hold":
         attributes["transition"] = self.delay / 1000
     await self.on(**attributes, light_on=True)
     self.value_attribute = new_state_attribute
     return exceeded
Exemple #4
0
 def get_stepper(self, attribute: str, steps: Number, mode: str) -> Stepper:
     previous_direction = Stepper.invert_direction(self.hold_toggle_direction_init)
     if attribute == LightController.ATTRIBUTE_XY_COLOR:
         return IndexLoopStepper(len(self.color_wheel), previous_direction)
     if mode not in STEPPER_MODES:
         raise ValueError(
             f"`{mode}` mode is not available. Options are: {list(STEPPER_MODES.keys())}"
         )
     stepper_cls = STEPPER_MODES[mode]
     return stepper_cls(
         self.min_max_attributes[attribute], steps, previous_direction
     )
Exemple #5
0
    def step(self, value: Number, direction: str) -> StepperOutput:
        value = self.min_max.clip(value)
        sign = Stepper.sign(direction)
        max_ = self.min_max.max
        min_ = self.min_max.min
        step = (max_ - min_) / self.steps

        new_value = value + sign * step
        new_value = round(new_value, 3)
        if self.min_max.is_between(new_value):
            return StepperOutput(new_value, next_direction=direction)
        else:
            new_value = self.min_max.clip(new_value)
            return StepperOutput(new_value, next_direction=None)