-
-
Notifications
You must be signed in to change notification settings - Fork 37.2k
iaqualink: Add basic DHCP discovery for iAquaLink devices #168256
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
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,9 +13,15 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import voluptuous as vol | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from homeassistant.config_entries import ConfigFlow, ConfigFlowResult | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from homeassistant.config_entries import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SOURCE_DHCP, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| SOURCE_REAUTH, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ConfigFlow, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ConfigFlowResult, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from homeassistant.const import CONF_PASSWORD, CONF_USERNAME | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from homeassistant.helpers.httpx_client import get_async_client | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from homeassistant.util.ssl import SSL_ALPN_HTTP11_HTTP2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from .const import DOMAIN | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -33,6 +39,16 @@ class AqualinkFlowHandler(ConfigFlow, domain=DOMAIN): | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| VERSION = 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def __init__(self) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Initialize the config flow.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._discovered_hostname: str | None = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._discovered_ip: str | None = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def _async_set_single_instance_unique_id(self) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Assign the unique ID used by this single-instance integration.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await self.async_set_unique_id(DOMAIN, raise_on_progress=False) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._abort_if_unique_id_configured(error="single_instance_allowed") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def _async_test_credentials( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self, user_input: dict[str, Any] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> dict[str, str]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -53,10 +69,24 @@ async def _async_test_credentials( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def async_step_dhcp( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self, discovery_info: DhcpServiceInfo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> ConfigFlowResult: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Handle a DHCP discovery.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await self._async_set_single_instance_unique_id() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._discovered_hostname = discovery_info.hostname | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._discovered_ip = discovery_info.ip | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return await self.async_step_user() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async def async_step_user( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self, user_input: dict[str, Any] | None = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> ConfigFlowResult: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Handle a flow start.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if self.source not in (SOURCE_DHCP, SOURCE_REAUTH): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await self._async_set_single_instance_unique_id() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errors = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if user_input is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -66,9 +96,21 @@ async def async_step_user( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title=user_input[CONF_USERNAME], data=user_input | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| discovery = "" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.source == SOURCE_DHCP | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and self._discovered_hostname is not None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and self._discovered_ip is not None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| discovery = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "A likely iAquaLink device was discovered on your network at " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f"{self._discovered_ip} ({self._discovered_hostname}). " | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return self.async_show_form( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| step_id="user", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data_schema=CREDENTIALS_DATA_SCHEMA, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| description_placeholders={"discovery": discovery}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+99
to
+113
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| discovery = "" | |
| if ( | |
| self.source == SOURCE_DHCP | |
| and self._discovered_hostname is not None | |
| and self._discovered_ip is not None | |
| ): | |
| discovery = ( | |
| "A likely iAquaLink device was discovered on your network at " | |
| f"{self._discovered_ip} ({self._discovered_hostname}). " | |
| ) | |
| return self.async_show_form( | |
| step_id="user", | |
| data_schema=CREDENTIALS_DATA_SCHEMA, | |
| description_placeholders={"discovery": discovery}, | |
| description_placeholders: dict[str, str] | None = None | |
| if ( | |
| self.source == SOURCE_DHCP | |
| and self._discovered_hostname is not None | |
| and self._discovered_ip is not None | |
| ): | |
| description_placeholders = { | |
| "ip": self._discovered_ip, | |
| "hostname": self._discovered_hostname, | |
| } | |
| return self.async_show_form( | |
| step_id="user", | |
| data_schema=CREDENTIALS_DATA_SCHEMA, | |
| description_placeholders=description_placeholders, |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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.
Add the missing
single_instance_allowedabort translation key so the new abort reason can be shown to users._abort_if_unique_id_configured(error="single_instance_allowed")requires a corresponding entry inhomeassistant/components/iaqualink/strings.json(typically mapping to[%key:common::config_flow::abort::single_instance_allowed%]), otherwise the abort reason will be untranslated / fail translation validation.