From f94329dbbde5cfafffeb7a4d8a7d95094ce65b24 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 23 Apr 2020 19:53:18 -0500 Subject: [PATCH] Handle synology_dsm discovery broadcasting on multiple ip addresses (#34623) --- .../components/synology_dsm/config_flow.py | 9 ++++++- .../synology_dsm/test_config_flow.py | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/synology_dsm/config_flow.py b/homeassistant/components/synology_dsm/config_flow.py index c1e8cf553d9..025b2959026 100644 --- a/homeassistant/components/synology_dsm/config_flow.py +++ b/homeassistant/components/synology_dsm/config_flow.py @@ -133,7 +133,7 @@ class SynologyDSMFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): return await self._show_setup_form(user_input, errors) # Check if already configured - await self.async_set_unique_id(serial) + await self.async_set_unique_id(serial, raise_on_progress=False) self._abort_if_unique_id_configured() config_data = { @@ -162,6 +162,13 @@ class SynologyDSMFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): if self._host_already_configured(parsed_url.hostname): return self.async_abort(reason="already_configured") + if ssdp.ATTR_UPNP_SERIAL in discovery_info: + # Synology can broadcast on multiple IP addresses + await self.async_set_unique_id( + discovery_info[ssdp.ATTR_UPNP_SERIAL].upper() + ) + self._abort_if_unique_id_configured() + self.discovered_conf = { CONF_NAME: friendly_name, CONF_HOST: parsed_url.hostname, diff --git a/tests/components/synology_dsm/test_config_flow.py b/tests/components/synology_dsm/test_config_flow.py index 9a9283256c5..66f752ffaf4 100644 --- a/tests/components/synology_dsm/test_config_flow.py +++ b/tests/components/synology_dsm/test_config_flow.py @@ -321,6 +321,30 @@ async def test_missing_data_after_login( assert result["errors"] == {"base": "missing_data"} +async def test_form_ssdp_already_configured( + hass: HomeAssistantType, service: MagicMock +): + """Test ssdp abort when the serial number is already configured.""" + await setup.async_setup_component(hass, "persistent_notification", {}) + + MockConfigEntry( + domain=DOMAIN, + data={CONF_HOST: HOST, CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD}, + unique_id=SERIAL.upper(), + ).add_to_hass(hass) + + result = await hass.config_entries.flow.async_init( + DOMAIN, + context={"source": SOURCE_SSDP}, + data={ + ssdp.ATTR_SSDP_LOCATION: "http://192.168.1.5:5000", + ssdp.ATTR_UPNP_FRIENDLY_NAME: "mydsm", + ssdp.ATTR_UPNP_SERIAL: SERIAL, + }, + ) + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + + async def test_form_ssdp(hass: HomeAssistantType, service: MagicMock): """Test we can setup from ssdp.""" await setup.async_setup_component(hass, "persistent_notification", {}) @@ -331,6 +355,7 @@ async def test_form_ssdp(hass: HomeAssistantType, service: MagicMock): data={ ssdp.ATTR_SSDP_LOCATION: "http://192.168.1.5:5000", ssdp.ATTR_UPNP_FRIENDLY_NAME: "mydsm", + ssdp.ATTR_UPNP_SERIAL: SERIAL, }, ) assert result["type"] == data_entry_flow.RESULT_TYPE_FORM