Home Assistant Unofficial Reference 2024.12.1
config_flow.py
Go to the documentation of this file.
1 """Config flow for Forecast.Solar integration."""
2 
3 from __future__ import annotations
4 
5 import re
6 from typing import Any
7 
8 import voluptuous as vol
9 
10 from homeassistant.config_entries import (
11  ConfigEntry,
12  ConfigFlow,
13  ConfigFlowResult,
14  OptionsFlow,
15 )
16 from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME
17 from homeassistant.core import callback
18 from homeassistant.helpers import config_validation as cv
19 
20 from .const import (
21  CONF_AZIMUTH,
22  CONF_DAMPING_EVENING,
23  CONF_DAMPING_MORNING,
24  CONF_DECLINATION,
25  CONF_INVERTER_SIZE,
26  CONF_MODULES_POWER,
27  DOMAIN,
28 )
29 
30 RE_API_KEY = re.compile(r"^[a-zA-Z0-9]{16}$")
31 
32 
33 class ForecastSolarFlowHandler(ConfigFlow, domain=DOMAIN):
34  """Handle a config flow for Forecast.Solar."""
35 
36  VERSION = 2
37 
38  @staticmethod
39  @callback
41  config_entry: ConfigEntry,
42  ) -> ForecastSolarOptionFlowHandler:
43  """Get the options flow for this handler."""
45 
46  async def async_step_user(
47  self, user_input: dict[str, Any] | None = None
48  ) -> ConfigFlowResult:
49  """Handle a flow initiated by the user."""
50  if user_input is not None:
51  return self.async_create_entryasync_create_entryasync_create_entry(
52  title=user_input[CONF_NAME],
53  data={
54  CONF_LATITUDE: user_input[CONF_LATITUDE],
55  CONF_LONGITUDE: user_input[CONF_LONGITUDE],
56  },
57  options={
58  CONF_AZIMUTH: user_input[CONF_AZIMUTH],
59  CONF_DECLINATION: user_input[CONF_DECLINATION],
60  CONF_MODULES_POWER: user_input[CONF_MODULES_POWER],
61  },
62  )
63 
64  return self.async_show_formasync_show_formasync_show_form(
65  step_id="user",
66  data_schema=vol.Schema(
67  {
68  vol.Required(
69  CONF_NAME, default=self.hass.config.location_name
70  ): str,
71  vol.Required(
72  CONF_LATITUDE, default=self.hass.config.latitude
73  ): cv.latitude,
74  vol.Required(
75  CONF_LONGITUDE, default=self.hass.config.longitude
76  ): cv.longitude,
77  vol.Required(CONF_DECLINATION, default=25): vol.All(
78  vol.Coerce(int), vol.Range(min=0, max=90)
79  ),
80  vol.Required(CONF_AZIMUTH, default=180): vol.All(
81  vol.Coerce(int), vol.Range(min=0, max=360)
82  ),
83  vol.Required(CONF_MODULES_POWER): vol.All(
84  vol.Coerce(int), vol.Range(min=1)
85  ),
86  }
87  ),
88  )
89 
90 
92  """Handle options."""
93 
94  async def async_step_init(
95  self, user_input: dict[str, Any] | None = None
96  ) -> ConfigFlowResult:
97  """Manage the options."""
98  errors = {}
99  if user_input is not None:
100  if (api_key := user_input.get(CONF_API_KEY)) and RE_API_KEY.match(
101  api_key
102  ) is None:
103  errors[CONF_API_KEY] = "invalid_api_key"
104  else:
105  return self.async_create_entryasync_create_entry(
106  title="", data=user_input | {CONF_API_KEY: api_key or None}
107  )
108 
109  return self.async_show_formasync_show_form(
110  step_id="init",
111  data_schema=vol.Schema(
112  {
113  vol.Optional(
114  CONF_API_KEY,
115  description={
116  "suggested_value": self.config_entryconfig_entryconfig_entry.options.get(
117  CONF_API_KEY, ""
118  )
119  },
120  ): str,
121  vol.Required(
122  CONF_DECLINATION,
123  default=self.config_entryconfig_entryconfig_entry.options[CONF_DECLINATION],
124  ): vol.All(vol.Coerce(int), vol.Range(min=0, max=90)),
125  vol.Required(
126  CONF_AZIMUTH,
127  default=self.config_entryconfig_entryconfig_entry.options.get(CONF_AZIMUTH),
128  ): vol.All(vol.Coerce(int), vol.Range(min=-0, max=360)),
129  vol.Required(
130  CONF_MODULES_POWER,
131  default=self.config_entryconfig_entryconfig_entry.options[CONF_MODULES_POWER],
132  ): vol.All(vol.Coerce(int), vol.Range(min=1)),
133  vol.Optional(
134  CONF_DAMPING_MORNING,
135  default=self.config_entryconfig_entryconfig_entry.options.get(
136  CONF_DAMPING_MORNING, 0.0
137  ),
138  ): vol.Coerce(float),
139  vol.Optional(
140  CONF_DAMPING_EVENING,
141  default=self.config_entryconfig_entryconfig_entry.options.get(
142  CONF_DAMPING_EVENING, 0.0
143  ),
144  ): vol.Coerce(float),
145  vol.Optional(
146  CONF_INVERTER_SIZE,
147  description={
148  "suggested_value": self.config_entryconfig_entryconfig_entry.options.get(
149  CONF_INVERTER_SIZE
150  )
151  },
152  ): vol.Coerce(int),
153  }
154  ),
155  errors=errors,
156  )
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:48
ForecastSolarOptionFlowHandler async_get_options_flow(ConfigEntry config_entry)
Definition: config_flow.py:42
ConfigFlowResult async_step_init(self, dict[str, Any]|None user_input=None)
Definition: config_flow.py:96
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_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)