1 """Config flow for Somfy MyLink integration."""
3 from __future__
import annotations
5 from copy
import deepcopy
9 from somfy_mylink_synergy
import SomfyMyLinkSynergy
10 import voluptuous
as vol
27 CONF_REVERSED_TARGET_IDS,
36 _LOGGER = logging.getLogger(__name__)
40 """Validate the user input allows us to connect.
42 Data has the keys from schema with values provided by the user.
44 somfy_mylink = SomfyMyLinkSynergy(
45 data[CONF_SYSTEM_ID], data[CONF_HOST], data[CONF_PORT]
49 status_info = await somfy_mylink.status_info()
50 except TimeoutError
as ex:
51 raise CannotConnect
from ex
53 if not status_info
or "error" in status_info:
54 _LOGGER.debug(
"Auth error: %s", status_info)
57 return {
"title": f
"MyLink {data[CONF_HOST]}"}
61 """Handle a config flow for Somfy MyLink."""
66 """Initialize the somfy_mylink flow."""
67 self.
hosthost: str |
None =
None
68 self.
macmac: str |
None =
None
72 self, discovery_info: dhcp.DhcpServiceInfo
73 ) -> ConfigFlowResult:
74 """Handle dhcp discovery."""
77 formatted_mac =
format_mac(discovery_info.macaddress)
80 self.
hosthost = discovery_info.hostname
81 self.
macmac = formatted_mac
83 self.context[
"title_placeholders"] = {
"ip": self.
ip_addressip_address,
"mac": self.
macmac}
87 self, user_input: dict[str, Any] |
None =
None
88 ) -> ConfigFlowResult:
89 """Handle the initial step."""
92 if user_input
is not None:
98 errors[
"base"] =
"cannot_connect"
100 errors[
"base"] =
"invalid_auth"
102 _LOGGER.exception(
"Unexpected exception")
103 errors[
"base"] =
"unknown"
109 data_schema=vol.Schema(
111 vol.Required(CONF_HOST, default=self.
ip_addressip_address): str,
112 vol.Required(CONF_SYSTEM_ID): str,
113 vol.Optional(CONF_PORT, default=DEFAULT_PORT): int,
122 config_entry: ConfigEntry,
123 ) -> OptionsFlowHandler:
124 """Get the options flow for this handler."""
129 """Handle a option flow for somfy_mylink."""
131 def __init__(self, config_entry: ConfigEntry) ->
None:
132 """Initialize options flow."""
138 """Return the list of targets."""
145 """Find the name of a target in the api data."""
147 for cover
in mylink_targets:
148 if cover[
"targetID"] == target_id:
153 self, user_input: dict[str, Any] |
None =
None
154 ) -> ConfigFlowResult:
155 """Handle options flow."""
158 _LOGGER.error(
"MyLink must be connected to manage device options")
159 return self.
async_abortasync_abort(reason=
"cannot_connect")
161 if user_input
is not None:
162 if target_id := user_input.get(CONF_TARGET_ID):
167 cover_dict = {
None:
None}
170 for cover
in mylink_targets:
171 cover_dict[cover[
"targetID"]] = cover[
"name"]
173 data_schema = vol.Schema({vol.Optional(CONF_TARGET_ID): vol.In(cover_dict)})
175 return self.
async_show_formasync_show_form(step_id=
"init", data_schema=data_schema, errors={})
178 self, user_input: dict[str, bool] |
None =
None, target_id: str |
None =
None
179 ) -> ConfigFlowResult:
180 """Handle options flow for target."""
181 reversed_target_ids: dict[str |
None, bool] = self.
optionsoptions.setdefault(
182 CONF_REVERSED_TARGET_IDS, {}
185 if user_input
is not None:
186 if user_input[CONF_REVERSE] != reversed_target_ids.get(self.
_target_id_target_id):
187 reversed_target_ids[self.
_target_id_target_id] = user_input[CONF_REVERSE]
193 step_id=
"target_config",
194 data_schema=vol.Schema(
198 default=reversed_target_ids.get(target_id,
False),
202 description_placeholders={
210 """Error to indicate we cannot connect."""
213 class InvalidAuth(HomeAssistantError):
214 """Error to indicate there is invalid auth."""
None __init__(self, ConfigEntry config_entry)
ConfigFlowResult async_step_target_config(self, dict[str, bool]|None user_input=None, str|None target_id=None)
def _async_callback_targets(self)
ConfigFlowResult async_step_init(self, dict[str, Any]|None user_input=None)
str _async_get_target_name(self, target_id)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
OptionsFlowHandler async_get_options_flow(ConfigEntry config_entry)
ConfigFlowResult async_step_dhcp(self, dhcp.DhcpServiceInfo discovery_info)
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_step_user(self, dict[str, Any]|None user_input=None)
None _async_abort_entries_match(self, dict[str, Any]|None match_dict=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)
ConfigEntry config_entry(self)
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)
def validate_input(HomeAssistant hass, data)