Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow for iBeacon Tracker integration."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 from uuid import UUID
7 
8 import voluptuous as vol
9 
10 from homeassistant.components import bluetooth
11 from homeassistant.config_entries import (
12  ConfigEntry,
13  ConfigFlow,
14  ConfigFlowResult,
15  OptionsFlow,
16 )
17 from homeassistant.core import callback
19 from homeassistant.helpers.typing import VolDictType
20 
21 from .const import CONF_ALLOW_NAMELESS_UUIDS, DOMAIN
22 
23 
24 class IBeaconConfigFlow(ConfigFlow, domain=DOMAIN):
25  """Handle a config flow for iBeacon Tracker."""
26 
27  VERSION = 1
28 
29  async def async_step_user(
30  self, user_input: dict[str, Any] | None = None
31  ) -> ConfigFlowResult:
32  """Handle the initial step."""
33  if not bluetooth.async_scanner_count(self.hass, connectable=False):
34  return self.async_abortasync_abortasync_abort(reason="bluetooth_not_available")
35 
36  if user_input is not None:
37  return self.async_create_entryasync_create_entryasync_create_entry(title="iBeacon Tracker", data={})
38 
39  return self.async_show_formasync_show_formasync_show_form(step_id="user")
40 
41  @staticmethod
42  @callback
44  config_entry: ConfigEntry,
45  ) -> OptionsFlow:
46  """Get the options flow for this handler."""
47  return IBeaconOptionsFlow()
48 
49 
51  """Handle options."""
52 
53  async def async_step_init(self, user_input: dict | None = None) -> ConfigFlowResult:
54  """Manage the options."""
55  errors = {}
56 
57  current_uuids = self.config_entryconfig_entryconfig_entry.options.get(CONF_ALLOW_NAMELESS_UUIDS, [])
58  new_uuid = None
59 
60  if user_input is not None:
61  if new_uuid := user_input.get("new_uuid", "").lower():
62  try:
63  # accept non-standard formats that can be fixed by UUID
64  new_uuid = str(UUID(new_uuid))
65  except ValueError:
66  errors["new_uuid"] = "invalid_uuid_format"
67 
68  if not errors:
69  # don't modify current_uuids in memory, cause HA will think that the new
70  # data is equal to the old, and will refuse to write them to disk.
71  updated_uuids = user_input.get("allow_nameless_uuids", [])
72  if new_uuid and new_uuid not in updated_uuids:
73  updated_uuids.append(new_uuid)
74 
75  data = {CONF_ALLOW_NAMELESS_UUIDS: list(updated_uuids)}
76  return self.async_create_entryasync_create_entry(title="", data=data)
77 
78  schema: VolDictType = {
79  vol.Optional(
80  "new_uuid",
81  description={"suggested_value": new_uuid},
82  ): str,
83  }
84  if current_uuids:
85  schema |= {
86  vol.Optional(
87  "allow_nameless_uuids",
88  default=current_uuids,
89  ): cv.multi_select(sorted(current_uuids))
90  }
91  return self.async_show_formasync_show_form(
92  step_id="init", errors=errors, data_schema=vol.Schema(schema)
93  )
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:31
OptionsFlow async_get_options_flow(ConfigEntry config_entry)
Definition: config_flow.py:45
ConfigFlowResult async_step_init(self, dict|None user_input=None)
Definition: config_flow.py:53
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)
None config_entry(self, ConfigEntry value)
str
_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)