From 892be99ca0140cc5d7662d89329152b63653d775 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Mon, 28 Nov 2022 19:55:07 +0100 Subject: [PATCH] Check if Multi-PAN addon is using the HA Yellow's radio (#82853) --- .../homeassistant_yellow/__init__.py | 39 +++++++++----- .../components/homeassistant_yellow/const.py | 3 +- .../homeassistant_yellow/test_init.py | 52 +++++++++++++++++++ 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/homeassistant_yellow/__init__.py b/homeassistant/components/homeassistant_yellow/__init__.py index a7e351535aa..1b61fe7d47f 100644 --- a/homeassistant/components/homeassistant_yellow/__init__.py +++ b/homeassistant/components/homeassistant_yellow/__init__.py @@ -18,23 +18,13 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady -from .const import ZHA_HW_DISCOVERY_DATA +from .const import RADIO_DEVICE, ZHA_HW_DISCOVERY_DATA _LOGGER = logging.getLogger(__name__) -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Set up a Home Assistant Yellow config entry.""" - if (os_info := get_os_info(hass)) is None: - # The hassio integration has not yet fetched data from the supervisor - raise ConfigEntryNotReady - - board: str | None - if (board := os_info.get("board")) is None or not board == "yellow": - # Not running on a Home Assistant Yellow, Home Assistant may have been migrated - hass.async_create_task(hass.config_entries.async_remove(entry.entry_id)) - return False - +async def _multi_pan_addon_info(hass, entry: ConfigEntry) -> AddonInfo | None: + """Return AddonInfo if the multi-PAN addon is enabled for the Yellow's radio.""" addon_manager: AddonManager = get_addon_manager(hass) try: addon_info: AddonInfo = await addon_manager.async_get_addon_info() @@ -54,6 +44,29 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: raise ConfigEntryNotReady if addon_info.state == AddonState.NOT_INSTALLED: + return None + + if addon_info.options["device"] != RADIO_DEVICE: + return None + + return addon_info + + +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Set up a Home Assistant Yellow config entry.""" + if (os_info := get_os_info(hass)) is None: + # The hassio integration has not yet fetched data from the supervisor + raise ConfigEntryNotReady + + board: str | None + if (board := os_info.get("board")) is None or not board == "yellow": + # Not running on a Home Assistant Yellow, Home Assistant may have been migrated + hass.async_create_task(hass.config_entries.async_remove(entry.entry_id)) + return False + + addon_info = await _multi_pan_addon_info(hass, entry) + + if not addon_info: hw_discovery_data = ZHA_HW_DISCOVERY_DATA else: hw_discovery_data = { diff --git a/homeassistant/components/homeassistant_yellow/const.py b/homeassistant/components/homeassistant_yellow/const.py index 5d693d819b6..8f1f9a4c2b8 100644 --- a/homeassistant/components/homeassistant_yellow/const.py +++ b/homeassistant/components/homeassistant_yellow/const.py @@ -2,10 +2,11 @@ DOMAIN = "homeassistant_yellow" +RADIO_DEVICE = "/dev/ttyAMA1" ZHA_HW_DISCOVERY_DATA = { "name": "Yellow", "port": { - "path": "/dev/ttyAMA1", + "path": RADIO_DEVICE, "baudrate": 115200, "flow_control": "hardware", }, diff --git a/tests/components/homeassistant_yellow/test_init.py b/tests/components/homeassistant_yellow/test_init.py index 6df8977b35d..85b027e82ed 100644 --- a/tests/components/homeassistant_yellow/test_init.py +++ b/tests/components/homeassistant_yellow/test_init.py @@ -110,6 +110,8 @@ async def test_setup_zha_multipan( """Test zha gets the right config.""" mock_integration(hass, MockModule("hassio")) + addon_info.return_value["options"]["device"] = "/dev/ttyAMA1" + # Setup the config entry config_entry = MockConfigEntry( data={}, @@ -152,6 +154,56 @@ async def test_setup_zha_multipan( assert config_entry.title == "Yellow Multi-PAN" +async def test_setup_zha_multipan_other_device( + hass: HomeAssistant, addon_info, addon_running +) -> None: + """Test zha gets the right config.""" + mock_integration(hass, MockModule("hassio")) + + addon_info.return_value["options"]["device"] = "/dev/not_yellow_radio" + + # Setup the config entry + config_entry = MockConfigEntry( + data={}, + domain=DOMAIN, + options={}, + title="Home Assistant Yellow", + ) + config_entry.add_to_hass(hass) + with patch( + "homeassistant.components.homeassistant_yellow.get_os_info", + return_value={"board": "yellow"}, + ) as mock_get_os_info, patch( + "homeassistant.components.onboarding.async_is_onboarded", return_value=False + ): + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + assert len(mock_get_os_info.mock_calls) == 1 + + # Finish setting up ZHA + zha_flows = hass.config_entries.flow.async_progress_by_handler("zha") + assert len(zha_flows) == 1 + assert zha_flows[0]["step_id"] == "choose_formation_strategy" + + await hass.config_entries.flow.async_configure( + zha_flows[0]["flow_id"], + user_input={"next_step_id": zha.config_flow.FORMATION_REUSE_SETTINGS}, + ) + await hass.async_block_till_done() + + config_entry = hass.config_entries.async_entries("zha")[0] + assert config_entry.data == { + "device": { + "baudrate": 115200, + "flow_control": "hardware", + "path": "/dev/ttyAMA1", + }, + "radio_type": "ezsp", + } + assert config_entry.options == {} + assert config_entry.title == "Yellow" + + async def test_setup_entry_wrong_board(hass: HomeAssistant) -> None: """Test setup of a config entry with wrong board type.""" mock_integration(hass, MockModule("hassio"))