Files
core/homeassistant/components/droplet/config_flow.py
Sarah Seidman ceeeb22040 Add integration for Droplet (#149989)
Co-authored-by: Norbert Rittel <norbert@rittel.de>
Co-authored-by: Josef Zweck <josef@zweck.dev>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
2025-09-10 17:38:49 +02:00

119 lines
4.3 KiB
Python

"""Config flow for Droplet integration."""
from __future__ import annotations
from typing import Any
from pydroplet.droplet import DropletConnection, DropletDiscovery
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_CODE, CONF_DEVICE_ID, CONF_IP_ADDRESS, CONF_PORT
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
from .const import DOMAIN
class DropletConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle Droplet config flow."""
_droplet_discovery: DropletDiscovery
async def async_step_zeroconf(
self, discovery_info: ZeroconfServiceInfo
) -> ConfigFlowResult:
"""Handle zeroconf discovery."""
self._droplet_discovery = DropletDiscovery(
discovery_info.host,
discovery_info.port,
discovery_info.name,
)
if not self._droplet_discovery.is_valid():
return self.async_abort(reason="invalid_discovery_info")
# In this case, device ID was part of the zeroconf discovery info
device_id: str = await self._droplet_discovery.get_device_id()
await self.async_set_unique_id(device_id)
self._abort_if_unique_id_configured(
updates={CONF_IP_ADDRESS: self._droplet_discovery.host},
)
self.context.update({"title_placeholders": {"name": device_id}})
return await self.async_step_confirm()
async def async_step_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm the setup."""
errors: dict[str, str] = {}
device_id: str = await self._droplet_discovery.get_device_id()
if user_input is not None:
# Test if we can connect before returning
session = async_get_clientsession(self.hass)
if await self._droplet_discovery.try_connect(
session, user_input[CONF_CODE]
):
device_data = {
CONF_IP_ADDRESS: self._droplet_discovery.host,
CONF_PORT: self._droplet_discovery.port,
CONF_DEVICE_ID: device_id,
CONF_CODE: user_input[CONF_CODE],
}
return self.async_create_entry(
title=device_id,
data=device_data,
)
errors["base"] = "cannot_connect"
return self.async_show_form(
step_id="confirm",
data_schema=vol.Schema(
{
vol.Required(CONF_CODE): str,
}
),
description_placeholders={
"device_name": device_id,
},
errors=errors,
)
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a flow initialized by the user."""
errors: dict[str, str] = {}
if user_input is not None:
self._droplet_discovery = DropletDiscovery(
user_input[CONF_IP_ADDRESS], DropletConnection.DEFAULT_PORT, ""
)
session = async_get_clientsession(self.hass)
if await self._droplet_discovery.try_connect(
session, user_input[CONF_CODE]
) and (device_id := await self._droplet_discovery.get_device_id()):
device_data = {
CONF_IP_ADDRESS: self._droplet_discovery.host,
CONF_PORT: self._droplet_discovery.port,
CONF_DEVICE_ID: device_id,
CONF_CODE: user_input[CONF_CODE],
}
await self.async_set_unique_id(device_id, raise_on_progress=False)
self._abort_if_unique_id_configured(
description_placeholders={CONF_DEVICE_ID: device_id},
)
return self.async_create_entry(
title=device_id,
data=device_data,
)
errors["base"] = "cannot_connect"
return self.async_show_form(
step_id="user",
data_schema=vol.Schema(
{vol.Required(CONF_IP_ADDRESS): str, vol.Required(CONF_CODE): str}
),
errors=errors,
)