mirror of
https://github.com/home-assistant/core.git
synced 2025-11-08 18:39:30 +00:00
Add Airzone DHCP discovery support (#82339)
This commit is contained in:
committed by
GitHub
parent
f91e250e90
commit
f1ffb25d99
@@ -1,6 +1,7 @@
|
||||
"""Config flow for Airzone."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from aioairzone.const import DEFAULT_PORT, DEFAULT_SYSTEM_ID
|
||||
@@ -9,13 +10,16 @@ from aioairzone.localapi import AirzoneLocalApi, ConnectionOptions
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components import dhcp
|
||||
from homeassistant.const import CONF_HOST, CONF_ID, CONF_PORT
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.data_entry_flow import AbortFlow, FlowResult
|
||||
from homeassistant.helpers import aiohttp_client
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_HOST): str,
|
||||
@@ -29,9 +33,17 @@ SYSTEM_ID_SCHEMA = CONFIG_SCHEMA.extend(
|
||||
)
|
||||
|
||||
|
||||
def short_mac(addr: str) -> str:
|
||||
"""Convert MAC address to short address."""
|
||||
return addr.replace(":", "")[-4:].upper()
|
||||
|
||||
|
||||
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle config flow for an Airzone device."""
|
||||
|
||||
_discovered_ip: str | None = None
|
||||
_discovered_mac: str | None = None
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
@@ -60,7 +72,9 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
errors["base"] = "cannot_connect"
|
||||
else:
|
||||
if mac:
|
||||
await self.async_set_unique_id(format_mac(mac))
|
||||
await self.async_set_unique_id(
|
||||
format_mac(mac), raise_on_progress=False
|
||||
)
|
||||
self._abort_if_unique_id_configured(
|
||||
updates={
|
||||
CONF_HOST: user_input[CONF_HOST],
|
||||
@@ -76,3 +90,78 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
data_schema=data_schema,
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
async def async_step_dhcp(self, discovery_info: dhcp.DhcpServiceInfo) -> FlowResult:
|
||||
"""Handle DHCP discovery."""
|
||||
self._discovered_ip = discovery_info.ip
|
||||
self._discovered_mac = discovery_info.macaddress
|
||||
|
||||
_LOGGER.debug(
|
||||
"DHCP discovery detected Airzone WebServer: %s", self._discovered_mac
|
||||
)
|
||||
|
||||
self._async_abort_entries_match({CONF_HOST: self._discovered_ip})
|
||||
|
||||
await self.async_set_unique_id(format_mac(self._discovered_mac))
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
options = ConnectionOptions(self._discovered_ip)
|
||||
airzone = AirzoneLocalApi(
|
||||
aiohttp_client.async_get_clientsession(self.hass), options
|
||||
)
|
||||
try:
|
||||
await airzone.get_version()
|
||||
except AirzoneError as err:
|
||||
raise AbortFlow("cannot_connect") from err
|
||||
|
||||
return await self.async_step_discovered_connection()
|
||||
|
||||
async def async_step_discovered_connection(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Confirm discovery."""
|
||||
assert self._discovered_ip is not None
|
||||
assert self._discovered_mac is not None
|
||||
|
||||
errors = {}
|
||||
base_schema = {vol.Required(CONF_PORT, default=DEFAULT_PORT): int}
|
||||
|
||||
if user_input is not None:
|
||||
airzone = AirzoneLocalApi(
|
||||
aiohttp_client.async_get_clientsession(self.hass),
|
||||
ConnectionOptions(
|
||||
self._discovered_ip,
|
||||
user_input[CONF_PORT],
|
||||
user_input.get(CONF_ID, DEFAULT_SYSTEM_ID),
|
||||
),
|
||||
)
|
||||
|
||||
try:
|
||||
mac = await airzone.validate()
|
||||
except InvalidSystem:
|
||||
base_schema[vol.Required(CONF_ID, default=1)] = int
|
||||
errors[CONF_ID] = "invalid_system_id"
|
||||
except AirzoneError:
|
||||
errors["base"] = "cannot_connect"
|
||||
else:
|
||||
user_input[CONF_HOST] = self._discovered_ip
|
||||
|
||||
if mac is None:
|
||||
mac = self._discovered_mac
|
||||
|
||||
await self.async_set_unique_id(format_mac(mac))
|
||||
self._abort_if_unique_id_configured(
|
||||
updates={
|
||||
CONF_HOST: user_input[CONF_HOST],
|
||||
CONF_PORT: user_input[CONF_PORT],
|
||||
}
|
||||
)
|
||||
|
||||
title = f"Airzone {short_mac(mac)}"
|
||||
return self.async_create_entry(title=title, data=user_input)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="discovered_connection",
|
||||
data_schema=vol.Schema(base_schema),
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user