1 """Config flow for Plugwise integration."""
3 from __future__
import annotations
5 from typing
import Any, Self
7 from plugwise
import Smile
8 from plugwise.exceptions
import (
10 InvalidAuthentication,
14 UnsupportedDeviceError,
16 import voluptuous
as vol
21 ATTR_CONFIGURATION_URL,
45 def base_schema(discovery_info: ZeroconfServiceInfo |
None) -> vol.Schema:
46 """Generate base schema for gateways."""
47 schema = vol.Schema({vol.Required(CONF_PASSWORD): str})
49 if not discovery_info:
50 schema = schema.extend(
52 vol.Required(CONF_HOST): str,
53 vol.Optional(CONF_PORT, default=DEFAULT_PORT): int,
54 vol.Required(CONF_USERNAME, default=SMILE): vol.In(
55 {SMILE: FLOW_SMILE, STRETCH: FLOW_STRETCH}
63 async
def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> Smile:
64 """Validate whether the user input allows us to connect to the gateway.
66 Data has the keys from base_schema() with values provided by the user.
71 password=data[CONF_PASSWORD],
73 username=data[CONF_USERNAME],
74 websession=websession,
81 """Handle a config flow for Plugwise Smile."""
85 discovery_info: ZeroconfServiceInfo |
None =
None
86 product: str =
"Unknown Smile"
87 _username: str = DEFAULT_USERNAME
90 self, discovery_info: ZeroconfServiceInfo
91 ) -> ConfigFlowResult:
92 """Prepare configuration for a discovered Plugwise Smile."""
94 _properties = discovery_info.properties
96 unique_id = discovery_info.hostname.split(
".")[0].split(
"-")[0]
102 CONF_HOST: discovery_info.host,
103 CONF_PORT: discovery_info.port,
104 CONF_USERNAME: config_entry.data[CONF_USERNAME],
105 CONF_PASSWORD: config_entry.data[CONF_PASSWORD],
113 CONF_HOST: discovery_info.host,
114 CONF_PORT: discovery_info.port,
118 if DEFAULT_USERNAME
not in unique_id:
120 self.
productproduct = _product = _properties.get(
"product",
"Unknown Smile")
121 _version = _properties.get(
"version",
"n/a")
122 _name = f
"{ZEROCONF_MAP.get(_product, _product)} v{_version}"
132 if self.hass.config_entries.flow.async_has_matching_flow(self):
137 "title_placeholders": {CONF_NAME: _name},
138 ATTR_CONFIGURATION_URL: (
139 f
"http://{discovery_info.host}:{discovery_info.port}"
146 """Return True if other_flow is matching this flow."""
148 if self.
productproduct ==
"smile_thermo" and other_flow.product ==
"smile_open_therm":
152 if self.
productproduct ==
"smile_open_therm" and other_flow.product ==
"smile_thermo":
153 self.hass.config_entries.flow.async_abort(other_flow.flow_id)
158 self, user_input: dict[str, Any] |
None =
None
159 ) -> ConfigFlowResult:
160 """Handle the initial step when using network/gateway setups."""
161 errors: dict[str, str] = {}
163 if user_input
is not None:
167 user_input[CONF_USERNAME] = self.
_username_username
171 except ConnectionFailedError:
172 errors[CONF_BASE] =
"cannot_connect"
173 except InvalidAuthentication:
174 errors[CONF_BASE] =
"invalid_auth"
175 except InvalidSetupError:
176 errors[CONF_BASE] =
"invalid_setup"
177 except (InvalidXMLError, ResponseError):
178 errors[CONF_BASE] =
"response_error"
179 except UnsupportedDeviceError:
180 errors[CONF_BASE] =
"unsupported"
182 errors[CONF_BASE] =
"unknown"
185 api.smile_hostname
or api.gateway_id, raise_on_progress=
False
ConfigFlowResult async_step_zeroconf(self, ZeroconfServiceInfo 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)
list[ConfigEntry] _async_current_entries(self, bool|None include_ignore=None)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
bool is_matching(self, Self other_flow)
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)
IssData update(pyiss.ISS iss)
Smile validate_input(HomeAssistant hass, dict[str, Any] data)
vol.Schema base_schema(ZeroconfServiceInfo|None discovery_info)
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)