core/homeassistant/components/guardian/config_flow.py

128 lines
4.1 KiB
Python
Raw Normal View History

"""Config flow for Elexa Guardian integration."""
from aioguardian import Client
from aioguardian.errors import GuardianError
import voluptuous as vol
from homeassistant import config_entries, core
2021-05-11 02:26:15 +00:00
from homeassistant.components.dhcp import IP_ADDRESS
from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT
from homeassistant.core import callback
from .const import CONF_UID, DOMAIN, LOGGER
2021-05-11 02:26:15 +00:00
DEFAULT_PORT = 7777
DATA_SCHEMA = vol.Schema(
2021-05-11 02:26:15 +00:00
{
vol.Required(CONF_IP_ADDRESS): str,
vol.Required(CONF_PORT, default=DEFAULT_PORT): int,
}
)
UNIQUE_ID = "guardian_{0}"
@callback
def async_get_pin_from_discovery_hostname(hostname):
"""Get the device's 4-digit PIN from its zeroconf-discovered hostname."""
return hostname.split(".")[0].split("-")[1]
@callback
def async_get_pin_from_uid(uid):
"""Get the device's 4-digit PIN from its UID."""
return uid[-4:]
async def validate_input(hass: core.HomeAssistant, data):
"""Validate the user input allows us to connect.
Data has the keys from DATA_SCHEMA with values provided by the user.
"""
async with Client(data[CONF_IP_ADDRESS]) as client:
ping_data = await client.system.ping()
return {
CONF_UID: ping_data["data"]["uid"],
}
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Elexa Guardian."""
VERSION = 1
def __init__(self):
"""Initialize."""
self.discovery_info = {}
async def _async_set_unique_id(self, pin):
"""Set the config entry's unique ID (based on the device's 4-digit PIN)."""
await self.async_set_unique_id(UNIQUE_ID.format(pin))
2021-05-11 02:26:15 +00:00
if self.discovery_info:
self._abort_if_unique_id_configured(
updates={CONF_IP_ADDRESS: self.discovery_info[CONF_IP_ADDRESS]}
)
else:
self._abort_if_unique_id_configured()
async def async_step_user(self, user_input=None):
"""Handle configuration via the UI."""
if user_input is None:
return self.async_show_form(
step_id="user", data_schema=DATA_SCHEMA, errors={}
)
try:
info = await validate_input(self.hass, user_input)
except GuardianError as err:
LOGGER.error("Error while connecting to unit: %s", err)
return self.async_show_form(
step_id="user",
data_schema=DATA_SCHEMA,
errors={CONF_IP_ADDRESS: "cannot_connect"},
)
pin = async_get_pin_from_uid(info[CONF_UID])
await self._async_set_unique_id(pin)
return self.async_create_entry(
title=info[CONF_UID], data={CONF_UID: info["uid"], **user_input}
)
2021-05-11 02:26:15 +00:00
async def async_step_dhcp(self, discovery_info):
"""Handle the configuration via dhcp."""
self.discovery_info = {
CONF_IP_ADDRESS: discovery_info[IP_ADDRESS],
CONF_PORT: DEFAULT_PORT,
}
return await self._async_handle_discovery()
async def async_step_zeroconf(self, discovery_info):
"""Handle the configuration via zeroconf."""
2021-05-11 02:26:15 +00:00
self.discovery_info = {
CONF_IP_ADDRESS: discovery_info["host"],
CONF_PORT: discovery_info["port"],
}
pin = async_get_pin_from_discovery_hostname(discovery_info["hostname"])
await self._async_set_unique_id(pin)
2021-05-11 02:26:15 +00:00
return await self._async_handle_discovery()
2021-05-11 02:26:15 +00:00
async def _async_handle_discovery(self):
"""Handle any discovery."""
self.context[CONF_IP_ADDRESS] = self.discovery_info[CONF_IP_ADDRESS]
if any(
2021-05-11 02:26:15 +00:00
self.context[CONF_IP_ADDRESS] == flow["context"][CONF_IP_ADDRESS]
for flow in self._async_in_progress()
):
return self.async_abort(reason="already_in_progress")
2021-05-11 02:26:15 +00:00
return await self.async_step_discovery_confirm()
2021-05-11 02:26:15 +00:00
async def async_step_discovery_confirm(self, user_input=None):
"""Finish the configuration via any discovery."""
if user_input is None:
2021-05-11 02:26:15 +00:00
self._set_confirm_only()
return self.async_show_form(step_id="discovery_confirm")
return await self.async_step_user(self.discovery_info)