Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow for Lektrico Charging Station."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from lektricowifi import Device, DeviceConnectionError
8 import voluptuous as vol
9 
10 from homeassistant.components.zeroconf import ZeroconfServiceInfo
11 from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
12 from homeassistant.const import (
13  ATTR_HW_VERSION,
14  ATTR_SERIAL_NUMBER,
15  CONF_HOST,
16  CONF_TYPE,
17 )
18 from homeassistant.core import callback
19 from homeassistant.helpers.httpx_client import get_async_client
20 
21 from .const import DOMAIN
22 
23 STEP_USER_DATA_SCHEMA = vol.Schema(
24  {
25  vol.Required(CONF_HOST): str,
26  }
27 )
28 
29 
30 class LektricoFlowHandler(ConfigFlow, domain=DOMAIN):
31  """Handle a Lektrico config flow."""
32 
33  VERSION = 1
34 
35  _host: str
36  _name: str
37  _serial_number: str
38  _board_revision: str
39  _device_type: str
40 
41  async def async_step_user(
42  self, user_input: dict[str, str] | None = None
43  ) -> ConfigFlowResult:
44  """Handle a flow initiated by the user."""
45  errors = None
46 
47  if user_input is not None:
48  self._host_host = user_input[CONF_HOST]
49 
50  # obtain serial number
51  try:
52  await self._get_lektrico_device_settings_and_treat_unique_id_get_lektrico_device_settings_and_treat_unique_id()
53  return self._async_create_entry_async_create_entry()
54  except DeviceConnectionError:
55  errors = {CONF_HOST: "cannot_connect"}
56 
57  return self._async_show_setup_form_async_show_setup_form(user_input=user_input, errors=errors)
58 
59  @callback
61  self,
62  user_input: dict[str, Any] | None = None,
63  errors: dict[str, str] | None = None,
64  ) -> ConfigFlowResult:
65  """Show the setup form to the user."""
66  if user_input is None:
67  user_input = {}
68 
69  schema = self.add_suggested_values_to_schemaadd_suggested_values_to_schema(STEP_USER_DATA_SCHEMA, user_input)
70 
71  return self.async_show_formasync_show_formasync_show_form(
72  step_id="user",
73  data_schema=schema,
74  errors=errors or {},
75  )
76 
77  @callback
78  def _async_create_entry(self) -> ConfigFlowResult:
79  return self.async_create_entryasync_create_entryasync_create_entry(
80  title=self._name_name,
81  data={
82  CONF_HOST: self._host_host,
83  ATTR_SERIAL_NUMBER: self._serial_number_serial_number,
84  CONF_TYPE: self._device_type_device_type,
85  ATTR_HW_VERSION: self._board_revision_board_revision,
86  },
87  )
88 
90  self, discovery_info: ZeroconfServiceInfo
91  ) -> ConfigFlowResult:
92  """Handle zeroconf discovery."""
93  self._host_host = discovery_info.host # 192.168.100.11
94 
95  # read settings from the device
96  try:
97  await self._get_lektrico_device_settings_and_treat_unique_id_get_lektrico_device_settings_and_treat_unique_id()
98  except DeviceConnectionError:
99  return self.async_abortasync_abortasync_abort(reason="cannot_connect")
100 
101  self.context["title_placeholders"] = {
102  "serial_number": self._serial_number_serial_number,
103  "name": self._name_name,
104  }
105 
106  return await self.async_step_confirmasync_step_confirm()
107 
109  """Get device's serial number from a Lektrico device."""
110  device = Device(
111  _host=self._host_host,
112  asyncClient=get_async_client(self.hass),
113  )
114 
115  settings = await device.device_config()
116  self._serial_number_serial_number = str(settings["serial_number"])
117  self._device_type_device_type = settings["type"]
118  self._board_revision_board_revision = settings["board_revision"]
119  self._name_name = f"{settings["type"]}_{self._serial_number}"
120 
121  # Check if already configured
122  # Set unique id
123  await self.async_set_unique_idasync_set_unique_id(self._serial_number_serial_number, raise_on_progress=True)
124  # Abort if already configured, but update the last-known host
125  self._abort_if_unique_id_configured_abort_if_unique_id_configured(
126  updates={CONF_HOST: self._host_host}, reload_on_update=True
127  )
128 
130  self, user_input: dict[str, str] | None = None
131  ) -> ConfigFlowResult:
132  """Allow the user to confirm adding the device."""
133 
134  if user_input is not None:
135  return self._async_create_entry_async_create_entry()
136 
137  self._set_confirm_only_set_confirm_only()
138  return self.async_show_formasync_show_formasync_show_form(step_id="confirm")
ConfigFlowResult async_step_user(self, dict[str, str]|None user_input=None)
Definition: config_flow.py:43
ConfigFlowResult async_step_zeroconf(self, ZeroconfServiceInfo discovery_info)
Definition: config_flow.py:91
ConfigFlowResult async_step_confirm(self, dict[str, str]|None user_input=None)
Definition: config_flow.py:131
ConfigFlowResult _async_show_setup_form(self, dict[str, Any]|None user_input=None, dict[str, str]|None errors=None)
Definition: config_flow.py:64
None _abort_if_unique_id_configured(self, dict[str, Any]|None updates=None, bool reload_on_update=True, *str error="already_configured")
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)
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)
str
vol.Schema add_suggested_values_to_schema(self, vol.Schema data_schema, Mapping[str, Any]|None suggested_values)
_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)
httpx.AsyncClient get_async_client(HomeAssistant hass, bool verify_ssl=True)
Definition: httpx_client.py:41