mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Fix HEOS discovery could result in multiple config entries (#22903)
* Prevent duplicate entries from discovery * Update reqs files * Prevent duplicate entries from discovery
This commit is contained in:
parent
d577955d1e
commit
38f063a158
@ -19,7 +19,7 @@ from .const import (
|
|||||||
COMMAND_RETRY_ATTEMPTS, COMMAND_RETRY_DELAY, DATA_CONTROLLER,
|
COMMAND_RETRY_ATTEMPTS, COMMAND_RETRY_DELAY, DATA_CONTROLLER,
|
||||||
DATA_SOURCE_MANAGER, DOMAIN, SIGNAL_HEOS_SOURCES_UPDATED)
|
DATA_SOURCE_MANAGER, DOMAIN, SIGNAL_HEOS_SOURCES_UPDATED)
|
||||||
|
|
||||||
REQUIREMENTS = ['pyheos==0.3.0']
|
REQUIREMENTS = ['pyheos==0.3.1']
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema({
|
CONFIG_SCHEMA = vol.Schema({
|
||||||
DOMAIN: vol.Schema({
|
DOMAIN: vol.Schema({
|
||||||
|
@ -23,8 +23,13 @@ class HeosFlowHandler(config_entries.ConfigFlow):
|
|||||||
|
|
||||||
async def async_step_discovery(self, discovery_info):
|
async def async_step_discovery(self, discovery_info):
|
||||||
"""Handle a discovered Heos device."""
|
"""Handle a discovered Heos device."""
|
||||||
|
# Only continue if this is the only active flow
|
||||||
|
flows = self.hass.config_entries.flow.async_progress()
|
||||||
|
heos_flows = [flow for flow in flows if flow['handler'] == DOMAIN]
|
||||||
|
if len(heos_flows) == 1:
|
||||||
return await self.async_step_user(
|
return await self.async_step_user(
|
||||||
{CONF_HOST: discovery_info[CONF_HOST]})
|
{CONF_HOST: discovery_info[CONF_HOST]})
|
||||||
|
return self.async_abort(reason='already_setup')
|
||||||
|
|
||||||
async def async_step_import(self, user_input=None):
|
async def async_step_import(self, user_input=None):
|
||||||
"""Occurs when an entry is setup through config."""
|
"""Occurs when an entry is setup through config."""
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Heos",
|
"name": "Heos",
|
||||||
"documentation": "https://www.home-assistant.io/components/heos",
|
"documentation": "https://www.home-assistant.io/components/heos",
|
||||||
"requirements": [
|
"requirements": [
|
||||||
"pyheos==0.3.0"
|
"pyheos==0.3.1"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"codeowners": [
|
"codeowners": [
|
||||||
|
@ -1064,7 +1064,7 @@ pygtt==1.1.2
|
|||||||
pyhaversion==2.0.3
|
pyhaversion==2.0.3
|
||||||
|
|
||||||
# homeassistant.components.heos
|
# homeassistant.components.heos
|
||||||
pyheos==0.3.0
|
pyheos==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.hikvision
|
# homeassistant.components.hikvision
|
||||||
pyhik==0.2.2
|
pyhik==0.2.2
|
||||||
|
@ -204,7 +204,7 @@ pydeconz==54
|
|||||||
pydispatcher==2.0.5
|
pydispatcher==2.0.5
|
||||||
|
|
||||||
# homeassistant.components.heos
|
# homeassistant.components.heos
|
||||||
pyheos==0.3.0
|
pyheos==0.3.1
|
||||||
|
|
||||||
# homeassistant.components.homematic
|
# homeassistant.components.homematic
|
||||||
pyhomematic==0.1.58
|
pyhomematic==0.1.58
|
||||||
|
@ -103,3 +103,21 @@ def input_sources_fixture() -> Sequence[InputSource]:
|
|||||||
def dispatcher_fixture() -> Dispatcher:
|
def dispatcher_fixture() -> Dispatcher:
|
||||||
"""Create a dispatcher for testing."""
|
"""Create a dispatcher for testing."""
|
||||||
return Dispatcher()
|
return Dispatcher()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="discovery_data")
|
||||||
|
def discovery_data_fixture() -> dict:
|
||||||
|
"""Return mock discovery data for testing."""
|
||||||
|
return {
|
||||||
|
'host': '127.0.0.1',
|
||||||
|
'manufacturer': 'Denon',
|
||||||
|
'model_name': 'HEOS Drive',
|
||||||
|
'model_number': 'DWSA-10 4.0',
|
||||||
|
'name': 'Office',
|
||||||
|
'port': 60006,
|
||||||
|
'serial': None,
|
||||||
|
'ssdp_description':
|
||||||
|
'http://127.0.0.1:60006/upnp/desc/aios_device/aios_device.xml',
|
||||||
|
'udn': 'uuid:e61de70c-2250-1c22-0080-0005cdf512be',
|
||||||
|
'upnp_device_type': 'urn:schemas-denon-com:device:AiosDevice:1'
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ import asyncio
|
|||||||
|
|
||||||
from homeassistant import data_entry_flow
|
from homeassistant import data_entry_flow
|
||||||
from homeassistant.components.heos.config_flow import HeosFlowHandler
|
from homeassistant.components.heos.config_flow import HeosFlowHandler
|
||||||
|
from homeassistant.components.heos.const import DOMAIN
|
||||||
from homeassistant.const import CONF_HOST
|
from homeassistant.const import CONF_HOST
|
||||||
|
|
||||||
|
|
||||||
@ -57,26 +58,41 @@ async def test_create_entry_when_host_valid(hass, controller):
|
|||||||
assert controller.disconnect.call_count == 1
|
assert controller.disconnect.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_create_entry_with_discovery(hass, controller):
|
async def test_create_entry_with_discovery(hass, controller, discovery_data):
|
||||||
"""Test result type is create entry when valid through discovery."""
|
"""Test discovery creates entry."""
|
||||||
flow = HeosFlowHandler()
|
await hass.config_entries.flow.async_init(
|
||||||
flow.hass = hass
|
DOMAIN, context={'source': 'discovery'},
|
||||||
data = {
|
data=discovery_data)
|
||||||
'host': '127.0.0.1',
|
await hass.async_block_till_done()
|
||||||
'manufacturer': 'Denon',
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
'model_name': 'HEOS Drive',
|
assert len(entries) == 1
|
||||||
'model_number': 'DWSA-10 4.0',
|
assert entries[0].data == {CONF_HOST: discovery_data[CONF_HOST]}
|
||||||
'name': 'Office',
|
assert entries[0].title == 'Controller (127.0.0.1)'
|
||||||
'port': 60006,
|
|
||||||
'serial': None,
|
|
||||||
'ssdp_description':
|
async def test_entry_already_exists_discovery(
|
||||||
'http://127.0.0.1:60006/upnp/desc/aios_device/aios_device.xml',
|
hass, controller, discovery_data, config_entry):
|
||||||
'udn': 'uuid:e61de70c-2250-1c22-0080-0005cdf512be',
|
"""Test discovery does not create multiple entries when already setup."""
|
||||||
'upnp_device_type': 'urn:schemas-denon-com:device:AiosDevice:1'
|
config_entry.add_to_hass(hass)
|
||||||
}
|
await hass.config_entries.flow.async_init(
|
||||||
result = await flow.async_step_discovery(data)
|
DOMAIN, context={'source': 'discovery'},
|
||||||
assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
data=discovery_data)
|
||||||
assert result['title'] == 'Controller (127.0.0.1)'
|
await hass.async_block_till_done()
|
||||||
assert result['data'] == {'host': '127.0.0.1'}
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
assert controller.connect.call_count == 1
|
assert len(entries) == 1
|
||||||
assert controller.disconnect.call_count == 1
|
|
||||||
|
|
||||||
|
async def test_multiple_discovery_creates_single_entry(
|
||||||
|
hass, controller, discovery_data):
|
||||||
|
"""Test discovery of multiple devices creates a single entry."""
|
||||||
|
hass.async_create_task(
|
||||||
|
hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={'source': 'discovery'},
|
||||||
|
data={CONF_HOST: discovery_data}))
|
||||||
|
hass.async_create_task(
|
||||||
|
hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={'source': 'discovery'},
|
||||||
|
data={CONF_HOST: discovery_data}))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
|
assert len(entries) == 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user