1 """Config flow to configure the IPP integration."""
3 from __future__
import annotations
11 IPPConnectionUpgradeRequired,
15 IPPVersionNotSupportedError,
17 import voluptuous
as vol
32 from .const
import CONF_BASE_PATH, CONF_SERIAL, DOMAIN
34 _LOGGER = logging.getLogger(__name__)
38 """Validate the user input allows us to connect.
40 Data has the keys from DATA_SCHEMA with values provided by the user.
46 base_path=data[CONF_BASE_PATH],
48 verify_ssl=data[CONF_VERIFY_SSL],
52 printer = await ipp.printer()
54 return {CONF_SERIAL: printer.info.serial, CONF_UUID: printer.info.uuid}
58 """Handle an IPP config flow."""
63 """Set up the instance."""
64 self.discovery_info: dict[str, Any] = {}
67 self, user_input: dict[str, Any] |
None =
None
68 ) -> ConfigFlowResult:
69 """Handle a flow initiated by the user."""
70 if user_input
is None:
75 except IPPConnectionUpgradeRequired:
77 except (IPPConnectionError, IPPResponseError):
78 _LOGGER.debug(
"IPP Connection/Response Error", exc_info=
True)
81 _LOGGER.debug(
"IPP Parse Error", exc_info=
True)
83 except IPPVersionNotSupportedError:
86 _LOGGER.debug(
"IPP Error", exc_info=
True)
89 unique_id = user_input[CONF_UUID] = info[CONF_UUID]
91 if not unique_id
and info[CONF_SERIAL]:
93 "Printer UUID is missing from IPP response. Falling back to IPP serial"
96 unique_id = info[CONF_SERIAL]
98 _LOGGER.debug(
"Unable to determine unique id from IPP response")
106 self, discovery_info: zeroconf.ZeroconfServiceInfo
107 ) -> ConfigFlowResult:
108 """Handle zeroconf discovery."""
109 host = discovery_info.host
114 port = discovery_info.port
115 zctype = discovery_info.type
116 name = discovery_info.name.replace(f
".{zctype}",
"")
117 tls = zctype ==
"_ipps._tcp.local."
118 base_path = discovery_info.properties.get(
"rp",
"ipp/print")
119 unique_id = discovery_info.properties.get(
"UUID")
121 self.discovery_info.
update(
126 CONF_VERIFY_SSL:
False,
127 CONF_BASE_PATH: f
"/{base_path}",
129 CONF_UUID: unique_id,
139 self.context.
update({
"title_placeholders": {
"name": name}})
143 except IPPConnectionUpgradeRequired:
145 except (IPPConnectionError, IPPResponseError):
146 _LOGGER.debug(
"IPP Connection/Response Error", exc_info=
True)
148 except IPPParseError:
149 _LOGGER.debug(
"IPP Parse Error", exc_info=
True)
151 except IPPVersionNotSupportedError:
154 _LOGGER.debug(
"IPP Error", exc_info=
True)
157 if not unique_id
and info[CONF_UUID]:
159 "Printer UUID is missing from discovery info. Falling back to IPP UUID"
161 unique_id = self.discovery_info[CONF_UUID] = info[CONF_UUID]
162 elif not unique_id
and info[CONF_SERIAL]:
164 "Printer UUID is missing from discovery info and IPP response. Falling"
165 " back to IPP serial number"
167 unique_id = info[CONF_SERIAL]
170 "Unable to determine unique id from discovery info and IPP response"
173 if unique_id
and self.
unique_idunique_id != unique_id:
182 """Set the unique ID and abort if already configured."""
186 CONF_HOST: self.discovery_info[CONF_HOST],
187 CONF_NAME: self.discovery_info[CONF_NAME],
192 self, user_input: dict[str, Any] |
None =
None
193 ) -> ConfigFlowResult:
194 """Handle a confirmation flow initiated by zeroconf."""
195 if user_input
is None:
197 step_id=
"zeroconf_confirm",
198 description_placeholders={
"name": self.discovery_info[CONF_NAME]},
203 title=self.discovery_info[CONF_NAME],
204 data=self.discovery_info,
208 """Show the setup form to the user."""
211 data_schema=vol.Schema(
213 vol.Required(CONF_HOST): str,
214 vol.Required(CONF_PORT, default=631): int,
215 vol.Required(CONF_BASE_PATH, default=
"/ipp/print"): str,
216 vol.Required(CONF_SSL, default=
False): bool,
217 vol.Required(CONF_VERIFY_SSL, default=
False): bool,
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_zeroconf(self, zeroconf.ZeroconfServiceInfo discovery_info)
ConfigFlowResult _show_setup_form(self, dict|None errors=None)
ConfigFlowResult async_step_zeroconf_confirm(self, dict[str, Any]|None user_input=None)
None _async_set_unique_id_and_abort_if_already_configured(self, str unique_id)
None _abort_if_unique_id_configured(self, dict[str, Any]|None updates=None, bool reload_on_update=True, *str error="already_configured")
None _async_handle_discovery_without_unique_id(self)
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_abort(self, *str reason, Mapping[str, str]|None description_placeholders=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)
_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)
dict[str, Any] validate_input(HomeAssistant hass, dict data)
IssData update(pyiss.ISS iss)
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)