Activate thread integration if thread border routers are present (#88551)
parent
4e32b65694
commit
ce1ef1d720
|
@ -1,6 +1,7 @@
|
||||||
"""Config flow for the Thread integration."""
|
"""Config flow for the Thread integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from homeassistant.components import zeroconf
|
||||||
from homeassistant.config_entries import ConfigFlow
|
from homeassistant.config_entries import ConfigFlow
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
|
|
||||||
|
@ -12,8 +13,16 @@ class ThreadConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||||
|
|
||||||
VERSION = 1
|
VERSION = 1
|
||||||
|
|
||||||
|
async def async_step_zeroconf(
|
||||||
|
self, discovery_info: zeroconf.ZeroconfServiceInfo
|
||||||
|
) -> FlowResult:
|
||||||
|
"""Set up because the user has border routers."""
|
||||||
|
await self._async_handle_discovery_without_unique_id()
|
||||||
|
return self.async_create_entry(title="Thread", data={})
|
||||||
|
|
||||||
async def async_step_import(
|
async def async_step_import(
|
||||||
self, import_data: dict[str, str] | None = None
|
self, import_data: dict[str, str] | None = None
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Set up by import from async_setup."""
|
"""Set up by import from async_setup."""
|
||||||
|
await self._async_handle_discovery_without_unique_id()
|
||||||
return self.async_create_entry(title="Thread", data={})
|
return self.async_create_entry(title="Thread", data={})
|
||||||
|
|
|
@ -7,5 +7,6 @@
|
||||||
"documentation": "https://www.home-assistant.io/integrations/thread",
|
"documentation": "https://www.home-assistant.io/integrations/thread",
|
||||||
"integration_type": "service",
|
"integration_type": "service",
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"requirements": ["python-otbr-api==1.0.3"]
|
"requirements": ["python-otbr-api==1.0.3"],
|
||||||
|
"zeroconf": ["_meshcop._udp.local."]
|
||||||
}
|
}
|
||||||
|
|
|
@ -522,6 +522,11 @@ ZEROCONF = {
|
||||||
"domain": "apple_tv",
|
"domain": "apple_tv",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
"_meshcop._udp.local.": [
|
||||||
|
{
|
||||||
|
"domain": "thread",
|
||||||
|
},
|
||||||
|
],
|
||||||
"_miio._udp.local.": [
|
"_miio._udp.local.": [
|
||||||
{
|
{
|
||||||
"domain": "xiaomi_aqara",
|
"domain": "xiaomi_aqara",
|
||||||
|
|
|
@ -1,10 +1,34 @@
|
||||||
"""Test the Thread config flow."""
|
"""Test the Thread config flow."""
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from homeassistant.components import thread
|
from homeassistant.components import thread, zeroconf
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
|
TEST_ZEROCONF_RECORD = zeroconf.ZeroconfServiceInfo(
|
||||||
|
host="127.0.0.1",
|
||||||
|
hostname="HomeAssistant OpenThreadBorderRouter #0BBF",
|
||||||
|
name="HomeAssistant OpenThreadBorderRouter #0BBF._meshcop._udp.local.",
|
||||||
|
addresses=["127.0.0.1"],
|
||||||
|
port=8080,
|
||||||
|
properties={
|
||||||
|
"rv": "1",
|
||||||
|
"vn": "HomeAssistant",
|
||||||
|
"mn": "OpenThreadBorderRouter",
|
||||||
|
"nn": "OpenThread HC",
|
||||||
|
"xp": "\xe6\x0f\xc7\xc1\x86!,\xe5",
|
||||||
|
"tv": "1.3.0",
|
||||||
|
"xa": "\xae\xeb/YKW\x0b\xbf",
|
||||||
|
"sb": "\x00\x00\x01\xb1",
|
||||||
|
"at": "\x00\x00\x00\x00\x00\x01\x00\x00",
|
||||||
|
"pt": "\x8f\x06Q~",
|
||||||
|
"sq": "3",
|
||||||
|
"bb": "\xf0\xbf",
|
||||||
|
"dn": "DefaultDomain",
|
||||||
|
},
|
||||||
|
type="_meshcop._udp.local.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_import(hass: HomeAssistant) -> None:
|
async def test_import(hass: HomeAssistant) -> None:
|
||||||
"""Test the import flow."""
|
"""Test the import flow."""
|
||||||
|
@ -27,3 +51,76 @@ async def test_import(hass: HomeAssistant) -> None:
|
||||||
assert config_entry.options == {}
|
assert config_entry.options == {}
|
||||||
assert config_entry.title == "Thread"
|
assert config_entry.title == "Thread"
|
||||||
assert config_entry.unique_id is None
|
assert config_entry.unique_id is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_import_then_zeroconf(hass: HomeAssistant) -> None:
|
||||||
|
"""Test the import flow."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.thread.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
thread.DOMAIN, context={"source": "import"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.thread.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
thread.DOMAIN, context={"source": "zeroconf"}, data=TEST_ZEROCONF_RECORD
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_zeroconf(hass: HomeAssistant) -> None:
|
||||||
|
"""Test the zeroconf flow."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.thread.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
thread.DOMAIN, context={"source": "zeroconf"}, data=TEST_ZEROCONF_RECORD
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||||
|
assert result["title"] == "Thread"
|
||||||
|
assert result["data"] == {}
|
||||||
|
assert result["options"] == {}
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
config_entry = hass.config_entries.async_entries(thread.DOMAIN)[0]
|
||||||
|
assert config_entry.data == {}
|
||||||
|
assert config_entry.options == {}
|
||||||
|
assert config_entry.title == "Thread"
|
||||||
|
assert config_entry.unique_id is None
|
||||||
|
|
||||||
|
|
||||||
|
async def test_zeroconf_then_import(hass: HomeAssistant) -> None:
|
||||||
|
"""Test the import flow."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.thread.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
thread.DOMAIN, context={"source": "zeroconf"}, data=TEST_ZEROCONF_RECORD
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.thread.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
thread.DOMAIN, context={"source": "import"}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result["type"] == FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 0
|
||||||
|
|
Loading…
Reference in New Issue