Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/thermopro/ @bdraco
/tests/components/thermopro/ @bdraco
/homeassistant/components/thethingsnetwork/ @fabaff
/homeassistant/components/thread/ @home-assistant/core
/tests/components/thread/ @home-assistant/core
/homeassistant/components/threshold/ @fabaff
/tests/components/threshold/ @fabaff
/homeassistant/components/tibber/ @danielhiversen
Expand Down
1 change: 1 addition & 0 deletions homeassistant/components/otbr/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"domain": "otbr",
"name": "Thread",
"config_flow": true,
"dependencies": ["thread"],
"documentation": "https://www.home-assistant.io/integrations/otbr",
"requirements": ["python-otbr-api==1.0.1"],
"after_dependencies": ["hassio"],
Expand Down
30 changes: 30 additions & 0 deletions homeassistant/components/thread/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""The Thread integration."""
from __future__ import annotations

from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType

from .const import DOMAIN


async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Thread integration."""
if not hass.config_entries.async_entries(DOMAIN):
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}
)
)
return True


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up a config entry."""

return True


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
return True
19 changes: 19 additions & 0 deletions homeassistant/components/thread/config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""Config flow for the Thread integration."""
from __future__ import annotations

from homeassistant.config_entries import ConfigFlow
from homeassistant.data_entry_flow import FlowResult

from .const import DOMAIN


class ThreadConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Thread."""

VERSION = 1

async def async_step_import(
self, import_data: dict[str, str] | None = None
) -> FlowResult:
"""Set up by import from async_setup."""
return self.async_create_entry(title="Thread", data={})
3 changes: 3 additions & 0 deletions homeassistant/components/thread/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"""Constants for the Thread integration."""

DOMAIN = "thread"
9 changes: 9 additions & 0 deletions homeassistant/components/thread/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"domain": "thread",
"name": "Thread",
"codeowners": ["@home-assistant/core"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/thread",
"integration_type": "service",
"iot_class": "local_polling"
}
1 change: 1 addition & 0 deletions homeassistant/generated/config_flows.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@
"tesla_wall_connector",
"thermobeacon",
"thermopro",
"thread",
"tibber",
"tile",
"tilt_ble",
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/generated/integrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -5565,6 +5565,12 @@
"config_flow": false,
"iot_class": "local_polling"
},
"thread": {
"name": "Thread",
"integration_type": "service",
"config_flow": true,
"iot_class": "local_polling"
},
"tibber": {
"name": "Tibber",
"integration_type": "hub",
Expand Down
1 change: 1 addition & 0 deletions tests/components/thread/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tests for the Thread integration."""
22 changes: 22 additions & 0 deletions tests/components/thread/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Test fixtures for the Thread integration."""

import pytest

from homeassistant.components import thread

from tests.common import MockConfigEntry

CONFIG_ENTRY_DATA = {}


@pytest.fixture(name="thread_config_entry")
async def thread_config_entry_fixture(hass):
"""Mock Thread config entry."""
config_entry = MockConfigEntry(
data=CONFIG_ENTRY_DATA,
domain=thread.DOMAIN,
options={},
title="Thread",
)
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
29 changes: 29 additions & 0 deletions tests/components/thread/test_config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Test the Thread config flow."""
from unittest.mock import patch

from homeassistant.components import thread
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType


async def test_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": "import"}
)

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
29 changes: 29 additions & 0 deletions tests/components/thread/test_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Test the Thread integration."""

from homeassistant.components import thread
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component


async def test_create_entry(hass: HomeAssistant):
"""Test an entry is created by async_setup."""
assert len(hass.config_entries.async_entries(thread.DOMAIN)) == 0
assert await async_setup_component(hass, thread.DOMAIN, {})
await hass.async_block_till_done()

assert len(hass.config_entries.async_entries(thread.DOMAIN)) == 1


async def test_remove_entry(hass: HomeAssistant, thread_config_entry):
"""Test removing the entry."""

config_entry = hass.config_entries.async_entries(thread.DOMAIN)[0]
assert await hass.config_entries.async_remove(config_entry.entry_id) == {
"require_restart": False
}


async def test_import_once(hass: HomeAssistant, thread_config_entry) -> None:
"""Test only a single entry is created."""
await hass.async_block_till_done()
assert len(hass.config_entries.async_entries(thread.DOMAIN)) == 1