-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
Tilt Pi integration #139726
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tilt Pi integration #139726
Changes from 1 commit
c4d2c1f
f1b7d61
f2bc36f
f13ecb3
679bd80
a9f80bf
e5c775a
b6ad9c1
844a1d4
84ed1b8
58b8c38
78cde3d
f2c70f5
44c3c2c
1eb10e4
dff4984
9503c5e
beb38e3
bed25e0
cd0a178
d558469
a86ea49
9a39f48
1965042
5c7b37d
3e91a19
c197354
e91eb08
a2b49f6
65d572b
9f1a0c4
02a57ca
7e9499e
806774b
6589045
a3a6054
d78b02d
5c47da2
d8eeae9
1c1d93f
05700b9
735d7f9
252626d
2a487ce
9b738c0
a725e78
834dcfd
3b92fa8
5a3e545
22bdffa
158056c
a0e0d25
0cebd49
8aec831
28da7aa
ad2c399
b7033d5
cb84f15
c181f1c
33c8855
6322d16
30882d2
ddcf2af
de5a6df
2e82b58
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,66 @@ | ||
"""Config flow for the Tilt Pi integration.""" | ||
"""Config flow for Tilt Pi integration.""" | ||
|
||
import my_pypi_dependency | ||
from __future__ import annotations | ||
|
||
from homeassistant.core import HomeAssistant | ||
from homeassistant.helpers import config_entry_flow | ||
from typing import Any | ||
|
||
import aiohttp | ||
import voluptuous as vol | ||
|
||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult | ||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT | ||
from homeassistant.helpers.aiohttp_client import async_get_clientsession | ||
|
||
from .const import DOMAIN | ||
|
||
USER_DATA_SCHEMA = vol.Schema( | ||
{ | ||
vol.Required(CONF_NAME): str, | ||
vol.Required(CONF_HOST): str, | ||
vol.Optional(CONF_PORT, default=1880): int, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can someone change the port? Can it do SSL? If we usually access the tilt pi thing via a web interface and need that url, consider just asking for the URL. Check |
||
} | ||
) | ||
|
||
|
||
class TiltPiConfigFlow(ConfigFlow, domain=DOMAIN): | ||
"""Handle a config flow for Tilt Pi.""" | ||
|
||
VERSION = 1 | ||
michaelheyman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
async def async_step_user( | ||
self, user_input: dict[str, Any] | None = None | ||
) -> ConfigFlowResult: | ||
"""Handle the initial configuration step.""" | ||
|
||
if user_input is None: | ||
return self.async_show_form( | ||
step_id="user", | ||
data_schema=USER_DATA_SCHEMA, | ||
) | ||
|
||
# Check if device is already configured | ||
await self.async_set_unique_id(f"tiltpi_{user_input[CONF_HOST]}") | ||
self._abort_if_unique_id_configured() | ||
|
||
async def _async_has_devices(hass: HomeAssistant) -> bool: | ||
"""Return if there are devices that can be discovered.""" | ||
# TODO Check if there are any devices that can be discovered in the network. | ||
devices = await hass.async_add_executor_job(my_pypi_dependency.discover) | ||
return len(devices) > 0 | ||
errors = {} | ||
|
||
try: | ||
session = async_get_clientsession(self.hass) | ||
async with session.get( | ||
f"http://{user_input[CONF_HOST]}:{user_input[CONF_PORT]}/macid/all", | ||
timeout=aiohttp.ClientTimeout(10), | ||
) as resp: | ||
resp.raise_for_status() | ||
await resp.json() | ||
|
||
config_entry_flow.register_discovery_flow(DOMAIN, "Tilt Pi", _async_has_devices) | ||
return self.async_create_entry( | ||
title=user_input[CONF_NAME], | ||
data=user_input, | ||
) | ||
except (TimeoutError, aiohttp.ClientError): | ||
errors["base"] = "cannot_connect" | ||
return self.async_show_form( | ||
step_id="user", | ||
data_schema=USER_DATA_SCHEMA, | ||
errors=errors, | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
"""Common fixtures for the Tilt Pi tests.""" | ||
|
||
import pytest | ||
|
||
|
||
@pytest.fixture | ||
def tiltpi_api_all_response() -> list[dict[str, any]]: | ||
"""Fixture for TiltPi API response.""" | ||
return [ | ||
{ | ||
"mac": "00:1A:2B:3C:4D:5E", | ||
"Color": "red", | ||
"Temp": "68.5", | ||
"SG": "1.052", | ||
} | ||
] |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm missing a test where we try to set up the same entry twice and then abort because we already have it |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
"""Test the Tilt config flow.""" | ||
|
||
from typing import Final | ||
|
||
import aiohttp | ||
|
||
from homeassistant import config_entries | ||
from homeassistant.components.tilt_pi.const import DOMAIN | ||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT | ||
from homeassistant.core import HomeAssistant | ||
from homeassistant.data_entry_flow import FlowResultType | ||
|
||
from tests.test_util.aiohttp import AiohttpClientMocker | ||
|
||
TEST_TILTPI_DATA: Final = { | ||
CONF_NAME: "Test TiltPi", | ||
CONF_HOST: "192.168.1.100", | ||
CONF_PORT: 1880, | ||
} | ||
|
||
|
||
async def test_async_step_user_gets_form(hass: HomeAssistant) -> None: | ||
"""Test that we can view the form when there is no previous user input.""" | ||
result = await hass.config_entries.flow.async_init( | ||
DOMAIN, | ||
context={"source": config_entries.SOURCE_USER}, | ||
) | ||
assert result["type"] is FlowResultType.FORM | ||
assert result["errors"] is None | ||
|
||
|
||
async def test_async_step_user_creates_entry( | ||
hass: HomeAssistant, | ||
aioclient_mock: AiohttpClientMocker, | ||
tiltpi_api_all_response: list[dict[str, any]], | ||
) -> None: | ||
"""Test that the config flow creates an entry.""" | ||
result = await hass.config_entries.flow.async_init( | ||
DOMAIN, | ||
context={"source": config_entries.SOURCE_USER}, | ||
) | ||
assert result["type"] is FlowResultType.FORM | ||
assert result["errors"] is None | ||
|
||
aioclient_mock.get( | ||
"http://192.168.1.100:1880/macid/all", | ||
json=tiltpi_api_all_response, | ||
) | ||
|
||
result = await hass.config_entries.flow.async_configure( | ||
result["flow_id"], | ||
user_input=TEST_TILTPI_DATA, | ||
) | ||
await hass.async_block_till_done() | ||
|
||
assert result["type"] is FlowResultType.CREATE_ENTRY | ||
assert result["data"] == TEST_TILTPI_DATA | ||
|
||
|
||
async def test_async_step_user_returns_error_form_client_error( | ||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker | ||
) -> None: | ||
"""Test that the config flow creates an entry.""" | ||
result = await hass.config_entries.flow.async_init( | ||
DOMAIN, | ||
context={"source": config_entries.SOURCE_USER}, | ||
) | ||
assert result["type"] is FlowResultType.FORM | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's also finish this test to test we can recover |
||
assert result["errors"] is None | ||
|
||
aioclient_mock.get( | ||
"http://192.168.1.100:1880/macid/all", | ||
exc=aiohttp.ClientError, | ||
) | ||
|
||
result = await hass.config_entries.flow.async_configure( | ||
result["flow_id"], | ||
user_input=TEST_TILTPI_DATA, | ||
) | ||
await hass.async_block_till_done() | ||
|
||
assert result["type"] is FlowResultType.FORM | ||
assert result["errors"] == {"base": "cannot_connect"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The name should not be user settable