Skip to content

Commit

Permalink
feat(light_controller): add "hold_toggle_direction_init" attribute to…
Browse files Browse the repository at this point in the history
… select init state

related to #388
  • Loading branch information
xaviml committed Jan 1, 2022
1 parent 201fb8f commit c3822d6
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 7 deletions.
7 changes: 5 additions & 2 deletions apps/controllerx/cx_core/stepper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def exceeded(self) -> bool:
class Stepper(abc.ABC):
sign_mapping = {StepperDir.UP: 1, StepperDir.DOWN: -1}

previous_direction: str = StepperDir.DOWN
previous_direction: str
min_max: MinMax
steps: Number

Expand All @@ -66,9 +66,12 @@ def invert_direction(direction: str) -> str:
def sign(direction: str) -> int:
return Stepper.sign_mapping[direction]

def __init__(self, min_max: MinMax, steps: Number) -> None:
def __init__(
self, min_max: MinMax, steps: Number, previous_direction: str = StepperDir.DOWN
) -> None:
self.min_max = min_max
self.steps = steps
self.previous_direction = previous_direction

def get_direction(self, value: Number, direction: str) -> str:
if direction == StepperDir.TOGGLE:
Expand Down
6 changes: 3 additions & 3 deletions apps/controllerx/cx_core/stepper/index_loop_stepper.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from cx_const import Number
from cx_core.stepper import MinMax, Stepper, StepperOutput
from cx_core.stepper import MinMax, Stepper, StepperDir, StepperOutput


class IndexLoopStepper(Stepper):
def __init__(self, size: int) -> None:
super().__init__(MinMax(0, size - 1), size)
def __init__(self, size: int, previous_direction: str = StepperDir.DOWN) -> None:
super().__init__(MinMax(0, size - 1), size, previous_direction)

def step(self, value: Number, direction: str) -> StepperOutput:
value = self.min_max.clip(value)
Expand Down
15 changes: 13 additions & 2 deletions apps/controllerx/cx_core/type/light_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
DEFAULT_TRANSITION = 300
DEFAULT_ADD_TRANSITION = True
DEFAULT_TRANSITION_TURN_TOGGLE = False
DEFAULT_HOLD_TOGGLE_DIRECTION_INIT = "up"

ColorMode = str
# Once the minimum supported version of Python is 3.8,
Expand Down Expand Up @@ -136,6 +137,13 @@ async def init(self) -> None:
self.add_transition_turn_toggle = self.args.get(
"add_transition_turn_toggle", DEFAULT_TRANSITION_TURN_TOGGLE
)
self.hold_toggle_direction_init = self.get_option(
self.args.get(
"hold_toggle_direction_init", DEFAULT_HOLD_TOGGLE_DIRECTION_INIT
),
[StepperDir.UP, StepperDir.DOWN],
"`hold_toggle_direction_init`",
)
await super().init()

def _get_entity_type(self) -> Type[LightEntity]:
Expand Down Expand Up @@ -568,14 +576,17 @@ async def is_colortemp_supported(self) -> bool:

@lru_cache(maxsize=None)
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))
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)
return stepper_cls(
self.min_max_attributes[attribute], steps, previous_direction
)

async def get_attribute(self, attribute: str) -> str:
if attribute == LightController.ATTRIBUTE_COLOR:
Expand Down
1 change: 1 addition & 0 deletions docs/start/type-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ This controller allows the devices to control light or group of lights. This all
| `supported_features` | int | `0b101100` or `44` | See [below](#supported_features-field) for the explanation. |
| `supported_color_modes` | list | `["xy", "rgb"]` | It overrides the `supported_color_modes` that can be found in light attributes. Values can be `color_temp`, `hs`, `xy`, `rgb`, `rgbw` and `rgbww`. |
| `update_supported_features` | boolean | False | If `true`, it will check the supported features field everytime before calling any call service action. Useful in case the supported features of the device entity changes over the time. |
| `hold_toggle_direction_init` | string | `up` | It indicates the first direction of the hold toggle actions (`up` or `down`). |

_\* Required fields_

Expand Down
10 changes: 10 additions & 0 deletions tests/integ_tests/hold_toggle_previous_dir_init/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
livingroom_controller:
module: controllerx
class: E1810Controller
controller: sensor.livingroom_controller_action
integration: z2m
light: light.livingroom
hold_toggle_direction_init: "down"
merge_mapping:
brightness_up_hold: hold_brightness_toggle

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This test is testing that the @lru_cache decorator from light_controller.py::get_stepper
# is working properly, and that the returned stepper is the same everytime.
entity_state_attributes:
brightness: 60
entity_state: "on"
fired_actions: [brightness_up_hold, 0.450, brightness_up_release, 0.3, brightness_up_hold, 0.05, brightness_up_release]
expected_calls:
- service: light/turn_on
data:
entity_id: light.livingroom
transition: 0.35
brightness: 34.6
- service: light/turn_on
data:
entity_id: light.livingroom
transition: 0.35
brightness: 9.2
- service: light/turn_on
data:
entity_id: light.livingroom
transition: 0.35
brightness: 85.4

0 comments on commit c3822d6

Please sign in to comment.