Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow to configure WiLight."""
2 
3 from typing import Any
4 from urllib.parse import urlparse
5 
6 import pywilight
7 
8 from homeassistant.components import ssdp
9 from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
10 from homeassistant.const import CONF_HOST
11 
12 from .const import DOMAIN
13 
14 CONF_SERIAL_NUMBER = "serial_number"
15 CONF_MODEL_NAME = "model_name"
16 
17 WILIGHT_MANUFACTURER = "All Automacao Ltda"
18 
19 # List the components supported by this integration.
20 ALLOWED_WILIGHT_COMPONENTS = ["cover", "fan", "light", "switch"]
21 
22 
23 class WiLightFlowHandler(ConfigFlow, domain=DOMAIN):
24  """Handle a WiLight config flow."""
25 
26  VERSION = 1
27 
28  _title: str
29 
30  def __init__(self) -> None:
31  """Initialize the WiLight flow."""
32  self._host_host = None
33  self._serial_number_serial_number = None
34  self._model_name_model_name = None
35  self._wilight_components_wilight_components: list[str] = []
36  self._components_text_components_text = ""
37 
38  def _wilight_update(self, host, serial_number, model_name):
39  self._host_host = host
40  self._serial_number_serial_number = serial_number
41  self._title_title = f"WL{serial_number}"
42  self._model_name_model_name = model_name
43  self._wilight_components_wilight_components = pywilight.get_components_from_model(model_name)
44  self._components_text_components_text = ", ".join(self._wilight_components_wilight_components)
45  return self._components_text_components_text != ""
46 
47  def _get_entry(self):
48  data = {
49  CONF_HOST: self._host_host,
50  CONF_SERIAL_NUMBER: self._serial_number_serial_number,
51  CONF_MODEL_NAME: self._model_name_model_name,
52  }
53  return self.async_create_entryasync_create_entryasync_create_entry(title=self._title_title, data=data)
54 
55  async def async_step_ssdp(
56  self, discovery_info: ssdp.SsdpServiceInfo
57  ) -> ConfigFlowResult:
58  """Handle a discovered WiLight."""
59  # Filter out basic information
60  if (
61  not discovery_info.ssdp_location
62  or ssdp.ATTR_UPNP_MANUFACTURER not in discovery_info.upnp
63  or ssdp.ATTR_UPNP_SERIAL not in discovery_info.upnp
64  or ssdp.ATTR_UPNP_MODEL_NAME not in discovery_info.upnp
65  or ssdp.ATTR_UPNP_MODEL_NUMBER not in discovery_info.upnp
66  ):
67  return self.async_abortasync_abortasync_abort(reason="not_wilight_device")
68  # Filter out non-WiLight devices
69  if discovery_info.upnp[ssdp.ATTR_UPNP_MANUFACTURER] != WILIGHT_MANUFACTURER:
70  return self.async_abortasync_abortasync_abort(reason="not_wilight_device")
71 
72  host = urlparse(discovery_info.ssdp_location).hostname
73  serial_number = discovery_info.upnp[ssdp.ATTR_UPNP_SERIAL]
74  model_name = discovery_info.upnp[ssdp.ATTR_UPNP_MODEL_NAME]
75 
76  if not self._wilight_update_wilight_update(host, serial_number, model_name):
77  return self.async_abortasync_abortasync_abort(reason="not_wilight_device")
78 
79  # Check if all components of this WiLight are allowed in this version of the HA integration
80  component_ok = all(
81  wilight_component in ALLOWED_WILIGHT_COMPONENTS
82  for wilight_component in self._wilight_components_wilight_components
83  )
84 
85  if not component_ok:
86  return self.async_abortasync_abortasync_abort(reason="not_supported_device")
87 
88  await self.async_set_unique_idasync_set_unique_id(self._serial_number_serial_number)
89  self._abort_if_unique_id_configured_abort_if_unique_id_configured(updates={CONF_HOST: self._host_host})
90 
91  self.context["title_placeholders"] = {"name": self._title_title}
92  return await self.async_step_confirmasync_step_confirm()
93 
94  async def async_step_confirm(
95  self, user_input: dict[str, Any] | None = None
96  ) -> ConfigFlowResult:
97  """Handle user-confirmation of discovered WiLight."""
98  if user_input is not None:
99  return self._get_entry_get_entry()
100 
101  return self.async_show_formasync_show_formasync_show_form(
102  step_id="confirm",
103  description_placeholders={
104  "name": self._title_title,
105  "components": self._components_text_components_text,
106  },
107  errors={},
108  )
def _wilight_update(self, host, serial_number, model_name)
Definition: config_flow.py:38
ConfigFlowResult async_step_confirm(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:96
ConfigFlowResult async_step_ssdp(self, ssdp.SsdpServiceInfo discovery_info)
Definition: config_flow.py:57
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)
_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)