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
13 changes: 11 additions & 2 deletions homeassistant/components/onboarding/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
"domain": "onboarding",
"name": "Home Assistant Onboarding",
"documentation": "https://www.home-assistant.io/integrations/onboarding",
"dependencies": ["auth", "http", "person"],
"codeowners": ["@home-assistant/core"],
"after_dependencies": [
"hassio"
],
"dependencies": [
"auth",
"http",
"person"
],
"codeowners": [
"@home-assistant/core"
],
"quality_scale": "internal"
}
8 changes: 8 additions & 0 deletions homeassistant/components/onboarding/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,14 @@ async def post(self, request):
"met", context={"source": "onboarding"}
)

if (
hass.components.hassio.is_hassio()
and "raspberrypi" in hass.components.hassio.get_core_info()["machine"]
):
await hass.config_entries.flow.async_init(
"rpi_power", context={"source": "onboarding"}
)

return self.json({})


Expand Down
33 changes: 26 additions & 7 deletions homeassistant/components/rpi_power/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"""Config flow for Raspberry Pi Power Supply Checker."""
from typing import Any, Dict, Optional

from rpi_bad_power import new_under_voltage

from homeassistant import config_entries
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_entry_flow
from homeassistant.helpers.config_entry_flow import DiscoveryFlowHandler

from .const import DOMAIN

Expand All @@ -14,9 +16,26 @@ async def _async_supported(hass: HomeAssistant) -> bool:
return under_voltage is not None


config_entry_flow.register_discovery_flow(
DOMAIN,
"Raspberry Pi Power Supply Checker",
_async_supported,
config_entries.CONN_CLASS_LOCAL_POLL,
)
class RPiPowerFlow(DiscoveryFlowHandler, domain=DOMAIN):
"""Discovery flow handler."""

VERSION = 1

def __init__(self) -> None:
"""Set up config flow."""
super().__init__(
DOMAIN,
"Raspberry Pi Power Supply Checker",
_async_supported,
config_entries.CONN_CLASS_LOCAL_POLL,
)

async def async_step_onboarding(
self, data: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
"""Handle a flow initialized by onboarding."""
has_devices = await self._discovery_function(self.hass)

if not has_devices:
return self.async_abort(reason="no_devices_found")
return self.async_create_entry(title=self._title, data={})
100 changes: 100 additions & 0 deletions tests/components/onboarding/test_views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Test the onboarding views."""
import asyncio
import os

import pytest

Expand Down Expand Up @@ -29,6 +30,57 @@ def auth_active(hass):
)


@pytest.fixture(name="rpi")
async def rpi_fixture(hass, aioclient_mock, mock_supervisor):
"""Mock core info with rpi."""
aioclient_mock.get(
"http://127.0.0.1/core/info",
json={
"result": "ok",
"data": {"version_latest": "1.0.0", "machine": "raspberrypi3"},
},
)
assert await async_setup_component(hass, "hassio", {})
await hass.async_block_till_done()


@pytest.fixture(name="no_rpi")
async def no_rpi_fixture(hass, aioclient_mock, mock_supervisor):
"""Mock core info with rpi."""
aioclient_mock.get(
"http://127.0.0.1/core/info",
json={
"result": "ok",
"data": {"version_latest": "1.0.0", "machine": "odroid-n2"},
},
)
assert await async_setup_component(hass, "hassio", {})
await hass.async_block_till_done()


@pytest.fixture(name="mock_supervisor")
async def mock_supervisor_fixture(hass, aioclient_mock):
"""Mock supervisor."""
aioclient_mock.post("http://127.0.0.1/homeassistant/options", json={"result": "ok"})
aioclient_mock.post("http://127.0.0.1/supervisor/options", json={"result": "ok"})
with patch.dict(os.environ, {"HASSIO": "127.0.0.1"}), patch(
"homeassistant.components.hassio.HassIO.is_connected",
return_value=True,
), patch(
"homeassistant.components.hassio.HassIO.get_info",
return_value={},
), patch(
"homeassistant.components.hassio.HassIO.get_host_info",
return_value={},
), patch(
"homeassistant.components.hassio.HassIO.get_ingress_panels",
return_value={"panels": {}},
), patch.dict(
os.environ, {"HASSIO_TOKEN": "123456"}
):
yield


async def test_onboarding_progress(hass, hass_storage, aiohttp_client):
"""Test fetching progress."""
mock_storage(hass_storage, {"done": ["hello"]})
Expand Down Expand Up @@ -277,3 +329,51 @@ async def test_onboarding_core_sets_up_met(hass, hass_storage, hass_client):

await hass.async_block_till_done()
assert len(hass.states.async_entity_ids("weather")) == 1


async def test_onboarding_core_sets_up_rpi_power(
hass, hass_storage, hass_client, aioclient_mock, rpi
):
"""Test that the core step sets up rpi_power on RPi."""
mock_storage(hass_storage, {"done": [const.STEP_USER]})
await async_setup_component(hass, "persistent_notification", {})

assert await async_setup_component(hass, "onboarding", {})

client = await hass_client()

with patch(
"homeassistant.components.rpi_power.config_flow.new_under_voltage"
), patch("homeassistant.components.rpi_power.binary_sensor.new_under_voltage"):
resp = await client.post("/api/onboarding/core_config")

assert resp.status == 200

await hass.async_block_till_done()

rpi_power_state = hass.states.get("binary_sensor.rpi_power_status")
assert rpi_power_state


async def test_onboarding_core_no_rpi_power(
hass, hass_storage, hass_client, aioclient_mock, no_rpi
):
"""Test that the core step do not set up rpi_power on non RPi."""
mock_storage(hass_storage, {"done": [const.STEP_USER]})
await async_setup_component(hass, "persistent_notification", {})

assert await async_setup_component(hass, "onboarding", {})

client = await hass_client()

with patch(
"homeassistant.components.rpi_power.config_flow.new_under_voltage"
), patch("homeassistant.components.rpi_power.binary_sensor.new_under_voltage"):
resp = await client.post("/api/onboarding/core_config")

assert resp.status == 200

await hass.async_block_till_done()

rpi_power_state = hass.states.get("binary_sensor.rpi_power_status")
assert not rpi_power_state
25 changes: 23 additions & 2 deletions tests/components/rpi_power/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
MODULE = "homeassistant.components.rpi_power.config_flow.new_under_voltage"


async def test_setup(hass: HomeAssistant):
async def test_setup(hass: HomeAssistant) -> None:
"""Test setting up manually."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
Expand All @@ -29,7 +29,7 @@ async def test_setup(hass: HomeAssistant):
assert result["type"] == RESULT_TYPE_CREATE_ENTRY


async def test_not_supported(hass: HomeAssistant):
async def test_not_supported(hass: HomeAssistant) -> None:
"""Test setting up on not supported system."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
Expand All @@ -40,3 +40,24 @@ async def test_not_supported(hass: HomeAssistant):
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "no_devices_found"


async def test_onboarding(hass: HomeAssistant) -> None:
"""Test setting up via onboarding."""
with patch(MODULE, return_value=MagicMock()):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": "onboarding"},
)
assert result["type"] == RESULT_TYPE_CREATE_ENTRY


async def test_onboarding_not_supported(hass: HomeAssistant) -> None:
"""Test setting up via onboarding with unsupported system."""
with patch(MODULE, return_value=None):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": "onboarding"},
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "no_devices_found"