"""Adds config flow for Brother Printer.""" import ipaddress import re from brother import Brother, SnmpError, UnsupportedModel import voluptuous as vol from homeassistant import config_entries, exceptions from homeassistant.const import CONF_HOST, CONF_TYPE from .const import DOMAIN, PRINTER_TYPES # pylint:disable=unused-import DATA_SCHEMA = vol.Schema( { vol.Required(CONF_HOST, default=""): str, vol.Optional(CONF_TYPE, default="laser"): vol.In(PRINTER_TYPES), } ) def host_valid(host): """Return True if hostname or IP address is valid.""" try: if ipaddress.ip_address(host).version == (4 or 6): return True except ValueError: disallowed = re.compile(r"[^a-zA-Z\d\-]") return all(x and not disallowed.search(x) for x in host.split(".")) class BrotherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Handle a config flow for Brother Printer.""" VERSION = 1 CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL async def async_step_user(self, user_input=None): """Handle the initial step.""" errors = {} if user_input is not None: try: if not host_valid(user_input[CONF_HOST]): raise InvalidHost() brother = Brother(user_input[CONF_HOST]) await brother.async_update() await self.async_set_unique_id(brother.serial.lower()) self._abort_if_unique_id_configured() title = f"{brother.model} {brother.serial}" return self.async_create_entry(title=title, data=user_input) except InvalidHost: errors[CONF_HOST] = "wrong_host" except ConnectionError: errors["base"] = "connection_error" except SnmpError: errors["base"] = "snmp_error" except UnsupportedModel: return self.async_abort(reason="unsupported_model") return self.async_show_form( step_id="user", data_schema=DATA_SCHEMA, errors=errors ) class InvalidHost(exceptions.HomeAssistantError): """Error to indicate that hostname/IP address is invalid."""