We can see myq on the network to tell them to configure it, but since the device will not give up the account it is bound to and there can be multiple myq gateways on a single account, we avoid showing the device as discovered once they already have one configured as they can always add a new one via "+"
92 lines
3.1 KiB
Python
92 lines
3.1 KiB
Python
"""Config flow for MyQ integration."""
|
|
import logging
|
|
|
|
import pymyq
|
|
from pymyq.errors import InvalidCredentialsError, MyQError
|
|
import voluptuous as vol
|
|
|
|
from homeassistant import config_entries, core, exceptions
|
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
|
from homeassistant.helpers import aiohttp_client
|
|
|
|
from .const import DOMAIN # pylint:disable=unused-import
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
DATA_SCHEMA = vol.Schema(
|
|
{vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str}
|
|
)
|
|
|
|
|
|
async def validate_input(hass: core.HomeAssistant, data):
|
|
"""Validate the user input allows us to connect.
|
|
|
|
Data has the keys from DATA_SCHEMA with values provided by the user.
|
|
"""
|
|
|
|
websession = aiohttp_client.async_get_clientsession(hass)
|
|
|
|
try:
|
|
await pymyq.login(data[CONF_USERNAME], data[CONF_PASSWORD], websession)
|
|
except InvalidCredentialsError:
|
|
raise InvalidAuth
|
|
except MyQError:
|
|
raise CannotConnect
|
|
|
|
return {"title": data[CONF_USERNAME]}
|
|
|
|
|
|
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|
"""Handle a config flow for MyQ."""
|
|
|
|
VERSION = 1
|
|
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
|
|
|
|
async def async_step_user(self, user_input=None):
|
|
"""Handle the initial step."""
|
|
errors = {}
|
|
if user_input is not None:
|
|
try:
|
|
info = await validate_input(self.hass, user_input)
|
|
except CannotConnect:
|
|
errors["base"] = "cannot_connect"
|
|
except InvalidAuth:
|
|
errors["base"] = "invalid_auth"
|
|
except Exception: # pylint: disable=broad-except
|
|
_LOGGER.exception("Unexpected exception")
|
|
errors["base"] = "unknown"
|
|
|
|
if "base" not in errors:
|
|
await self.async_set_unique_id(user_input[CONF_USERNAME])
|
|
self._abort_if_unique_id_configured()
|
|
return self.async_create_entry(title=info["title"], data=user_input)
|
|
|
|
return self.async_show_form(
|
|
step_id="user", data_schema=DATA_SCHEMA, errors=errors
|
|
)
|
|
|
|
async def async_step_homekit(self, homekit_info):
|
|
"""Handle HomeKit discovery."""
|
|
if self._async_current_entries():
|
|
# We can see myq on the network to tell them to configure
|
|
# it, but since the device will not give up the account it is
|
|
# bound to and there can be multiple myq gateways on a single
|
|
# account, we avoid showing the device as discovered once
|
|
# they already have one configured as they can always
|
|
# add a new one via "+"
|
|
return self.async_abort(reason="already_configured")
|
|
return await self.async_step_user()
|
|
|
|
async def async_step_import(self, user_input):
|
|
"""Handle import."""
|
|
await self.async_set_unique_id(user_input[CONF_USERNAME])
|
|
self._abort_if_unique_id_configured()
|
|
return await self.async_step_user(user_input)
|
|
|
|
|
|
class CannotConnect(exceptions.HomeAssistantError):
|
|
"""Error to indicate we cannot connect."""
|
|
|
|
|
|
class InvalidAuth(exceptions.HomeAssistantError):
|
|
"""Error to indicate there is invalid auth."""
|