config_flow.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import logging
  2. import voluptuous as vol
  3. from homeassistant import config_entries, data_entry_flow
  4. from homeassistant.const import CONF_HOST, CONF_NAME
  5. from homeassistant.core import HomeAssistant, callback
  6. from . import DOMAIN
  7. from .configuration import individual_config_schema
  8. from .device import TuyaLocalDevice
  9. from .const import CONF_DEVICE_ID, CONF_LOCAL_KEY, CONF_TYPE
  10. from .helpers.device_config import config_for_legacy_use
  11. _LOGGER = logging.getLogger(__name__)
  12. class ConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
  13. VERSION = 2
  14. CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL
  15. async def async_step_user(self, user_input=None):
  16. errors = {}
  17. if user_input is not None:
  18. await self.async_set_unique_id(user_input[CONF_DEVICE_ID])
  19. self._abort_if_unique_id_configured()
  20. self.device = await async_test_connection(user_input, self.hass)
  21. if self.device:
  22. self.data = user_input
  23. return await self.async_step_select_type()
  24. else:
  25. errors["base"] = "connection"
  26. return self.async_show_form(
  27. step_id="user",
  28. data_schema=vol.Schema(individual_config_schema(user_input or {})),
  29. errors=errors,
  30. )
  31. async def async_step_select_type(self, user_input=None):
  32. if user_input is not None:
  33. self.data[CONF_TYPE] = user_input[CONF_TYPE]
  34. return await self.async_step_choose_entities()
  35. types = []
  36. async for type in self.device.async_possible_types():
  37. types.append(type)
  38. if types:
  39. return self.async_show_form(
  40. step_id="type",
  41. data_schema=vol.Schema({vol.Required(CONF_TYPE): vol.In(types)}),
  42. )
  43. else:
  44. return self.async_abort(reason="not_supported")
  45. async def async_step_choose_entities(self, user_input=None):
  46. if user_input is not None:
  47. title = user_input[CONF_NAME]
  48. del user_input[CONF_NAME]
  49. return self.async_create_entry(
  50. title=title, data={**self.data, **user_input}
  51. )
  52. config = config_for_legacy_use(self.data[CONF_TYPE])
  53. schema = {vol.Required(CONF_NAME, default=config.name): str}
  54. e = config.primary_entity
  55. schema[vol.Optional(e.entity, default=True)] = bool
  56. for e in config.secondary_entities():
  57. schema[vol.Optional(e.entity, default=not e.deprecated)] = bool
  58. return self.async_show_form(
  59. step_id="entities",
  60. data_schema=vol.Schema(schema),
  61. )
  62. @staticmethod
  63. @callback
  64. def async_get_options_flow(config_entry):
  65. return OptionsFlowHandler(config_entry)
  66. class OptionsFlowHandler(config_entries.OptionsFlow):
  67. def __init__(self, config_entry):
  68. """Initialize options flow."""
  69. self.config_entry = config_entry
  70. async def async_step_init(self, user_input=None):
  71. return await self.async_step_user(user_input)
  72. async def async_step_user(self, user_input=None):
  73. """Manage the options."""
  74. errors = {}
  75. config = {**self.config_entry.data, **self.config_entry.options}
  76. if user_input is not None:
  77. config = {**config, **user_input}
  78. connect_success = await async_test_connection(config, self.hass)
  79. if connect_success:
  80. return self.async_create_entry(title="", data=user_input)
  81. else:
  82. errors["base"] = "connection"
  83. return self.async_show_form(
  84. step_id="user",
  85. data_schema=vol.Schema(
  86. individual_config_schema(defaults=config, options_only=True)
  87. ),
  88. errors=errors,
  89. )
  90. async def async_test_connection(config: dict, hass: HomeAssistant):
  91. device = TuyaLocalDevice(
  92. "Test", config[CONF_DEVICE_ID], config[CONF_HOST], config[CONF_LOCAL_KEY], hass
  93. )
  94. await device.async_refresh()
  95. return device if device.has_returned_state else None