From bc82a2d88f59b40c95315bcf2217a676e216ffa7 Mon Sep 17 00:00:00 2001 From: Xavier Moreno Date: Sat, 21 Nov 2020 18:58:55 +0100 Subject: [PATCH] refactor(isort): organize imports with isort --- .coveragerc | 7 ---- .flake8 | 3 -- .gitignore | 3 +- .pre-commit-config.yaml | 36 +++++++++---------- .vscode/settings.json | 22 ++++++++++++ Pipfile | 1 + apps/controllerx/cx_const.py | 1 - apps/controllerx/cx_core/controller.py | 2 +- .../cx_core/feature_support/__init__.py | 2 +- apps/controllerx/cx_core/integration/mqtt.py | 3 +- apps/controllerx/cx_core/integration/state.py | 1 - apps/controllerx/cx_core/integration/z2m.py | 3 +- azure-pipelines.yml | 5 +-- pytest.ini | 2 -- setup.cfg | 30 ++++++++++++++++ tests/conftest.py | 2 +- tests/integ_tests/integ_test.py | 6 ++-- tests/test_utils.py | 4 +-- tests/unit_tests/cx_core/color_helper_test.py | 4 +-- tests/unit_tests/cx_core/controller_test.py | 6 ++-- .../cx_core/custom_controller_test.py | 6 ++-- .../feature_support/feature_support_test.py | 2 +- .../cx_core/integration/zha_test.py | 4 +-- .../cx_core/release_hold_controller_test.py | 6 ++-- .../cx_core/stepper/circular_stepper_test.py | 4 +-- .../cx_core/stepper/minmax_stepper_test.py | 4 +-- .../cx_core/type/cover_controller_test.py | 1 + .../cx_core/type/light_controller_test.py | 9 ++--- .../type/media_player_controller_test.py | 7 ++-- .../cx_core/type/switch_controller_test.py | 1 - tests/unit_tests/cx_core/type/type_test.py | 3 +- .../cx_core/type_controller_test.py | 5 +-- tests/unit_tests/cx_devices/aqara_test.py | 1 - tests/unit_tests/cx_devices/devices_test.py | 7 ++-- tests/unit_tests/cx_devices/legrand_test.py | 1 - tests/unit_tests/cx_devices/phillips_test.py | 1 - 36 files changed, 121 insertions(+), 84 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .flake8 create mode 100644 .vscode/settings.json delete mode 100644 pytest.ini create mode 100644 setup.cfg diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index 48a4e188..00000000 --- a/.coveragerc +++ /dev/null @@ -1,7 +0,0 @@ -[report] -exclude_lines = - # Have to re-enable the standard pragma - pragma: no cover - - # Don't complain if tests don't hit defensive assertion code: - raise NotImplementedError \ No newline at end of file diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 9c6a8ccc..00000000 --- a/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -ignore = E501, W503 -exclude = controllerx.py diff --git a/.gitignore b/.gitignore index a75742d0..f3f2f168 100644 --- a/.gitignore +++ b/.gitignore @@ -129,7 +129,8 @@ dmypy.json .pyre/ #VSCode -.vscode/ +.vscode/* +!.vscode/settings.json .idea # Ignoring Pipfile.lock since we support python 3.6, 3.7 and 3.8 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 97a4505b..7e9bf988 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,33 +1,29 @@ repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.4.0 - hooks: - - id: check-json - - id: pretty-format-json - args: - - --autofix - - --indent - - '4' - repo: local hooks: + - id: isort + name: isort + entry: pipenv run isort + language: python + types: [python] + args: [] + require_serial: false - id: black name: black - entry: pipenv run black apps/controllerx tests - language: system - pass_filenames: false - always_run: true + entry: pipenv run black + language: python + types: [python] - id: flake8 name: flake8 - entry: pipenv run flake8 apps/controllerx tests - language: system - pass_filenames: false - always_run: true + entry: pipenv run flake8 + language: python + types: [python] - id: mypy name: mypy - entry: pipenv run mypy apps/controllerx tests/ --no-implicit-optional - language: system + entry: pipenv run mypy apps/controllerx/ tests/ + language: python + types: [python] pass_filenames: false - always_run: true - id: pytest name: pytest entry: pipenv run pytest diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..986f6932 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,22 @@ +{ + "files.autoSave": "afterDelay", + "files.autoSaveDelay": 100, + "python.testing.pytestEnabled": true, + "editor.formatOnSave": true, + "python.formatting.provider": "black", + "python.analysis.typeCheckingMode": "basic", + "python.analysis.diagnosticMode": "workspace", + "python.analysis.stubPath": "apps/controllerx", + "python.testing.pytestArgs": [ + "tests" + ], + "python.languageServer": "Pylance", + "python.linting.mypyEnabled": true, + "python.linting.mypyCategorySeverity.note": "Error", + "python.linting.flake8Enabled": true, + "[python]": { + "editor.codeActionsOnSave": { + "source.organizeImports": true + } + }, +} \ No newline at end of file diff --git a/Pipfile b/Pipfile index 1743b134..0ab5ced5 100644 --- a/Pipfile +++ b/Pipfile @@ -14,6 +14,7 @@ pre-commit = "==2.8.2" commitizen = "==2.4.2" mypy = "==0.790" flake8 = "==3.8.4" +isort = "==5.6.4" controllerx = {path = ".", editable = true} [packages] diff --git a/apps/controllerx/cx_const.py b/apps/controllerx/cx_const.py index 8279fb52..6984f3e4 100644 --- a/apps/controllerx/cx_const.py +++ b/apps/controllerx/cx_const.py @@ -1,6 +1,5 @@ from typing import Any, Awaitable, Callable, Dict, Tuple, Union - ActionFunction = Callable[..., Awaitable[Any]] TypeAction = Union[ActionFunction, Tuple, str] ActionEvent = Union[str, int] diff --git a/apps/controllerx/cx_core/controller.py b/apps/controllerx/cx_core/controller.py index 09e3c84d..d35d3bcb 100644 --- a/apps/controllerx/cx_core/controller.py +++ b/apps/controllerx/cx_core/controller.py @@ -23,13 +23,13 @@ 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_core import integration as integration_module from cx_core.integration import EventData, Integration Service = Tuple[str, Dict] Services = List[Service] + DEFAULT_DELAY = 350 # In milliseconds DEFAULT_ACTION_DELTA = 300 # In milliseconds DEFAULT_MULTIPLE_CLICK_DELAY = 500 # In milliseconds diff --git a/apps/controllerx/cx_core/feature_support/__init__.py b/apps/controllerx/cx_core/feature_support/__init__.py index 31f7a297..75f024ac 100644 --- a/apps/controllerx/cx_core/feature_support/__init__.py +++ b/apps/controllerx/cx_core/feature_support/__init__.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Set, TYPE_CHECKING, Type, TypeVar +from typing import TYPE_CHECKING, List, Optional, Set, Type, TypeVar if TYPE_CHECKING: from cx_core.type_controller import TypeController diff --git a/apps/controllerx/cx_core/integration/mqtt.py b/apps/controllerx/cx_core/integration/mqtt.py index 5e965714..cf9d67ca 100644 --- a/apps/controllerx/cx_core/integration/mqtt.py +++ b/apps/controllerx/cx_core/integration/mqtt.py @@ -1,9 +1,8 @@ from typing import Optional from appdaemon.plugins.mqtt.mqttapi import Mqtt # type: ignore - from cx_const import TypeActionsMapping -from cx_core.integration import Integration, EventData +from cx_core.integration import EventData, Integration class MQTTIntegration(Integration): diff --git a/apps/controllerx/cx_core/integration/state.py b/apps/controllerx/cx_core/integration/state.py index fdf6b61c..520aa125 100644 --- a/apps/controllerx/cx_core/integration/state.py +++ b/apps/controllerx/cx_core/integration/state.py @@ -1,7 +1,6 @@ from typing import Optional from appdaemon.plugins.hass.hassapi import Hass # type: ignore - from cx_const import TypeActionsMapping from cx_core.integration import Integration diff --git a/apps/controllerx/cx_core/integration/z2m.py b/apps/controllerx/cx_core/integration/z2m.py index 94361c66..95c161bb 100644 --- a/apps/controllerx/cx_core/integration/z2m.py +++ b/apps/controllerx/cx_core/integration/z2m.py @@ -3,9 +3,8 @@ from appdaemon.plugins.hass.hassapi import Hass # type: ignore from appdaemon.plugins.mqtt.mqttapi import Mqtt # type: ignore - from cx_const import TypeActionsMapping -from cx_core.integration import Integration, EventData +from cx_core.integration import EventData, Integration LISTENS_TO_HA = "ha" LISTENS_TO_MQTT = "mqtt" diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d2a2933b..bef18e72 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,7 +21,6 @@ stages: jobs: - job: Build displayName: Build job - strategy: matrix: Python36: @@ -41,11 +40,13 @@ stages: displayName: Lock dependencies - script: pipenv install --system --deploy --dev displayName: Install dependencies + - script: isort apps/controllerx tests --check + displayName: Formatter (black) - script: black apps/controllerx tests --check displayName: Formatter (black) - script: flake8 apps/controllerx tests displayName: Styling (flake8) - - script: mypy apps/controllerx tests/ --no-implicit-optional + - script: mypy apps/controllerx tests/ displayName: Typing (mypy) - script: pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=apps --cov-report=xml --cov-report=html displayName: Tests (pytest) diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 86d57a40..00000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -mock_use_standalone_module = true diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..da7180ac --- /dev/null +++ b/setup.cfg @@ -0,0 +1,30 @@ +[isort] +profile=black + +[black] +line-length = 88 +exclude = .git,.hg,.mypy_cache,.tox,_build,buck-out,build,dist + +[flake8] +ignore = E501, W503 +exclude = controllerx.py +max-line-length = 88 + +[mypy] +python_version = 3.6 +namespace_packages = True +no_implicit_optional = True + +[tool:pytest] +mock_use_standalone_module = true + +[report] +exclude_lines = + # Have to re-enable the standard pragma + pragma: no cover + + # Don't complain if tests don't hit defensive assertion code: + raise NotImplementedError + +[mypy-appdaemon.*] +ignore_missing_imports = true diff --git a/tests/conftest.py b/tests/conftest.py index f7fd6046..5b95a790 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -4,8 +4,8 @@ import appdaemon.plugins.mqtt.mqttapi as mqtt # type: ignore import pytest from _pytest.monkeypatch import MonkeyPatch -from cx_core.controller import Controller from cx_core import LightController +from cx_core.controller import Controller from tests.test_utils import fake_fn diff --git a/tests/integ_tests/integ_test.py b/tests/integ_tests/integ_test.py index b7cd7bad..3070c6aa 100644 --- a/tests/integ_tests/integ_test.py +++ b/tests/integ_tests/integ_test.py @@ -3,11 +3,11 @@ from pathlib import Path from typing import Any, Dict -from pytest_mock.plugin import MockerFixture -from tests.test_utils import get_controller - import pytest import yaml +from pytest_mock.plugin import MockerFixture + +from tests.test_utils import get_controller def get_integ_tests(): diff --git a/tests/test_utils.py b/tests/test_utils.py index e5400c57..73e3c47b 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -2,11 +2,11 @@ import os import pkgutil from contextlib import contextmanager -from typing import Callable, TYPE_CHECKING, Generator, Optional -from mock import MagicMock +from typing import TYPE_CHECKING, Callable, Generator, Optional import pytest from _pytest._code.code import ExceptionInfo +from mock import MagicMock from pytest_mock.plugin import MockerFixture if TYPE_CHECKING: diff --git a/tests/unit_tests/cx_core/color_helper_test.py b/tests/unit_tests/cx_core/color_helper_test.py index 1c685a00..be200663 100644 --- a/tests/unit_tests/cx_core/color_helper_test.py +++ b/tests/unit_tests/cx_core/color_helper_test.py @@ -1,8 +1,8 @@ import pytest -from tests.test_utils import wrap_exetuction - from cx_core.color_helper import Colors, get_color_wheel +from tests.test_utils import wrap_exetuction + @pytest.mark.parametrize( "colors, error_expected", diff --git a/tests/unit_tests/cx_core/controller_test.py b/tests/unit_tests/cx_core/controller_test.py index 99216e30..a46390aa 100644 --- a/tests/unit_tests/cx_core/controller_test.py +++ b/tests/unit_tests/cx_core/controller_test.py @@ -4,11 +4,11 @@ import appdaemon.plugins.hass.hassapi as hass # type: ignore import pytest from cx_const import ActionEvent, ActionFunction, TypeAction, TypeActionsMapping -from pytest_mock.plugin import MockerFixture -from tests.test_utils import IntegrationMock, fake_fn, wrap_exetuction - from cx_core import integration as integration_module from cx_core.controller import Controller, action +from pytest_mock.plugin import MockerFixture + +from tests.test_utils import IntegrationMock, fake_fn, wrap_exetuction INTEGRATION_TEST_NAME = "test" CONTROLLER_NAME = "test_controller" diff --git a/tests/unit_tests/cx_core/custom_controller_test.py b/tests/unit_tests/cx_core/custom_controller_test.py index b24054ee..f59dea90 100644 --- a/tests/unit_tests/cx_core/custom_controller_test.py +++ b/tests/unit_tests/cx_core/custom_controller_test.py @@ -3,9 +3,6 @@ import pytest from _pytest.monkeypatch import MonkeyPatch from cx_const import TypeActionsMapping -from pytest_mock.plugin import MockerFixture -from tests.test_utils import fake_fn - from cx_core import ( CallServiceController, Controller, @@ -15,6 +12,9 @@ SwitchController, ) from cx_core.type_controller import TypeController +from pytest_mock.plugin import MockerFixture + +from tests.test_utils import fake_fn @pytest.mark.parametrize( diff --git a/tests/unit_tests/cx_core/feature_support/feature_support_test.py b/tests/unit_tests/cx_core/feature_support/feature_support_test.py index e9f2c592..faccfe64 100644 --- a/tests/unit_tests/cx_core/feature_support/feature_support_test.py +++ b/tests/unit_tests/cx_core/feature_support/feature_support_test.py @@ -1,6 +1,6 @@ -from cx_core.type_controller import TypeController import pytest from cx_core.feature_support import Features, FeatureSupport, SupportedFeatures +from cx_core.type_controller import TypeController @pytest.mark.parametrize( diff --git a/tests/unit_tests/cx_core/integration/zha_test.py b/tests/unit_tests/cx_core/integration/zha_test.py index cd2941dc..a7c004f4 100644 --- a/tests/unit_tests/cx_core/integration/zha_test.py +++ b/tests/unit_tests/cx_core/integration/zha_test.py @@ -1,7 +1,7 @@ from typing import Dict -from cx_core.controller import Controller -import pytest +import pytest +from cx_core.controller import Controller from cx_core.integration.zha import ZHAIntegration from pytest_mock.plugin import MockerFixture diff --git a/tests/unit_tests/cx_core/release_hold_controller_test.py b/tests/unit_tests/cx_core/release_hold_controller_test.py index 203a61a3..4f2a512a 100644 --- a/tests/unit_tests/cx_core/release_hold_controller_test.py +++ b/tests/unit_tests/cx_core/release_hold_controller_test.py @@ -1,9 +1,9 @@ -from _pytest.monkeypatch import MonkeyPatch import pytest +from _pytest.monkeypatch import MonkeyPatch +from cx_core.controller import Controller, ReleaseHoldController from pytest_mock import MockerFixture -from tests.test_utils import fake_fn -from cx_core.controller import Controller, ReleaseHoldController +from tests.test_utils import fake_fn class FakeReleaseHoldController(ReleaseHoldController): diff --git a/tests/unit_tests/cx_core/stepper/circular_stepper_test.py b/tests/unit_tests/cx_core/stepper/circular_stepper_test.py index a516c0e8..bf6159e4 100644 --- a/tests/unit_tests/cx_core/stepper/circular_stepper_test.py +++ b/tests/unit_tests/cx_core/stepper/circular_stepper_test.py @@ -1,8 +1,8 @@ from typing import Tuple -import pytest -from cx_core.stepper.circular_stepper import CircularStepper +import pytest from cx_core.stepper import Stepper +from cx_core.stepper.circular_stepper import CircularStepper from typing_extensions import Literal diff --git a/tests/unit_tests/cx_core/stepper/minmax_stepper_test.py b/tests/unit_tests/cx_core/stepper/minmax_stepper_test.py index 0d2a4bb8..a8d6709b 100644 --- a/tests/unit_tests/cx_core/stepper/minmax_stepper_test.py +++ b/tests/unit_tests/cx_core/stepper/minmax_stepper_test.py @@ -1,8 +1,8 @@ from typing import Tuple -import pytest -from cx_core.stepper.minmax_stepper import MinMaxStepper +import pytest from cx_core.stepper import Stepper +from cx_core.stepper.minmax_stepper import MinMaxStepper from typing_extensions import Literal diff --git a/tests/unit_tests/cx_core/type/cover_controller_test.py b/tests/unit_tests/cx_core/type/cover_controller_test.py index d3dbb7a5..2e19ef97 100644 --- a/tests/unit_tests/cx_core/type/cover_controller_test.py +++ b/tests/unit_tests/cx_core/type/cover_controller_test.py @@ -7,6 +7,7 @@ from cx_core.feature_support.cover import CoverSupport from cx_core.type_controller import TypeController from pytest_mock.plugin import MockerFixture + from tests.test_utils import fake_fn, wrap_exetuction ENTITY_NAME = "cover.test" diff --git a/tests/unit_tests/cx_core/type/light_controller_test.py b/tests/unit_tests/cx_core/type/light_controller_test.py index 92191164..77a50a80 100644 --- a/tests/unit_tests/cx_core/type/light_controller_test.py +++ b/tests/unit_tests/cx_core/type/light_controller_test.py @@ -1,17 +1,18 @@ from typing import Any, Dict, Set, Tuple, Type, Union -from _pytest.monkeypatch import MonkeyPatch -from cx_core.controller import Controller + import pytest +from _pytest.monkeypatch import MonkeyPatch from cx_core import LightController, ReleaseHoldController +from cx_core.controller import Controller from cx_core.feature_support.light import LightSupport from cx_core.stepper import Stepper from cx_core.stepper.circular_stepper import CircularStepper from cx_core.stepper.minmax_stepper import MinMaxStepper +from cx_core.type.light_controller import ColorMode, LightEntity from pytest_mock.plugin import MockerFixture from typing_extensions import Literal -from tests.test_utils import fake_fn, wrap_exetuction -from cx_core.type.light_controller import ColorMode, LightEntity +from tests.test_utils import fake_fn, wrap_exetuction ENTITY_NAME = "light.test" diff --git a/tests/unit_tests/cx_core/type/media_player_controller_test.py b/tests/unit_tests/cx_core/type/media_player_controller_test.py index f8468956..3010e1bc 100644 --- a/tests/unit_tests/cx_core/type/media_player_controller_test.py +++ b/tests/unit_tests/cx_core/type/media_player_controller_test.py @@ -1,13 +1,14 @@ from typing import List -from _pytest.monkeypatch import MonkeyPatch -from cx_core.controller import Controller -import pytest +import pytest +from _pytest.monkeypatch import MonkeyPatch from cx_core import MediaPlayerController, ReleaseHoldController +from cx_core.controller import Controller from cx_core.feature_support.media_player import MediaPlayerSupport from cx_core.stepper import Stepper from pytest_mock.plugin import MockerFixture from typing_extensions import Literal + from tests.test_utils import fake_fn ENTITY_NAME = "media_player.test" diff --git a/tests/unit_tests/cx_core/type/switch_controller_test.py b/tests/unit_tests/cx_core/type/switch_controller_test.py index 6912f26d..5ae7a1e4 100644 --- a/tests/unit_tests/cx_core/type/switch_controller_test.py +++ b/tests/unit_tests/cx_core/type/switch_controller_test.py @@ -3,7 +3,6 @@ from cx_core.type_controller import Entity from pytest_mock.plugin import MockerFixture - ENTITY_NAME = "switch.test" diff --git a/tests/unit_tests/cx_core/type/type_test.py b/tests/unit_tests/cx_core/type/type_test.py index e3e0bf6f..9c162072 100644 --- a/tests/unit_tests/cx_core/type/type_test.py +++ b/tests/unit_tests/cx_core/type/type_test.py @@ -1,10 +1,11 @@ from typing import Type +import pytest from cx_const import TypeActionsMapping from cx_core import type as type_module from cx_core.type_controller import TypeController -import pytest from pytest_mock.plugin import MockerFixture + from tests.test_utils import get_classes diff --git a/tests/unit_tests/cx_core/type_controller_test.py b/tests/unit_tests/cx_core/type_controller_test.py index db7bbba7..9d66b9e7 100644 --- a/tests/unit_tests/cx_core/type_controller_test.py +++ b/tests/unit_tests/cx_core/type_controller_test.py @@ -1,12 +1,13 @@ -from tests.test_utils import fake_fn, wrap_exetuction from typing import Any, Dict, List, Type import pytest +from _pytest.monkeypatch import MonkeyPatch from cx_core.controller import Controller from cx_core.feature_support import FeatureSupport from cx_core.type_controller import Entity, TypeController from pytest_mock.plugin import MockerFixture -from _pytest.monkeypatch import MonkeyPatch + +from tests.test_utils import fake_fn, wrap_exetuction ENTITY_ARG = "my_entity" ENTITY_NAME = "domain_1.test" diff --git a/tests/unit_tests/cx_devices/aqara_test.py b/tests/unit_tests/cx_devices/aqara_test.py index ff544fd4..3cb959e1 100644 --- a/tests/unit_tests/cx_devices/aqara_test.py +++ b/tests/unit_tests/cx_devices/aqara_test.py @@ -1,6 +1,5 @@ import pytest from cx_core.integration import EventData - from cx_devices.aqara import ( MFKZQ01LMLightController, WXKG01LMLightController, diff --git a/tests/unit_tests/cx_devices/devices_test.py b/tests/unit_tests/cx_devices/devices_test.py index c08d8341..864772a2 100644 --- a/tests/unit_tests/cx_devices/devices_test.py +++ b/tests/unit_tests/cx_devices/devices_test.py @@ -1,11 +1,12 @@ from typing import Callable, KeysView, List, Optional, Type -import pytest -from tests.test_utils import get_classes, get_controller import cx_devices as devices_module +import pytest +from cx_const import ActionEvent, TypeActionsMapping from cx_core import Controller from cx_core.controller import ReleaseHoldController -from cx_const import TypeActionsMapping, ActionEvent + +from tests.test_utils import get_classes, get_controller def check_mapping( diff --git a/tests/unit_tests/cx_devices/legrand_test.py b/tests/unit_tests/cx_devices/legrand_test.py index bea62929..d99737d4 100644 --- a/tests/unit_tests/cx_devices/legrand_test.py +++ b/tests/unit_tests/cx_devices/legrand_test.py @@ -1,6 +1,5 @@ import pytest from cx_core.integration import EventData - from cx_devices.legrand import get_zha_action_LegrandWallController diff --git a/tests/unit_tests/cx_devices/phillips_test.py b/tests/unit_tests/cx_devices/phillips_test.py index bbec757b..f94bdd98 100644 --- a/tests/unit_tests/cx_devices/phillips_test.py +++ b/tests/unit_tests/cx_devices/phillips_test.py @@ -1,6 +1,5 @@ import pytest from cx_core.integration import EventData - from cx_devices.phillips import HueDimmerController