From c1cf07768b3d0ac7655bd673bca26eea8e2f7390 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 11 May 2021 17:06:55 -0500 Subject: [PATCH] Add dhcp discovery support to isy994 (#50488) - SSDP may not be enabled by default --- .../components/isy994/config_flow.py | 17 +++++++ homeassistant/components/isy994/manifest.json | 3 ++ homeassistant/generated/dhcp.py | 5 ++ tests/components/isy994/test_config_flow.py | 46 ++++++++++++++++++- 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/isy994/config_flow.py b/homeassistant/components/isy994/config_flow.py index ce919003622..502008ff0ab 100644 --- a/homeassistant/components/isy994/config_flow.py +++ b/homeassistant/components/isy994/config_flow.py @@ -8,6 +8,7 @@ import voluptuous as vol from homeassistant import config_entries, core, exceptions from homeassistant.components import ssdp +from homeassistant.components.dhcp import HOSTNAME, IP_ADDRESS, MAC_ADDRESS from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import callback @@ -149,6 +150,22 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Handle import.""" return await self.async_step_user(user_input) + async def async_step_dhcp(self, discovery_info): + """Handle a discovered isy994 via dhcp.""" + friendly_name = discovery_info[HOSTNAME] + url = f"http://{discovery_info[IP_ADDRESS]}" + mac = discovery_info[MAC_ADDRESS] + await self.async_set_unique_id(mac) + self._abort_if_unique_id_configured() + + self.discovered_conf = { + CONF_NAME: friendly_name, + CONF_HOST: url, + } + + self.context["title_placeholders"] = self.discovered_conf + return await self.async_step_user() + async def async_step_ssdp(self, discovery_info): """Handle a discovered isy994.""" friendly_name = discovery_info[ssdp.ATTR_UPNP_FRIENDLY_NAME] diff --git a/homeassistant/components/isy994/manifest.json b/homeassistant/components/isy994/manifest.json index 8758a9d828b..a2326cbae5f 100644 --- a/homeassistant/components/isy994/manifest.json +++ b/homeassistant/components/isy994/manifest.json @@ -11,5 +11,8 @@ "deviceType": "urn:udi-com:device:X_Insteon_Lighting_Device:1" } ], + "dhcp": [ + {"hostname":"isy*", "macaddress":"0021B9*"} + ], "iot_class": "local_push" } diff --git a/homeassistant/generated/dhcp.py b/homeassistant/generated/dhcp.py index 368d0189ab4..dc32b9c4c99 100644 --- a/homeassistant/generated/dhcp.py +++ b/homeassistant/generated/dhcp.py @@ -81,6 +81,11 @@ DHCP = [ "hostname": "hunter*", "macaddress": "002674*" }, + { + "domain": "isy994", + "hostname": "isy*", + "macaddress": "0021B9*" + }, { "domain": "lyric", "hostname": "lyric-*", diff --git a/tests/components/isy994/test_config_flow.py b/tests/components/isy994/test_config_flow.py index 1107e184e9b..bf08e6526ba 100644 --- a/tests/components/isy994/test_config_flow.py +++ b/tests/components/isy994/test_config_flow.py @@ -3,7 +3,7 @@ from unittest.mock import patch from homeassistant import config_entries, data_entry_flow, setup -from homeassistant.components import ssdp +from homeassistant.components import dhcp, ssdp from homeassistant.components.isy994.config_flow import CannotConnect from homeassistant.components.isy994.const import ( CONF_IGNORE_STRING, @@ -15,7 +15,7 @@ from homeassistant.components.isy994.const import ( ISY_URL_POSTFIX, UDN_UUID_PREFIX, ) -from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_SSDP +from homeassistant.config_entries import SOURCE_DHCP, SOURCE_IMPORT, SOURCE_SSDP from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant @@ -319,3 +319,45 @@ async def test_form_ssdp(hass: HomeAssistant): assert result2["data"] == MOCK_USER_INPUT assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1 + + +async def test_form_dhcp(hass: HomeAssistant): + """Test we can setup from dhcp.""" + await setup.async_setup_component(hass, "persistent_notification", {}) + + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_DHCP}, + data={ + dhcp.IP_ADDRESS: "1.2.3.4", + dhcp.HOSTNAME: "isy994-ems", + dhcp.MAC_ADDRESS: MOCK_UUID, + }, + ) + assert result["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result["step_id"] == "user" + assert result["errors"] == {} + + with patch(PATCH_CONFIGURATION) as mock_config_class, patch( + PATCH_CONNECTION + ) as mock_connection_class, patch( + PATCH_ASYNC_SETUP, return_value=True + ) as mock_setup, patch( + PATCH_ASYNC_SETUP_ENTRY, + return_value=True, + ) as mock_setup_entry: + isy_conn = mock_connection_class.return_value + isy_conn.get_config.return_value = None + mock_config_class.return_value = MOCK_VALIDATED_RESPONSE + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], + MOCK_USER_INPUT, + ) + await hass.async_block_till_done() + + assert result2["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert result2["title"] == f"{MOCK_DEVICE_NAME} ({MOCK_HOSTNAME})" + assert result2["result"].unique_id == MOCK_UUID + assert result2["data"] == MOCK_USER_INPUT + assert len(mock_setup.mock_calls) == 1 + assert len(mock_setup_entry.mock_calls) == 1