1 """Config flow for Keenetic NDMS2."""
3 from __future__
import annotations
5 from typing
import Any, cast
6 from urllib.parse
import urlparse
8 from ndms2_client
import Client, ConnectionException, InterfaceInfo, TelnetConnection
9 import voluptuous
as vol
32 CONF_INCLUDE_ASSOCIATED,
35 DEFAULT_CONSIDER_HOME,
37 DEFAULT_SCAN_INTERVAL,
42 from .router
import KeeneticRouter
46 """Handle a config flow."""
50 host: str | bytes |
None =
None
55 config_entry: ConfigEntry,
56 ) -> KeeneticOptionsFlowHandler:
57 """Get the options flow for this handler."""
61 self, user_input: dict[str, Any] |
None =
None
62 ) -> ConfigFlowResult:
63 """Handle a flow initialized by the user."""
65 if user_input
is not None:
66 host = self.
hosthost
or user_input[CONF_HOST]
72 user_input[CONF_PORT],
73 user_input[CONF_USERNAME],
74 user_input[CONF_PASSWORD],
80 router_info = await self.hass.async_add_executor_job(
81 _client.get_router_info
83 except ConnectionException:
84 errors[
"base"] =
"cannot_connect"
87 title=router_info.name, data={CONF_HOST: host, **user_input}
90 host_schema: VolDictType = (
91 {vol.Required(CONF_HOST): str}
if not self.
hosthost
else {}
96 data_schema=vol.Schema(
99 vol.Required(CONF_USERNAME): str,
100 vol.Required(CONF_PASSWORD): str,
101 vol.Optional(CONF_PORT, default=DEFAULT_TELNET_PORT): int,
108 self, discovery_info: ssdp.SsdpServiceInfo
109 ) -> ConfigFlowResult:
110 """Handle a discovered device."""
111 friendly_name = discovery_info.upnp.get(ssdp.ATTR_UPNP_FRIENDLY_NAME,
"")
114 if "keenetic" not in friendly_name.lower():
118 if not discovery_info.upnp.get(ssdp.ATTR_UPNP_UDN):
123 host = cast(str, urlparse(discovery_info.ssdp_location).hostname)
130 self.context[
"title_placeholders"] = {
131 "name": friendly_name,
139 """Handle options."""
142 """Initialize options flow."""
146 self, user_input: dict[str, Any] |
None =
None
147 ) -> ConfigFlowResult:
148 """Manage the options."""
153 interfaces: list[InterfaceInfo] = await self.hass.async_add_executor_job(
154 router.client.get_interfaces
158 interface.name: (interface.description
or interface.name)
159 for interface
in interfaces
160 if interface.type.lower() ==
"bridge"
165 self, user_input: dict[str, Any] |
None =
None
166 ) -> ConfigFlowResult:
167 """Manage the device tracker options."""
168 if user_input
is not None:
171 options = vol.Schema(
176 CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
182 CONF_CONSIDER_HOME, DEFAULT_CONSIDER_HOME
188 CONF_INTERFACES, [DEFAULT_INTERFACE]
200 CONF_INCLUDE_ASSOCIATED,
202 CONF_INCLUDE_ASSOCIATED,
True
208 return self.
async_show_formasync_show_form(step_id=
"user", data_schema=options)
ConfigFlowResult async_step_ssdp(self, ssdp.SsdpServiceInfo discovery_info)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
KeeneticOptionsFlowHandler async_get_options_flow(ConfigEntry config_entry)
ConfigFlowResult async_step_init(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
None _abort_if_unique_id_configured(self, dict[str, Any]|None updates=None, bool reload_on_update=True, *str error="already_configured")
ConfigEntry|None async_set_unique_id(self, str|None unique_id=None, *bool raise_on_progress=True)
ConfigFlowResult async_create_entry(self, *str title, Mapping[str, Any] data, str|None description=None, Mapping[str, str]|None description_placeholders=None, Mapping[str, Any]|None options=None)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
None _async_abort_entries_match(self, dict[str, Any]|None match_dict=None)
ConfigFlowResult async_show_form(self, *str|None step_id=None, vol.Schema|None data_schema=None, dict[str, str]|None errors=None, Mapping[str, str]|None description_placeholders=None, bool|None last_step=None, str|None preview=None)
ConfigEntry config_entry(self)
None config_entry(self, ConfigEntry value)
_FlowResultT async_show_form(self, *str|None step_id=None, vol.Schema|None data_schema=None, dict[str, str]|None errors=None, Mapping[str, str]|None description_placeholders=None, bool|None last_step=None, str|None preview=None)
_FlowResultT async_create_entry(self, *str|None title=None, Mapping[str, Any] data, str|None description=None, Mapping[str, str]|None description_placeholders=None)
_FlowResultT async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)