Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow for the Velbus platform."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 import velbusaio.controller
8 from velbusaio.exceptions import VelbusConnectionFailed
9 import voluptuous as vol
10 
11 from homeassistant.components import usb
12 from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
13 from homeassistant.const import CONF_NAME, CONF_PORT
14 from homeassistant.util import slugify
15 
16 from .const import DOMAIN
17 
18 
19 class VelbusConfigFlow(ConfigFlow, domain=DOMAIN):
20  """Handle a config flow."""
21 
22  VERSION = 2
23 
24  def __init__(self) -> None:
25  """Initialize the velbus config flow."""
26  self._errors_errors: dict[str, str] = {}
27  self._device_device: str = ""
28  self._title_title: str = ""
29 
30  def _create_device(self, name: str, prt: str) -> ConfigFlowResult:
31  """Create an entry async."""
32  return self.async_create_entryasync_create_entryasync_create_entry(title=name, data={CONF_PORT: prt})
33 
34  async def _test_connection(self, prt: str) -> bool:
35  """Try to connect to the velbus with the port specified."""
36  try:
37  controller = velbusaio.controller.Velbus(prt)
38  await controller.connect(True)
39  await controller.stop()
40  except VelbusConnectionFailed:
41  self._errors_errors[CONF_PORT] = "cannot_connect"
42  return False
43  return True
44 
45  async def async_step_user(
46  self, user_input: dict[str, Any] | None = None
47  ) -> ConfigFlowResult:
48  """Step when user initializes a integration."""
49  self._errors_errors = {}
50  if user_input is not None:
51  name = slugify(user_input[CONF_NAME])
52  prt = user_input[CONF_PORT]
53  self._async_abort_entries_match_async_abort_entries_match({CONF_PORT: prt})
54  if await self._test_connection_test_connection(prt):
55  return self._create_device_create_device(name, prt)
56  else:
57  user_input = {}
58  user_input[CONF_NAME] = ""
59  user_input[CONF_PORT] = ""
60 
61  return self.async_show_formasync_show_formasync_show_form(
62  step_id="user",
63  data_schema=vol.Schema(
64  {
65  vol.Required(CONF_NAME, default=user_input[CONF_NAME]): str,
66  vol.Required(CONF_PORT, default=user_input[CONF_PORT]): str,
67  }
68  ),
69  errors=self._errors_errors,
70  )
71 
72  async def async_step_usb(
73  self, discovery_info: usb.UsbServiceInfo
74  ) -> ConfigFlowResult:
75  """Handle USB Discovery."""
76  await self.async_set_unique_idasync_set_unique_id(
77  f"{discovery_info.vid}:{discovery_info.pid}_{discovery_info.serial_number}_{discovery_info.manufacturer}_{discovery_info.description}"
78  )
79  dev_path = discovery_info.device
80  # check if this device is not already configured
81  self._async_abort_entries_match_async_abort_entries_match({CONF_PORT: dev_path})
82  # check if we can make a valid velbus connection
83  if not await self._test_connection_test_connection(dev_path):
84  return self.async_abortasync_abortasync_abort(reason="cannot_connect")
85  # store the data for the config step
86  self._device_device = dev_path
87  self._title_title = "Velbus USB"
88  # call the config step
89  self._set_confirm_only_set_confirm_only()
90  return await self.async_step_discovery_confirmasync_step_discovery_confirm()
91 
93  self, user_input: dict[str, Any] | None = None
94  ) -> ConfigFlowResult:
95  """Handle Discovery confirmation."""
96  if user_input is not None:
97  return self._create_device_create_device(self._title_title, self._device_device)
98 
99  return self.async_show_formasync_show_formasync_show_form(
100  step_id="discovery_confirm",
101  description_placeholders={CONF_NAME: self._title_title},
102  )
ConfigFlowResult async_step_discovery_confirm(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:94
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:47
ConfigFlowResult _create_device(self, str name, str prt)
Definition: config_flow.py:30
ConfigFlowResult async_step_usb(self, usb.UsbServiceInfo discovery_info)
Definition: config_flow.py:74
ConfigEntry|None async_set_unique_id(self, str|None unique_id=None, *bool raise_on_progress=True)
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_abort(self, *str reason, Mapping[str, str]|None description_placeholders=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)
_FlowResultT async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)