diff --git a/homeassistant/components/dlna_dmr/config_flow.py b/homeassistant/components/dlna_dmr/config_flow.py index bfc5cb27129..2b38cf4e56d 100644 --- a/homeassistant/components/dlna_dmr/config_flow.py +++ b/homeassistant/components/dlna_dmr/config_flow.py @@ -236,6 +236,10 @@ class DlnaDmrFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): ) return self.async_abort(reason="already_in_progress") + # Abort if another config entry has the same location, in case the + # device doesn't have a static and unique UDN (breaking the UPnP spec). + self._async_abort_entries_match({CONF_URL: self._location}) + self.context["title_placeholders"] = {"name": self._name} return await self.async_step_confirm() @@ -478,6 +482,11 @@ def _is_ignored_device(discovery_info: Mapping[str, Any]) -> bool: if manufacturer.startswith("xbmc") or model == "kodi": # kodi return True + if "philips" in manufacturer and "tv" in model: + # philips_js + # These TVs don't have a stable UDN, so also get discovered as a new + # device every time they are turned on. + return True if manufacturer.startswith("samsung") and "tv" in model: # samsungtv return True diff --git a/tests/components/dlna_dmr/test_config_flow.py b/tests/components/dlna_dmr/test_config_flow.py index e2d82d5b559..6ff718290b2 100644 --- a/tests/components/dlna_dmr/test_config_flow.py +++ b/tests/components/dlna_dmr/test_config_flow.py @@ -558,6 +558,21 @@ async def test_ssdp_flow_existing( assert config_entry_mock.data[CONF_URL] == NEW_DEVICE_LOCATION +async def test_ssdp_flow_duplicate_location( + hass: HomeAssistant, config_entry_mock: MockConfigEntry +) -> None: + """Test that discovery of device with URL matching existing entry gets aborted.""" + config_entry_mock.add_to_hass(hass) + result = await hass.config_entries.flow.async_init( + DLNA_DOMAIN, + context={"source": config_entries.SOURCE_SSDP}, + data=MOCK_DISCOVERY, + ) + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result["reason"] == "already_configured" + assert config_entry_mock.data[CONF_URL] == MOCK_DEVICE_LOCATION + + async def test_ssdp_flow_upnp_udn( hass: HomeAssistant, config_entry_mock: MockConfigEntry ) -> None: @@ -635,6 +650,7 @@ async def test_ssdp_ignore_device(hass: HomeAssistant) -> None: ("XBMC Foundation", "Kodi"), ("Samsung", "Smart TV"), ("LG Electronics.", "LG TV"), + ("Royal Philips Electronics", "Philips TV DMR"), ]: discovery = dict(MOCK_DISCOVERY) discovery[ssdp.ATTR_UPNP_MANUFACTURER] = manufacturer