Hardware integration MVP (#71677)
parent
f166fc009a
commit
2bc093a04d
homeassistant/components
script/hassfest
tests/components
hardware
hassio
|
@ -416,6 +416,8 @@ build.json @home-assistant/supervisor
|
|||
/tests/components/guardian/ @bachya
|
||||
/homeassistant/components/habitica/ @ASMfreaK @leikoilja
|
||||
/tests/components/habitica/ @ASMfreaK @leikoilja
|
||||
/homeassistant/components/hardware/ @home-assistant/core
|
||||
/tests/components/hardware/ @home-assistant/core
|
||||
/homeassistant/components/harmony/ @ehendrix23 @bramkragten @bdraco @mkeesey @Aohzan
|
||||
/tests/components/harmony/ @ehendrix23 @bramkragten @bdraco @mkeesey @Aohzan
|
||||
/homeassistant/components/hassio/ @home-assistant/supervisor
|
||||
|
@ -829,6 +831,8 @@ build.json @home-assistant/supervisor
|
|||
/tests/components/rainmachine/ @bachya
|
||||
/homeassistant/components/random/ @fabaff
|
||||
/tests/components/random/ @fabaff
|
||||
/homeassistant/components/raspberry_pi/ @home-assistant/core
|
||||
/tests/components/raspberry_pi/ @home-assistant/core
|
||||
/homeassistant/components/rdw/ @frenck
|
||||
/tests/components/rdw/ @frenck
|
||||
/homeassistant/components/recollect_waste/ @bachya
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
"""The Hardware integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from . import websocket_api
|
||||
from .const import DOMAIN
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up Hardware."""
|
||||
hass.data[DOMAIN] = {}
|
||||
|
||||
websocket_api.async_setup(hass)
|
||||
|
||||
return True
|
|
@ -0,0 +1,3 @@
|
|||
"""Constants for the Hardware integration."""
|
||||
|
||||
DOMAIN = "hardware"
|
|
@ -0,0 +1,31 @@
|
|||
"""The Hardware integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.integration_platform import (
|
||||
async_process_integration_platforms,
|
||||
)
|
||||
|
||||
from .const import DOMAIN
|
||||
from .models import HardwareProtocol
|
||||
|
||||
|
||||
async def async_process_hardware_platforms(hass: HomeAssistant):
|
||||
"""Start processing hardware platforms."""
|
||||
hass.data[DOMAIN]["hardware_platform"] = {}
|
||||
|
||||
await async_process_integration_platforms(hass, DOMAIN, _register_hardware_platform)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def _register_hardware_platform(
|
||||
hass: HomeAssistant, integration_domain: str, platform: HardwareProtocol
|
||||
):
|
||||
"""Register a hardware platform."""
|
||||
if integration_domain == DOMAIN:
|
||||
return
|
||||
if not hasattr(platform, "async_info"):
|
||||
raise HomeAssistantError(f"Invalid hardware platform {platform}")
|
||||
hass.data[DOMAIN]["hardware_platform"][integration_domain] = platform
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"domain": "hardware",
|
||||
"name": "Hardware",
|
||||
"config_flow": false,
|
||||
"documentation": "https://www.home-assistant.io/integrations/hardware",
|
||||
"codeowners": ["@home-assistant/core"]
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
"""Models for Hardware."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Protocol
|
||||
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
||||
|
||||
@dataclass
|
||||
class BoardInfo:
|
||||
"""Board info type."""
|
||||
|
||||
hassio_board_id: str | None
|
||||
manufacturer: str
|
||||
model: str | None
|
||||
revision: str | None
|
||||
|
||||
|
||||
@dataclass
|
||||
class HardwareInfo:
|
||||
"""Hardware info type."""
|
||||
|
||||
name: str | None
|
||||
board: BoardInfo | None
|
||||
url: str | None
|
||||
|
||||
|
||||
class HardwareProtocol(Protocol):
|
||||
"""Define the format of hardware platforms."""
|
||||
|
||||
@callback
|
||||
def async_info(self, hass: HomeAssistant) -> HardwareInfo:
|
||||
"""Return info."""
|
|
@ -0,0 +1,47 @@
|
|||
"""The Hardware websocket API."""
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
from dataclasses import asdict
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import websocket_api
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .const import DOMAIN
|
||||
from .hardware import async_process_hardware_platforms
|
||||
from .models import HardwareProtocol
|
||||
|
||||
|
||||
@callback
|
||||
def async_setup(hass: HomeAssistant) -> None:
|
||||
"""Set up the hardware websocket API."""
|
||||
websocket_api.async_register_command(hass, ws_info)
|
||||
|
||||
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "hardware/info",
|
||||
}
|
||||
)
|
||||
@websocket_api.async_response
|
||||
async def ws_info(
|
||||
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict
|
||||
) -> None:
|
||||
"""Return hardware info."""
|
||||
hardware_info = []
|
||||
|
||||
if "hardware_platform" not in hass.data[DOMAIN]:
|
||||
await async_process_hardware_platforms(hass)
|
||||
|
||||
hardware_platform: dict[str, HardwareProtocol] = hass.data[DOMAIN][
|
||||
"hardware_platform"
|
||||
]
|
||||
for platform in hardware_platform.values():
|
||||
if hasattr(platform, "async_info"):
|
||||
with contextlib.suppress(HomeAssistantError):
|
||||
hardware_info.append(asdict(platform.async_info(hass)))
|
||||
|
||||
connection.send_result(msg["id"], {"hardware": hardware_info})
|
|
@ -205,6 +205,10 @@ MAP_SERVICE_API = {
|
|||
),
|
||||
}
|
||||
|
||||
HARDWARE_INTEGRATIONS = {
|
||||
"rpi": "raspberry_pi",
|
||||
}
|
||||
|
||||
|
||||
@bind_hass
|
||||
async def async_get_addon_info(hass: HomeAssistant, slug: str) -> dict:
|
||||
|
@ -705,6 +709,29 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
|
|||
# Init add-on ingress panels
|
||||
await async_setup_addon_panel(hass, hassio)
|
||||
|
||||
# Setup hardware integration for the detected board type
|
||||
async def _async_setup_hardware_integration(hass):
|
||||
"""Set up hardaware integration for the detected board type."""
|
||||
if (os_info := get_os_info(hass)) is None:
|
||||
# os info not yet fetched from supervisor, retry later
|
||||
async_track_point_in_utc_time(
|
||||
hass,
|
||||
_async_setup_hardware_integration,
|
||||
utcnow() + HASSIO_UPDATE_INTERVAL,
|
||||
)
|
||||
return
|
||||
if (board := os_info.get("board")) is None:
|
||||
return
|
||||
if (hw_integration := HARDWARE_INTEGRATIONS.get(board)) is None:
|
||||
return
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
hw_integration, context={"source": "system"}
|
||||
)
|
||||
)
|
||||
|
||||
await _async_setup_hardware_integration(hass)
|
||||
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(DOMAIN, context={"source": "system"})
|
||||
)
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
"""The Raspberry Pi integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.components.hassio import get_os_info
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up a Raspberry Pi config entry."""
|
||||
if (os_info := get_os_info(hass)) is None:
|
||||
# The hassio integration has not yet fetched data from the supervisor
|
||||
raise ConfigEntryNotReady
|
||||
|
||||
board: str
|
||||
if (board := os_info.get("board")) is None or not board.startswith("rpi"):
|
||||
# Not running on a Raspberry Pi, Home Assistant may have been migrated
|
||||
hass.async_create_task(hass.config_entries.async_remove(entry.entry_id))
|
||||
return False
|
||||
|
||||
await hass.config_entries.flow.async_init(
|
||||
"rpi_power", context={"source": "onboarding"}
|
||||
)
|
||||
|
||||
return True
|
|
@ -0,0 +1,22 @@
|
|||
"""Config flow for the Raspberry Pi integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.config_entries import ConfigFlow
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
|
||||
class RaspberryPiConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Raspberry Pi."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
async def async_step_system(self, data: dict[str, Any] | None = None) -> FlowResult:
|
||||
"""Handle the initial step."""
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
|
||||
return self.async_create_entry(title="Raspberry Pi", data={})
|
|
@ -0,0 +1,3 @@
|
|||
"""Constants for the Raspberry Pi integration."""
|
||||
|
||||
DOMAIN = "raspberry_pi"
|
|
@ -0,0 +1,54 @@
|
|||
"""The Raspberry Pi hardware platform."""
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.components.hardware.models import BoardInfo, HardwareInfo
|
||||
from homeassistant.components.hassio import get_os_info
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
BOARD_NAMES = {
|
||||
"rpi": "Raspberry Pi",
|
||||
"rpi0": "Raspberry Pi Zero",
|
||||
"rpi0-w": "Raspberry Pi Zero W",
|
||||
"rpi2": "Raspberry Pi 2",
|
||||
"rpi3": "Raspberry Pi 3 (32-bit)",
|
||||
"rpi3-64": "Raspberry Pi 3",
|
||||
"rpi4": "Raspberry Pi 4 (32-bit)",
|
||||
"rpi4-64": "Raspberry Pi 4",
|
||||
}
|
||||
|
||||
MODELS = {
|
||||
"rpi": "1",
|
||||
"rpi0": "zero",
|
||||
"rpi0-w": "zero_w",
|
||||
"rpi2": "2",
|
||||
"rpi3": "3",
|
||||
"rpi3-64": "3",
|
||||
"rpi4": "4",
|
||||
"rpi4-64": "4",
|
||||
}
|
||||
|
||||
|
||||
@callback
|
||||
def async_info(hass: HomeAssistant) -> HardwareInfo:
|
||||
"""Return board info."""
|
||||
if (os_info := get_os_info(hass)) is None:
|
||||
raise HomeAssistantError
|
||||
board: str
|
||||
if (board := os_info.get("board")) is None:
|
||||
raise HomeAssistantError
|
||||
if not board.startswith("rpi"):
|
||||
raise HomeAssistantError
|
||||
|
||||
return HardwareInfo(
|
||||
board=BoardInfo(
|
||||
hassio_board_id=board,
|
||||
manufacturer=DOMAIN,
|
||||
model=MODELS.get(board),
|
||||
revision=None,
|
||||
),
|
||||
name=BOARD_NAMES.get(board, f"Unknown Raspberry Pi model '{board}'"),
|
||||
url=None,
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"domain": "raspberry_pi",
|
||||
"name": "Raspberry Pi",
|
||||
"config_flow": false,
|
||||
"documentation": "https://www.home-assistant.io/integrations/raspberry_pi",
|
||||
"dependencies": ["hardware", "hassio"],
|
||||
"codeowners": ["@home-assistant/core"],
|
||||
"integration_type": "hardware"
|
||||
}
|
|
@ -36,6 +36,8 @@ class RPiPowerFlow(DiscoveryFlowHandler[Awaitable[bool]], domain=DOMAIN):
|
|||
self, data: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Handle a flow initialized by onboarding."""
|
||||
if self._async_current_entries():
|
||||
return self.async_abort(reason="single_instance_allowed")
|
||||
has_devices = await self._discovery_function(self.hass)
|
||||
|
||||
if not has_devices:
|
||||
|
|
|
@ -52,6 +52,7 @@ NO_IOT_CLASS = [
|
|||
"downloader",
|
||||
"ffmpeg",
|
||||
"frontend",
|
||||
"hardware",
|
||||
"history",
|
||||
"homeassistant",
|
||||
"image",
|
||||
|
@ -76,6 +77,7 @@ NO_IOT_CLASS = [
|
|||
"profiler",
|
||||
"proxy",
|
||||
"python_script",
|
||||
"raspberry_pi",
|
||||
"safe_mode",
|
||||
"script",
|
||||
"search",
|
||||
|
@ -153,7 +155,7 @@ MANIFEST_SCHEMA = vol.Schema(
|
|||
{
|
||||
vol.Required("domain"): str,
|
||||
vol.Required("name"): str,
|
||||
vol.Optional("integration_type"): "helper",
|
||||
vol.Optional("integration_type"): vol.In(["hardware", "helper"]),
|
||||
vol.Optional("config_flow"): bool,
|
||||
vol.Optional("mqtt"): [str],
|
||||
vol.Optional("zeroconf"): [
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"""Tests for the Hardware integration."""
|
|
@ -0,0 +1,18 @@
|
|||
"""Test the hardware websocket API."""
|
||||
from homeassistant.components.hardware.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
|
||||
async def test_board_info(hass: HomeAssistant, hass_ws_client) -> None:
|
||||
"""Test we can get the board info."""
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
await client.send_json({"id": 1, "type": "hardware/info"})
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["id"] == 1
|
||||
assert msg["success"]
|
||||
assert msg["result"] == {"hardware": []}
|
|
@ -20,8 +20,19 @@ from tests.common import MockConfigEntry, async_fire_time_changed
|
|||
MOCK_ENVIRON = {"HASSIO": "127.0.0.1", "HASSIO_TOKEN": "abcdefgh"}
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def os_info():
|
||||
"""Mock os/info."""
|
||||
return {
|
||||
"json": {
|
||||
"result": "ok",
|
||||
"data": {"version_latest": "1.0.0", "version": "1.0.0"},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_all(aioclient_mock, request):
|
||||
def mock_all(aioclient_mock, request, os_info):
|
||||
"""Mock all setup requests."""
|
||||
aioclient_mock.post("http://127.0.0.1/homeassistant/options", json={"result": "ok"})
|
||||
aioclient_mock.get("http://127.0.0.1/supervisor/ping", json={"result": "ok"})
|
||||
|
@ -64,7 +75,7 @@ def mock_all(aioclient_mock, request):
|
|||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/os/info",
|
||||
json={"result": "ok", "data": {"version_latest": "1.0.0", "version": "1.0.0"}},
|
||||
**os_info,
|
||||
)
|
||||
aioclient_mock.get(
|
||||
"http://127.0.0.1/supervisor/info",
|
||||
|
@ -701,3 +712,29 @@ async def test_coordinator_updates(hass, caplog):
|
|||
)
|
||||
assert refresh_updates_mock.call_count == 1
|
||||
assert "Error on Supervisor API: Unknown" in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"os_info",
|
||||
[
|
||||
{
|
||||
"json": {
|
||||
"result": "ok",
|
||||
"data": {"version_latest": "1.0.0", "version": "1.0.0", "board": "rpi"},
|
||||
}
|
||||
}
|
||||
],
|
||||
)
|
||||
async def test_setup_hardware_integration(hass, aioclient_mock):
|
||||
"""Test setup initiates hardware integration."""
|
||||
|
||||
with patch.dict(os.environ, MOCK_ENVIRON), patch(
|
||||
"homeassistant.components.raspberry_pi.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result = await async_setup_component(hass, "hassio", {"hassio": {}})
|
||||
assert result
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert aioclient_mock.call_count == 15
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"""Tests for the Raspberry Pi integration."""
|
|
@ -0,0 +1,58 @@
|
|||
"""Test the Raspberry Pi config flow."""
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components.raspberry_pi.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import RESULT_TYPE_ABORT, RESULT_TYPE_CREATE_ENTRY
|
||||
|
||||
from tests.common import MockConfigEntry, MockModule, mock_integration
|
||||
|
||||
|
||||
async def test_config_flow(hass: HomeAssistant) -> None:
|
||||
"""Test the config flow."""
|
||||
mock_integration(hass, MockModule("hassio"))
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.raspberry_pi.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "system"}
|
||||
)
|
||||
|
||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
||||
assert result["title"] == "Raspberry Pi"
|
||||
assert result["data"] == {}
|
||||
assert result["options"] == {}
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
config_entry = hass.config_entries.async_entries(DOMAIN)[0]
|
||||
assert config_entry.data == {}
|
||||
assert config_entry.options == {}
|
||||
assert config_entry.title == "Raspberry Pi"
|
||||
|
||||
|
||||
async def test_config_flow_single_entry(hass: HomeAssistant) -> None:
|
||||
"""Test only a single entry is allowed."""
|
||||
mock_integration(hass, MockModule("hassio"))
|
||||
|
||||
# Setup the config entry
|
||||
config_entry = MockConfigEntry(
|
||||
data={},
|
||||
domain=DOMAIN,
|
||||
options={},
|
||||
title="Raspberry Pi",
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.raspberry_pi.async_setup_entry",
|
||||
return_value=True,
|
||||
) as mock_setup_entry:
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": "system"}
|
||||
)
|
||||
|
||||
assert result["type"] == RESULT_TYPE_ABORT
|
||||
assert result["reason"] == "single_instance_allowed"
|
||||
mock_setup_entry.assert_not_called()
|
|
@ -0,0 +1,57 @@
|
|||
"""Test the Raspberry Pi hardware platform."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.hassio import DATA_OS_INFO
|
||||
from homeassistant.components.raspberry_pi.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import MockModule, mock_integration
|
||||
|
||||
|
||||
async def test_hardware_info(hass: HomeAssistant, hass_ws_client) -> None:
|
||||
"""Test we can get the board info."""
|
||||
mock_integration(hass, MockModule("hassio"))
|
||||
hass.data[DATA_OS_INFO] = {"board": "rpi"}
|
||||
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
await client.send_json({"id": 1, "type": "hardware/info"})
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["id"] == 1
|
||||
assert msg["success"]
|
||||
assert msg["result"] == {
|
||||
"hardware": [
|
||||
{
|
||||
"board": {
|
||||
"hassio_board_id": "rpi",
|
||||
"manufacturer": "raspberry_pi",
|
||||
"model": "1",
|
||||
"revision": None,
|
||||
},
|
||||
"name": "Raspberry Pi",
|
||||
"url": None,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("os_info", [None, {"board": None}, {"board": "other"}])
|
||||
async def test_hardware_info_fail(hass: HomeAssistant, hass_ws_client, os_info) -> None:
|
||||
"""Test async_info raises if os_info is not as expected."""
|
||||
mock_integration(hass, MockModule("hassio"))
|
||||
hass.data[DATA_OS_INFO] = os_info
|
||||
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
await client.send_json({"id": 1, "type": "hardware/info"})
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["id"] == 1
|
||||
assert msg["success"]
|
||||
assert msg["result"] == {"hardware": []}
|
|
@ -0,0 +1,72 @@
|
|||
"""Test the Raspberry Pi integration."""
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.components.raspberry_pi.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry, MockModule, mock_integration
|
||||
|
||||
|
||||
async def test_setup_entry(hass: HomeAssistant) -> None:
|
||||
"""Test setup of a config entry."""
|
||||
mock_integration(hass, MockModule("hassio"))
|
||||
|
||||
# Setup the config entry
|
||||
config_entry = MockConfigEntry(
|
||||
data={},
|
||||
domain=DOMAIN,
|
||||
options={},
|
||||
title="Raspberry Pi",
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
with patch(
|
||||
"homeassistant.components.raspberry_pi.get_os_info",
|
||||
return_value={"board": "rpi"},
|
||||
) as mock_get_os_info:
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert len(mock_get_os_info.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_setup_entry_wrong_board(hass: HomeAssistant) -> None:
|
||||
"""Test setup of a config entry with wrong board type."""
|
||||
mock_integration(hass, MockModule("hassio"))
|
||||
|
||||
# Setup the config entry
|
||||
config_entry = MockConfigEntry(
|
||||
data={},
|
||||
domain=DOMAIN,
|
||||
options={},
|
||||
title="Raspberry Pi",
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
with patch(
|
||||
"homeassistant.components.raspberry_pi.get_os_info",
|
||||
return_value={"board": "generic-x86-64"},
|
||||
) as mock_get_os_info:
|
||||
assert not await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert len(mock_get_os_info.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_setup_entry_wait_hassio(hass: HomeAssistant) -> None:
|
||||
"""Test setup of a config entry when hassio has not fetched os_info."""
|
||||
mock_integration(hass, MockModule("hassio"))
|
||||
|
||||
# Setup the config entry
|
||||
config_entry = MockConfigEntry(
|
||||
data={},
|
||||
domain=DOMAIN,
|
||||
options={},
|
||||
title="Raspberry Pi",
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
with patch(
|
||||
"homeassistant.components.raspberry_pi.get_os_info",
|
||||
return_value=None,
|
||||
) as mock_get_os_info:
|
||||
assert not await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert len(mock_get_os_info.mock_calls) == 1
|
||||
assert config_entry.state == ConfigEntryState.SETUP_RETRY
|
Loading…
Reference in New Issue