Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow for HLK-SW16."""
2 
3 import asyncio
4 from typing import Any
5 
6 from hlk_sw16 import create_hlk_sw16_connection
7 from hlk_sw16.protocol import SW16Client
8 import voluptuous as vol
9 
10 from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
11 from homeassistant.const import CONF_HOST, CONF_PORT
12 from homeassistant.core import HomeAssistant
13 
14 from .const import (
15  CONNECTION_TIMEOUT,
16  DEFAULT_KEEP_ALIVE_INTERVAL,
17  DEFAULT_PORT,
18  DEFAULT_RECONNECT_INTERVAL,
19  DOMAIN,
20 )
21 from .errors import CannotConnect
22 
23 DATA_SCHEMA = vol.Schema(
24  {
25  vol.Required(CONF_HOST): str,
26  vol.Optional(CONF_PORT, default=DEFAULT_PORT): vol.Coerce(int),
27  }
28 )
29 
30 
31 async def connect_client(hass: HomeAssistant, user_input: dict[str, Any]) -> SW16Client:
32  """Connect the HLK-SW16 client."""
33  client_aw = create_hlk_sw16_connection(
34  host=user_input[CONF_HOST],
35  port=user_input[CONF_PORT],
36  loop=hass.loop,
37  timeout=CONNECTION_TIMEOUT,
38  reconnect_interval=DEFAULT_RECONNECT_INTERVAL,
39  keep_alive_interval=DEFAULT_KEEP_ALIVE_INTERVAL,
40  )
41  async with asyncio.timeout(CONNECTION_TIMEOUT):
42  return await client_aw
43 
44 
45 async def validate_input(hass: HomeAssistant, user_input: dict[str, Any]) -> None:
46  """Validate the user input allows us to connect."""
47  try:
48  client = await connect_client(hass, user_input)
49  except TimeoutError as err:
50  raise CannotConnect from err
51 
52  try:
53 
54  def disconnect_callback():
55  if client.in_transaction:
56  client.active_transaction.set_exception(CannotConnect)
57 
58  client.disconnect_callback = disconnect_callback
59  await client.status()
60  except CannotConnect:
61  client.disconnect_callback = None
62  client.stop()
63  raise
64 
65  client.disconnect_callback = None
66  client.stop()
67 
68 
69 class SW16FlowHandler(ConfigFlow, domain=DOMAIN):
70  """Handle a HLK-SW16 config flow."""
71 
72  VERSION = 1
73 
74  async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
75  """Handle import."""
76  return await self.async_step_userasync_step_userasync_step_user(import_data)
77 
78  async def async_step_user(
79  self, user_input: dict[str, Any] | None = None
80  ) -> ConfigFlowResult:
81  """Handle the initial step."""
82  errors = {}
83  if user_input is not None:
84  self._async_abort_entries_match_async_abort_entries_match(
85  {CONF_HOST: user_input[CONF_HOST], CONF_PORT: user_input[CONF_PORT]}
86  )
87  try:
88  await validate_input(self.hass, user_input)
89  address = f"{user_input[CONF_HOST]}:{user_input[CONF_PORT]}"
90  return self.async_create_entryasync_create_entryasync_create_entry(title=address, data=user_input)
91  except CannotConnect:
92  errors["base"] = "cannot_connect"
93 
94  return self.async_show_formasync_show_formasync_show_form(
95  step_id="user", data_schema=DATA_SCHEMA, errors=errors
96  )
ConfigFlowResult async_step_import(self, dict[str, Any] import_data)
Definition: config_flow.py:74
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:80
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)
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)
_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)
None validate_input(HomeAssistant hass, dict[str, Any] user_input)
Definition: config_flow.py:45
SW16Client connect_client(HomeAssistant hass, dict[str, Any] user_input)
Definition: config_flow.py:31