Activate thread integration if thread border routers are present (#88551)

pull/88554/head
Jc2k 2023-02-21 16:22:00 +00:00 committed by GitHub
parent 4e32b65694
commit ce1ef1d720
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 114 additions and 2 deletions

View File

@ -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={})

View File

@ -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."]
} }

View File

@ -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",

View File

@ -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