config_flow.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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_NAME], 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)),
  75. vol.Required(CONF_PASSWORD
  76. ): TextSelector(TextSelectorConfig(type=TextSelectorType.PASSWORD))
  77. }
  78. ),
  79. errors={},
  80. )
  81. async def _validate_user_input(self, ip: str, user: str, password: str):
  82. """Validate user input."""
  83. session = async_create_clientsession(self.hass)
  84. client = RouterApiClient(ip=ip,
  85. user=user,
  86. password=password,
  87. session=session)
  88. await client.async_login()
  89. @staticmethod
  90. @callback
  91. def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow:
  92. return RouterOptionsFlowHandler()
  93. class RouterOptionsFlowHandler(OptionsFlow):
  94. """Router config flow options handler."""
  95. async def async_step_init(
  96. self, user_input: dict[str, Any] | None = None
  97. ) -> FlowResult:
  98. """Manage the options."""
  99. if user_input is not None:
  100. return self.async_create_entry(
  101. title=self.config_entry.data.get(CONF_NAME), data=user_input
  102. )
  103. return self.async_show_form(
  104. step_id="init",
  105. data_schema=vol.Schema(
  106. {
  107. vol.Required(
  108. CONF_SCAN_INTERVAL,
  109. default=self.config_entry.options.get(
  110. CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL
  111. ),
  112. ): vol.All(vol.Coerce(int), vol.Range(min=30, max=3600))
  113. }
  114. ),
  115. )