config_flow.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. """Adds config flow for ZYXEL."""
  2. import logging
  3. from typing import Any
  4. from homeassistant.config_entries import (
  5. ConfigEntry,
  6. ConfigFlow,
  7. FlowResult,
  8. OptionsFlow,
  9. )
  10. from homeassistant.const import (
  11. CONF_SCAN_INTERVAL,
  12. CONF_USERNAME,
  13. CONF_PASSWORD,
  14. CONF_IP_ADDRESS
  15. )
  16. from homeassistant.core import callback
  17. from homeassistant.helpers.aiohttp_client import async_create_clientsession
  18. from homeassistant.helpers.selector import (TextSelector,
  19. TextSelectorConfig,
  20. TextSelectorType)
  21. import homeassistant.helpers.config_validation as cv
  22. import voluptuous as vol
  23. from .api import (
  24. RouterApiClient,
  25. RouterApiClientLoginError,
  26. RouterApiClientCommunicationError,
  27. RouterApiClientResponseError,
  28. )
  29. from .const import (DEFAULT_SCAN_INTERVAL,
  30. DOMAIN,
  31. DEFAULT_IP,
  32. DEFAULT_USER)
  33. _LOGGER: logging.Logger = logging.getLogger(__package__)
  34. class RouterFlowHandler(ConfigFlow, domain=DOMAIN):
  35. """Config flow for Odido Router."""
  36. VERSION = 1
  37. async def async_step_user(
  38. self, user_input: dict[str, Any] | None = None
  39. ) -> FlowResult:
  40. """Handle a flow initialized by the user."""
  41. _errors = {}
  42. if user_input is not None:
  43. try:
  44. await self._validate_user_input(
  45. user_input[CONF_IP_ADDRESS],
  46. user_input[CONF_USERNAME],
  47. user_input[CONF_PASSWORD],
  48. )
  49. except RouterApiClientCommunicationError as exception:
  50. _LOGGER.error(exception)
  51. _errors["base"] = "general"
  52. except RouterApiClientLoginError as exception:
  53. _LOGGER.error(exception)
  54. _errors["base"] = "api_key"
  55. except RouterApiClientResponseError as exception:
  56. _LOGGER.error(exception)
  57. _errors["base"] = "daily_limit"
  58. else:
  59. return self.async_create_entry(
  60. title=user_input[CONF_IP_ADDRESS], data=user_input
  61. )
  62. return self.async_show_form(
  63. step_id="user",
  64. data_schema=vol.Schema(
  65. {
  66. vol.Required(
  67. CONF_IP_ADDRESS, default=DEFAULT_IP
  68. ): str,
  69. vol.Required(
  70. CONF_USERNAME, default=DEFAULT_USER
  71. ): TextSelector(TextSelectorConfig(type=TextSelectorType.TEXT, autocomplete='username')),
  72. vol.Required(CONF_PASSWORD): TextSelector(TextSelectorConfig(type=TextSelectorType.PASSWORD, autocomplete='current-password'))
  73. }
  74. ),
  75. errors={},
  76. )
  77. async def _validate_user_input(self, ip: str, user: str, password: str):
  78. """Validate user input."""
  79. session = async_create_clientsession(self.hass)
  80. client = RouterApiClient(ip=ip,
  81. user=user,
  82. password=password,
  83. session=session)
  84. await client.async_login()
  85. @staticmethod
  86. @callback
  87. def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
  88. return RouterOptionsFlowHandler()
  89. class RouterOptionsFlowHandler(OptionsFlow):
  90. """Router config flow options handler."""
  91. async def async_step_init(
  92. self, user_input: dict[str, Any] | None = None
  93. ) -> FlowResult:
  94. """Manage the options."""
  95. if user_input is not None:
  96. return self.async_create_entry(
  97. title=self.config_entry.data.get(CONF_IP_ADDRESS), data=user_input
  98. )
  99. return self.async_show_form(
  100. step_id="init",
  101. data_schema=vol.Schema(
  102. {
  103. vol.Required(
  104. CONF_SCAN_INTERVAL,
  105. default=self.config_entry.options.get(
  106. CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
  107. ),
  108. ): vol.All(vol.Coerce(int), vol.Range(min=30, max=3600))
  109. }
  110. ),
  111. )