Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow to configure Met component."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 import voluptuous as vol
8 
10  ConfigEntry,
11  ConfigFlow,
12  ConfigFlowResult,
13  OptionsFlow,
14 )
15 from homeassistant.const import (
16  CONF_ELEVATION,
17  CONF_LATITUDE,
18  CONF_LONGITUDE,
19  CONF_NAME,
20  UnitOfLength,
21 )
22 from homeassistant.core import HomeAssistant, callback
25  NumberSelector,
26  NumberSelectorConfig,
27  NumberSelectorMode,
28 )
29 
30 from .const import (
31  CONF_TRACK_HOME,
32  DEFAULT_HOME_LATITUDE,
33  DEFAULT_HOME_LONGITUDE,
34  DOMAIN,
35  HOME_LOCATION_NAME,
36 )
37 
38 
39 @callback
40 def configured_instances(hass: HomeAssistant) -> set[str]:
41  """Return a set of configured met.no instances."""
42  entries = []
43  for entry in hass.config_entries.async_entries(DOMAIN):
44  if entry.data.get("track_home"):
45  entries.append("home")
46  continue
47  entries.append(
48  f"{entry.data.get(CONF_LATITUDE)}-{entry.data.get(CONF_LONGITUDE)}"
49  )
50  return set(entries)
51 
52 
54  hass: HomeAssistant, config_entry: ConfigEntry | None = None
55 ) -> vol.Schema:
56  """Get a schema with default values."""
57  # If tracking home or no config entry is passed in, default value come from Home location
58  if config_entry is None or config_entry.data.get(CONF_TRACK_HOME, False):
59  return vol.Schema(
60  {
61  vol.Required(CONF_NAME, default=HOME_LOCATION_NAME): str,
62  vol.Required(CONF_LATITUDE, default=hass.config.latitude): cv.latitude,
63  vol.Required(
64  CONF_LONGITUDE, default=hass.config.longitude
65  ): cv.longitude,
66  vol.Required(
67  CONF_ELEVATION, default=hass.config.elevation
68  ): NumberSelector(
70  mode=NumberSelectorMode.BOX,
71  unit_of_measurement=UnitOfLength.METERS,
72  )
73  ),
74  }
75  )
76  # Not tracking home, default values come from config entry
77  return vol.Schema(
78  {
79  vol.Required(CONF_NAME, default=config_entry.data.get(CONF_NAME)): str,
80  vol.Required(
81  CONF_LATITUDE, default=config_entry.data.get(CONF_LATITUDE)
82  ): cv.latitude,
83  vol.Required(
84  CONF_LONGITUDE, default=config_entry.data.get(CONF_LONGITUDE)
85  ): cv.longitude,
86  vol.Required(
87  CONF_ELEVATION, default=config_entry.data.get(CONF_ELEVATION)
88  ): NumberSelector(
90  mode=NumberSelectorMode.BOX,
91  unit_of_measurement=UnitOfLength.METERS,
92  )
93  ),
94  }
95  )
96 
97 
98 class MetConfigFlowHandler(ConfigFlow, domain=DOMAIN):
99  """Config flow for Met component."""
100 
101  VERSION = 1
102 
103  async def async_step_user(
104  self, user_input: dict[str, Any] | None = None
105  ) -> ConfigFlowResult:
106  """Handle a flow initialized by the user."""
107  errors = {}
108 
109  if user_input is not None:
110  if (
111  f"{user_input.get(CONF_LATITUDE)}-{user_input.get(CONF_LONGITUDE)}"
112  not in configured_instances(self.hass)
113  ):
114  return self.async_create_entryasync_create_entryasync_create_entry(
115  title=user_input[CONF_NAME], data=user_input
116  )
117  errors[CONF_NAME] = "already_configured"
118 
119  return self.async_show_formasync_show_formasync_show_form(
120  step_id="user",
121  data_schema=_get_data_schema(self.hass),
122  errors=errors,
123  )
124 
126  self, data: dict[str, Any] | None = None
127  ) -> ConfigFlowResult:
128  """Handle a flow initialized by onboarding."""
129  # Don't create entry if latitude or longitude isn't set.
130  # Also, filters out our onboarding default location.
131  if (not self.hass.config.latitude and not self.hass.config.longitude) or (
132  self.hass.config.latitude == DEFAULT_HOME_LATITUDE
133  and self.hass.config.longitude == DEFAULT_HOME_LONGITUDE
134  ):
135  return self.async_abortasync_abortasync_abort(reason="no_home")
136 
137  return self.async_create_entryasync_create_entryasync_create_entry(
138  title=HOME_LOCATION_NAME, data={CONF_TRACK_HOME: True}
139  )
140 
141  @staticmethod
142  @callback
144  config_entry: ConfigEntry,
145  ) -> MetOptionsFlowHandler:
146  """Get the options flow for Met."""
147  return MetOptionsFlowHandler()
148 
149 
151  """Options flow for Met component."""
152 
153  async def async_step_init(
154  self, user_input: dict[str, Any] | None = None
155  ) -> ConfigFlowResult:
156  """Configure options for Met."""
157 
158  if user_input is not None:
159  # Update config entry with data from user input
160  self.hass.config_entries.async_update_entry(
161  self.config_entryconfig_entryconfig_entry, data=user_input
162  )
163  return self.async_create_entryasync_create_entry(
164  title=self.config_entryconfig_entryconfig_entry.title, data=user_input
165  )
166 
167  return self.async_show_formasync_show_form(
168  step_id="init",
169  data_schema=_get_data_schema(self.hass, config_entry=self.config_entryconfig_entryconfig_entry),
170  )
MetOptionsFlowHandler async_get_options_flow(ConfigEntry config_entry)
Definition: config_flow.py:145
ConfigFlowResult async_step_onboarding(self, dict[str, Any]|None data=None)
Definition: config_flow.py:127
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:105
ConfigFlowResult async_step_init(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:155
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)
_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)
set[str] configured_instances(HomeAssistant hass)
Definition: config_flow.py:40
vol.Schema _get_data_schema(HomeAssistant hass, ConfigEntry|None config_entry=None)
Definition: config_flow.py:55