config_flow.py 4.3 KB

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