From 0e3c4f438ee2b963c69e2d03c537815956846aba Mon Sep 17 00:00:00 2001 From: Xavier Moreno Date: Thu, 7 Jan 2021 20:46:38 +0100 Subject: [PATCH] refactor(controller): change typings for action mapping --- apps/controllerx/cx_const.py | 3 ++- apps/controllerx/cx_core/controller.py | 18 ++++++++++++++---- .../cx_core/type/cover_controller.py | 4 ++-- .../cx_core/type/light_controller.py | 4 ++-- .../cx_core/type/media_player_controller.py | 4 ++-- .../cx_core/type/switch_controller.py | 4 ++-- apps/controllerx/cx_devices/ikea.py | 17 ++++++++++++----- apps/controllerx/cx_devices/muller_licht.py | 6 +++--- tests/unit_tests/cx_core/controller_test.py | 5 +++-- tests/unit_tests/cx_core/type/type_test.py | 4 ++-- 10 files changed, 44 insertions(+), 25 deletions(-) diff --git a/apps/controllerx/cx_const.py b/apps/controllerx/cx_const.py index 6984f3e4..372ecf76 100644 --- a/apps/controllerx/cx_const.py +++ b/apps/controllerx/cx_const.py @@ -1,9 +1,10 @@ from typing import Any, Awaitable, Callable, Dict, Tuple, Union ActionFunction = Callable[..., Awaitable[Any]] -TypeAction = Union[ActionFunction, Tuple, str] +TypeAction = Union[ActionFunction, Tuple[Any, ...], str] ActionEvent = Union[str, int] TypeActionsMapping = Dict[ActionEvent, TypeAction] +ActionsMapping = Dict[ActionEvent, Union[ActionFunction, Tuple[Any, ...]]] class Light: diff --git a/apps/controllerx/cx_core/controller.py b/apps/controllerx/cx_core/controller.py index d7dc99c7..17817dc8 100644 --- a/apps/controllerx/cx_core/controller.py +++ b/apps/controllerx/cx_core/controller.py @@ -22,7 +22,13 @@ import cx_version from appdaemon.plugins.hass.hassapi import Hass # type: ignore from appdaemon.plugins.mqtt.mqttapi import Mqtt # type: ignore -from cx_const import ActionEvent, ActionFunction, TypeAction, TypeActionsMapping +from cx_const import ( + ActionEvent, + ActionFunction, + ActionsMapping, + TypeAction, + TypeActionsMapping, +) from cx_core import integration as integration_module from cx_core.integration import EventData, Integration @@ -72,8 +78,9 @@ class Controller(Hass, Mqtt): integration: Integration controllers_ids: List[str] actions_key_mapping: TypeActionsMapping + actions_mapping: ActionsMapping multiple_click_actions: Set[ActionEvent] - type_actions_mapping: TypeActionsMapping + type_actions_mapping: ActionsMapping action_delay: Dict[ActionEvent, int] action_delta: int action_times: Dict[str, float] @@ -82,7 +89,6 @@ class Controller(Hass, Mqtt): action_delay_handles: Dict[ActionEvent, Optional[float]] multiple_click_action_delay_tasks: Dict[ActionEvent, Optional[Future]] multiple_click_delay: int - actions_mapping: TypeActionsMapping async def initialize(self) -> None: self.log(f"🎮 ControllerX {cx_version.__version__}", ascii_encode=False) @@ -331,6 +337,10 @@ async def action_timer_callback(self, kwargs: Dict[str, Any]): level="INFO", ascii_encode=False, ) + self.log( + f"Extra:\n{extra}", + level="DEBUG", + ) action, *args = self.get_action(self.actions_mapping[action_key]) if "extra" in set(inspect.signature(action).parameters): await action(*args, extra=extra) @@ -411,5 +421,5 @@ def get_zha_action(self, data: EventData) -> Optional[str]: """ return None - def get_type_actions_mapping(self) -> TypeActionsMapping: + def get_type_actions_mapping(self) -> ActionsMapping: return {} diff --git a/apps/controllerx/cx_core/type/cover_controller.py b/apps/controllerx/cx_core/type/cover_controller.py index aafeee67..37a51d40 100644 --- a/apps/controllerx/cx_core/type/cover_controller.py +++ b/apps/controllerx/cx_core/type/cover_controller.py @@ -1,6 +1,6 @@ from typing import Callable, Type -from cx_const import Cover, TypeActionsMapping +from cx_const import ActionsMapping, Cover from cx_core.controller import action from cx_core.feature_support.cover import CoverSupport from cx_core.type_controller import Entity, TypeController @@ -35,7 +35,7 @@ async def initialize(self) -> None: def _get_entity_type(self) -> Type[Entity]: return Entity - def get_type_actions_mapping(self) -> TypeActionsMapping: + def get_type_actions_mapping(self) -> ActionsMapping: return { Cover.OPEN: self.open, Cover.CLOSE: self.close, diff --git a/apps/controllerx/cx_core/type/light_controller.py b/apps/controllerx/cx_core/type/light_controller.py index 27d266cd..f96fefd5 100644 --- a/apps/controllerx/cx_core/type/light_controller.py +++ b/apps/controllerx/cx_core/type/light_controller.py @@ -1,6 +1,6 @@ from typing import Any, Dict, Optional, Type, Union -from cx_const import Light, TypeActionsMapping +from cx_const import ActionsMapping, Light from cx_core.color_helper import get_color_wheel from cx_core.controller import action from cx_core.feature_support.light import LightSupport @@ -120,7 +120,7 @@ async def initialize(self) -> None: def _get_entity_type(self) -> Type[LightEntity]: return LightEntity - def get_type_actions_mapping(self) -> TypeActionsMapping: + def get_type_actions_mapping(self) -> ActionsMapping: return { Light.ON: self.on, Light.OFF: self.off, diff --git a/apps/controllerx/cx_core/type/media_player_controller.py b/apps/controllerx/cx_core/type/media_player_controller.py index 8aead587..dccfbf8a 100644 --- a/apps/controllerx/cx_core/type/media_player_controller.py +++ b/apps/controllerx/cx_core/type/media_player_controller.py @@ -1,6 +1,6 @@ from typing import Type -from cx_const import MediaPlayer, TypeActionsMapping +from cx_const import ActionsMapping, MediaPlayer from cx_core.controller import action from cx_core.feature_support.media_player import MediaPlayerSupport from cx_core.release_hold_controller import ReleaseHoldController @@ -26,7 +26,7 @@ async def initialize(self) -> None: def _get_entity_type(self) -> Type[Entity]: return Entity - def get_type_actions_mapping(self) -> TypeActionsMapping: + def get_type_actions_mapping(self) -> ActionsMapping: return { MediaPlayer.HOLD_VOLUME_DOWN: (self.hold, Stepper.DOWN), MediaPlayer.HOLD_VOLUME_UP: (self.hold, Stepper.UP), diff --git a/apps/controllerx/cx_core/type/switch_controller.py b/apps/controllerx/cx_core/type/switch_controller.py index a4cfd794..f8a9e5d3 100644 --- a/apps/controllerx/cx_core/type/switch_controller.py +++ b/apps/controllerx/cx_core/type/switch_controller.py @@ -1,6 +1,6 @@ from typing import Type -from cx_const import Switch, TypeActionsMapping +from cx_const import ActionsMapping, Switch from cx_core.controller import action from cx_core.type_controller import Entity, TypeController @@ -27,7 +27,7 @@ class SwitchController(TypeController[Entity]): ] entity_arg = "switch" - def get_type_actions_mapping(self) -> TypeActionsMapping: + def get_type_actions_mapping(self) -> ActionsMapping: return { Switch.ON: self.on, Switch.OFF: self.off, diff --git a/apps/controllerx/cx_devices/ikea.py b/apps/controllerx/cx_devices/ikea.py index 8161a8aa..e3186379 100644 --- a/apps/controllerx/cx_devices/ikea.py +++ b/apps/controllerx/cx_devices/ikea.py @@ -1,4 +1,11 @@ -from cx_const import Cover, Light, MediaPlayer, Switch, TypeActionsMapping +from cx_const import ( + ActionsMapping, + Cover, + Light, + MediaPlayer, + Switch, + TypeActionsMapping, +) from cx_core import ( CoverController, LightController, @@ -252,9 +259,9 @@ async def rotate_right_quick(self) -> None: await self.release() await self.on_full(LightController.ATTRIBUTE_BRIGHTNESS) - def get_type_actions_mapping(self) -> TypeActionsMapping: + def get_type_actions_mapping(self) -> ActionsMapping: parent_mapping = super().get_type_actions_mapping() - mapping: TypeActionsMapping = { + mapping: ActionsMapping = { "rotate_left_quick": self.rotate_left_quick, "rotate_right_quick": self.rotate_right_quick, } @@ -306,9 +313,9 @@ async def rotate_right_quick(self) -> None: await self.release() await self.play() - def get_type_actions_mapping(self) -> TypeActionsMapping: + def get_type_actions_mapping(self) -> ActionsMapping: parent_mapping = super().get_type_actions_mapping() - mapping: TypeActionsMapping = { + mapping: ActionsMapping = { "rotate_left_quick": self.rotate_left_quick, "rotate_right_quick": self.rotate_right_quick, } diff --git a/apps/controllerx/cx_devices/muller_licht.py b/apps/controllerx/cx_devices/muller_licht.py index a831754f..8d8da061 100644 --- a/apps/controllerx/cx_devices/muller_licht.py +++ b/apps/controllerx/cx_devices/muller_licht.py @@ -1,4 +1,4 @@ -from cx_const import Light, TypeActionsMapping +from cx_const import ActionsMapping, Light, TypeActionsMapping from cx_core import LightController from cx_core.controller import action from cx_core.integration import EventData @@ -14,9 +14,9 @@ async def change_xy_color(self, extra: EventData) -> None: if isinstance(self.integration, DeCONZIntegration): await self.on(xy_color=extra["xy"]) - def get_type_actions_mapping(self) -> TypeActionsMapping: + def get_type_actions_mapping(self) -> ActionsMapping: parent_mapping = super().get_type_actions_mapping() - mapping: TypeActionsMapping = { + mapping: ActionsMapping = { MLI404011LightController.CHANGE_XY_COLOR: self.change_xy_color, } parent_mapping.update(mapping) diff --git a/tests/unit_tests/cx_core/controller_test.py b/tests/unit_tests/cx_core/controller_test.py index 62328436..5ba8afdb 100644 --- a/tests/unit_tests/cx_core/controller_test.py +++ b/tests/unit_tests/cx_core/controller_test.py @@ -3,7 +3,7 @@ import appdaemon.plugins.hass.hassapi as hass # type: ignore import pytest -from cx_const import ActionEvent, ActionFunction, TypeAction, TypeActionsMapping +from cx_const import ActionEvent, ActionFunction, ActionsMapping, TypeAction from cx_core import integration as integration_module from cx_core.controller import Controller, action from pytest_mock.plugin import MockerFixture @@ -347,7 +347,8 @@ async def test_handle_action( ): sut.action_delta = action_delta sut.action_times = defaultdict(lambda: 0) - actions_mapping: TypeActionsMapping = {action: "test" for action in actions_input} + + actions_mapping: ActionsMapping = {action: fake_fn() for action in actions_input} sut.actions_mapping = actions_mapping call_action_patch = mocker.patch.object(sut, "call_action") diff --git a/tests/unit_tests/cx_core/type/type_test.py b/tests/unit_tests/cx_core/type/type_test.py index 9c162072..8b2cdee2 100644 --- a/tests/unit_tests/cx_core/type/type_test.py +++ b/tests/unit_tests/cx_core/type/type_test.py @@ -1,7 +1,7 @@ from typing import Type import pytest -from cx_const import TypeActionsMapping +from cx_const import ActionsMapping from cx_core import type as type_module from cx_core.type_controller import TypeController from pytest_mock.plugin import MockerFixture @@ -9,7 +9,7 @@ from tests.test_utils import get_classes -def check_mapping(mapping: TypeActionsMapping) -> None: +def check_mapping(mapping: ActionsMapping) -> None: if mapping is None: return for v in mapping.values():