diff --git a/apps/controllerx/cx_core/integration/deconz.py b/apps/controllerx/cx_core/integration/deconz.py index 283faa9d..f3fcb8dd 100644 --- a/apps/controllerx/cx_core/integration/deconz.py +++ b/apps/controllerx/cx_core/integration/deconz.py @@ -4,6 +4,9 @@ from cx_const import DefaultActionsMapping # type:ignore from cx_core.integration import EventData, Integration +LISTENS_TO_ID = "id" +LISTENS_TO_UNIQUE_ID = "unique_id" + class DeCONZIntegration(Integration): name = "deconz" @@ -12,8 +15,12 @@ def get_default_actions_mapping(self) -> Optional[DefaultActionsMapping]: return self.controller.get_deconz_actions_mapping() async def listen_changes(self, controller_id: str) -> None: + listens_to = self.kwargs.get("listen_to", LISTENS_TO_ID) await Hass.listen_event( - self.controller, self.event_callback, "deconz_event", id=controller_id + self.controller, + self.event_callback, + "deconz_event", + **{listens_to: controller_id} ) async def event_callback( diff --git a/tests/unit_tests/cx_core/integration/deconz_test.py b/tests/unit_tests/cx_core/integration/deconz_test.py index 6c26c0a0..14449405 100644 --- a/tests/unit_tests/cx_core/integration/deconz_test.py +++ b/tests/unit_tests/cx_core/integration/deconz_test.py @@ -1,6 +1,7 @@ from typing import Dict, Optional import pytest +from appdaemon.plugins.hass.hassapi import Hass from cx_core.controller import Controller from cx_core.integration.deconz import DeCONZIntegration from pytest_mock.plugin import MockerFixture @@ -36,3 +37,35 @@ async def test_callback( deconz_integration = DeCONZIntegration(fake_controller, kwargs) await deconz_integration.event_callback("test", data, {}) handle_action_patch.assert_called_once_with(expected, extra=data) + + +@pytest.mark.parametrize( + "listen_to, expected_id", + [ + ("id", "id"), + ("unique_id", "unique_id"), + (None, "id"), + ], +) +@pytest.mark.asyncio +async def test_listen_changes( + fake_controller: Controller, + mocker: MockerFixture, + listen_to: Optional[str], + expected_id: str, +): + kwargs = {} + if listen_to is not None: + kwargs["listen_to"] = listen_to + + listen_event_mock = mocker.patch.object(Hass, "listen_event") + deconz_integration = DeCONZIntegration(fake_controller, kwargs) + + await deconz_integration.listen_changes("controller_id") + + listen_event_mock.assert_called_once_with( + fake_controller, + deconz_integration.event_callback, + "deconz_event", + **{expected_id: "controller_id"} + ) diff --git a/tests/unit_tests/cx_core/integration/z2m_test.py b/tests/unit_tests/cx_core/integration/z2m_test.py index b5d0d581..7e47991a 100644 --- a/tests/unit_tests/cx_core/integration/z2m_test.py +++ b/tests/unit_tests/cx_core/integration/z2m_test.py @@ -2,10 +2,14 @@ from typing import Any, Dict, Optional import pytest +from appdaemon.plugins.hass.hassapi import Hass +from appdaemon.plugins.mqtt.mqttapi import Mqtt from cx_core.controller import Controller from cx_core.integration.z2m import Z2MIntegration from pytest_mock import MockerFixture +from tests.test_utils import wrap_exetuction + @pytest.mark.parametrize( "data, action_key, action_group, handle_action_called, expected_called_with", @@ -56,3 +60,54 @@ async def test_event_callback( ) else: handle_action_patch.assert_not_called() + + +@pytest.mark.parametrize( + "listen_to, topic_prefix, expected_id", + [ + ("ha", None, "ha"), + (None, None, "ha"), + ("mqtt", None, "mqtt"), + ("mqtt", "my_prefix", "mqtt"), + ("fake", None, None), + ], +) +@pytest.mark.asyncio +async def test_listen_changes( + fake_controller: Controller, + mocker: MockerFixture, + listen_to: Optional[str], + topic_prefix: Optional[str], + expected_id: str, +): + kwargs = {} + if listen_to is not None: + kwargs["listen_to"] = listen_to + if topic_prefix is not None: + kwargs["topic_prefix"] = topic_prefix + + hass_listen_state_mock = mocker.patch.object(Hass, "listen_state") + mqtt_listen_event_mock = mocker.patch.object(Mqtt, "listen_event") + z2m_integration = Z2MIntegration(fake_controller, kwargs) + + with wrap_exetuction(error_expected=expected_id is None, exception=ValueError): + await z2m_integration.listen_changes("controller_id") + + if expected_id is None: + return + + if expected_id == "ha": + hass_listen_state_mock.assert_called_once_with( + fake_controller, + z2m_integration.state_callback, + "controller_id", + ) + elif expected_id == "mqtt": + mqtt_listen_event_mock.assert_called_once_with( + fake_controller, + z2m_integration.event_callback, + topic=f"{topic_prefix or 'zigbee2mqtt'}/controller_id", + namespace="mqtt", + ) + else: + assert False, "expected_id cannot be other than 'ha' or 'mqtt'"