mirror of
https://github.com/home-assistant/core.git
synced 2025-11-06 01:19:29 +00:00
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Norbert Rittel <norbert@rittel.de> Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
115 lines
4.0 KiB
Python
115 lines
4.0 KiB
Python
"""Config flow file."""
|
|
|
|
from contextlib import suppress
|
|
import logging
|
|
from typing import Any
|
|
|
|
from fing_agent_api import FingAgent
|
|
import httpx
|
|
import voluptuous as vol
|
|
|
|
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
|
from homeassistant.const import CONF_API_KEY, CONF_IP_ADDRESS, CONF_PORT
|
|
|
|
from .const import DOMAIN, UPNP_AVAILABLE
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
class FingConfigFlow(ConfigFlow, domain=DOMAIN):
|
|
"""Fing config flow."""
|
|
|
|
VERSION = 1
|
|
|
|
async def async_step_user(
|
|
self, user_input: dict[str, Any] | None = None
|
|
) -> ConfigFlowResult:
|
|
"""Set up user step."""
|
|
errors: dict[str, str] = {}
|
|
description_placeholders: dict[str, str] = {}
|
|
|
|
if user_input is not None:
|
|
devices_response = None
|
|
agent_info_response = None
|
|
|
|
self._async_abort_entries_match(
|
|
{CONF_IP_ADDRESS: user_input[CONF_IP_ADDRESS]}
|
|
)
|
|
|
|
fing_api = FingAgent(
|
|
ip=user_input[CONF_IP_ADDRESS],
|
|
port=int(user_input[CONF_PORT]),
|
|
key=user_input[CONF_API_KEY],
|
|
)
|
|
|
|
try:
|
|
devices_response = await fing_api.get_devices()
|
|
|
|
with suppress(httpx.ConnectError):
|
|
# The suppression is needed because the get_agent_info method isn't available for desktop agents
|
|
agent_info_response = await fing_api.get_agent_info()
|
|
|
|
except httpx.NetworkError as _:
|
|
errors["base"] = "cannot_connect"
|
|
except httpx.TimeoutException as _:
|
|
errors["base"] = "timeout_connect"
|
|
except httpx.HTTPStatusError as exception:
|
|
description_placeholders["message"] = (
|
|
f"{exception.response.status_code} - {exception.response.reason_phrase}"
|
|
)
|
|
if exception.response.status_code == 401:
|
|
errors["base"] = "invalid_api_key"
|
|
else:
|
|
errors["base"] = "http_status_error"
|
|
except httpx.InvalidURL as _:
|
|
errors["base"] = "url_error"
|
|
except (
|
|
httpx.HTTPError,
|
|
httpx.CookieConflict,
|
|
httpx.StreamError,
|
|
) as ex:
|
|
_LOGGER.error("Unexpected exception: %s", ex)
|
|
errors["base"] = "unknown"
|
|
else:
|
|
if (
|
|
devices_response.network_id is not None
|
|
and len(devices_response.network_id) > 0
|
|
):
|
|
agent_name = user_input.get(CONF_IP_ADDRESS)
|
|
upnp_available = False
|
|
if agent_info_response is not None:
|
|
upnp_available = True
|
|
agent_name = agent_info_response.agent_id
|
|
await self.async_set_unique_id(agent_info_response.agent_id)
|
|
self._abort_if_unique_id_configured()
|
|
|
|
data = {
|
|
CONF_IP_ADDRESS: user_input[CONF_IP_ADDRESS],
|
|
CONF_PORT: user_input[CONF_PORT],
|
|
CONF_API_KEY: user_input[CONF_API_KEY],
|
|
UPNP_AVAILABLE: upnp_available,
|
|
}
|
|
|
|
return self.async_create_entry(
|
|
title=f"Fing Agent {agent_name}",
|
|
data=data,
|
|
)
|
|
|
|
return self.async_abort(reason="api_version_error")
|
|
|
|
return self.async_show_form(
|
|
step_id="user",
|
|
data_schema=self.add_suggested_values_to_schema(
|
|
vol.Schema(
|
|
{
|
|
vol.Required(CONF_IP_ADDRESS): str,
|
|
vol.Required(CONF_PORT, default="49090"): str,
|
|
vol.Required(CONF_API_KEY): str,
|
|
}
|
|
),
|
|
user_input,
|
|
),
|
|
errors=errors,
|
|
description_placeholders=description_placeholders,
|
|
)
|