update config_flow source file
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
"""Config flow WF-RAC"""
|
"""Config flow Koolnova"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
@@ -22,157 +22,18 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
|
|
||||||
from .const import CONF_OPERATOR_ID, CONF_AIRCO_ID, DOMAIN
|
#from .const import CONF_OPERATOR_ID, CONF_AIRCO_ID, DOMAIN
|
||||||
from .wfrac.repository import Repository
|
#from .wfrac.repository import Repository
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
class WfRacConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
class KoolnovaConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
"""Handle a config flow."""
|
"""Handle a config flow."""
|
||||||
|
|
||||||
VERSION = 1
|
VERSION = 1
|
||||||
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL
|
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL
|
||||||
_discovery_info = {}
|
|
||||||
DOMAIN = DOMAIN
|
DOMAIN = DOMAIN
|
||||||
|
|
||||||
def _find_entry_matching(self, key, matches):
|
|
||||||
"""Returns the first entry where matches(entry.data[key]) returns True"""
|
|
||||||
for entry in self._async_current_entries():
|
|
||||||
if key in entry.data and matches(entry.data[key]):
|
|
||||||
return entry
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def _async_register_airco(
|
|
||||||
self, hass: HomeAssistant, data: dict
|
|
||||||
) -> dict[str, Any]:
|
|
||||||
"""Validate the user input allows us to connect, and register with the airco device"""
|
|
||||||
if len(data[CONF_HOST]) < 3:
|
|
||||||
raise InvalidHost
|
|
||||||
|
|
||||||
if len(data[CONF_NAME]) < 3:
|
|
||||||
raise InvalidName
|
|
||||||
|
|
||||||
if not data.get(CONF_FORCE_UPDATE):
|
|
||||||
# Is this hostname or IP address already configured?
|
|
||||||
existing_entry = self._find_entry_matching(CONF_HOST, lambda h: h == data[CONF_HOST])
|
|
||||||
if existing_entry:
|
|
||||||
raise HostAlreadyConfigured(error_name=existing_entry.data[CONF_NAME])
|
|
||||||
|
|
||||||
repository = Repository(
|
|
||||||
hass,
|
|
||||||
data[CONF_HOST],
|
|
||||||
data[CONF_PORT],
|
|
||||||
data[CONF_OPERATOR_ID],
|
|
||||||
data[CONF_DEVICE_ID],
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
airco_id = await repository.get_airco_id()
|
|
||||||
except Exception as query_failed:
|
|
||||||
raise CannotConnect(reason=str(query_failed)) from query_failed
|
|
||||||
|
|
||||||
data[CONF_AIRCO_ID] = airco_id
|
|
||||||
if not airco_id:
|
|
||||||
raise CannotConnect(reason="unknown reason")
|
|
||||||
|
|
||||||
_LOGGER.info(
|
|
||||||
"Trying to register OperatorId[%s] on Airco[%s]",
|
|
||||||
data[CONF_OPERATOR_ID],
|
|
||||||
data[CONF_AIRCO_ID],
|
|
||||||
)
|
|
||||||
result = await repository.update_account_info(airco_id, hass.config.time_zone)
|
|
||||||
if not result:
|
|
||||||
raise CannotConnect
|
|
||||||
if int(result["result"]) == 2:
|
|
||||||
raise TooManyDevicesRegistered
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
async def _async_fetch_operator_id(self):
|
|
||||||
"""Fetch UUID operator id if exists otherwise create it"""
|
|
||||||
entry = self._find_entry_matching(CONF_OPERATOR_ID, bool)
|
|
||||||
if entry:
|
|
||||||
return entry.data[CONF_OPERATOR_ID]
|
|
||||||
return f"hassio-{str(uuid4())[7:]}"
|
|
||||||
|
|
||||||
async def _async_fetch_device_id(self):
|
|
||||||
"""Fetch unique device id if exists otherwise create it"""
|
|
||||||
entry = self._find_entry_matching(CONF_DEVICE_ID, bool)
|
|
||||||
if entry:
|
|
||||||
return entry.data[CONF_DEVICE_ID]
|
|
||||||
return f"homeassistant-device-{uuid4().hex[21:]}"
|
|
||||||
|
|
||||||
async def _async_create_common(
|
|
||||||
self,
|
|
||||||
step_id: str,
|
|
||||||
data_schema: vol.Schema = None,
|
|
||||||
user_input: dict[str, Any] | None = None,
|
|
||||||
description_placeholders : dict[str, str] | None = None
|
|
||||||
):
|
|
||||||
"""Create a new entry"""
|
|
||||||
errors = {}
|
|
||||||
description_placeholders = description_placeholders or {}
|
|
||||||
|
|
||||||
if user_input:
|
|
||||||
description_placeholders["error_name"] = ""
|
|
||||||
try:
|
|
||||||
user_input[CONF_OPERATOR_ID] = await self._async_fetch_operator_id()
|
|
||||||
user_input[CONF_DEVICE_ID] = await self._async_fetch_device_id()
|
|
||||||
|
|
||||||
info = await self._async_register_airco(self.hass, user_input)
|
|
||||||
return self.async_create_entry(title=info[CONF_NAME], data=user_input)
|
|
||||||
except KnownError as error:
|
|
||||||
_LOGGER.exception("create failed")
|
|
||||||
errors, placeholders = error.get_errors_and_placeholders(data_schema.schema)
|
|
||||||
errors.update(errors)
|
|
||||||
description_placeholders.update(placeholders)
|
|
||||||
except Exception: # pylint: disable=broad-except
|
|
||||||
_LOGGER.exception("Unexpected exception")
|
|
||||||
errors[CONF_BASE] = "unexpected_error"
|
|
||||||
|
|
||||||
# If there is no user input or there were errors, show the form again, including any errors
|
|
||||||
# that were found with the input.
|
|
||||||
return self.async_show_form(
|
|
||||||
step_id=step_id,
|
|
||||||
data_schema=data_schema,
|
|
||||||
errors=errors,
|
|
||||||
description_placeholders=description_placeholders
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _field(user_input, name, which, default=None):
|
|
||||||
"""Helper for creating schema fields"""
|
|
||||||
value = user_input.get(name, default) if user_input else default
|
|
||||||
description = None
|
|
||||||
if value is not None:
|
|
||||||
description = {"suggested_value": value}
|
|
||||||
return which(name, description=description)
|
|
||||||
|
|
||||||
async def async_step_discovery_confirm(self, user_input=None):
|
|
||||||
"""Handle adding device discovered by zeroconf."""
|
|
||||||
|
|
||||||
description_placeholders = {
|
|
||||||
"id": self._discovery_info[CONF_NAME],
|
|
||||||
"host": self._discovery_info[CONF_HOST],
|
|
||||||
"port": self._discovery_info[CONF_PORT],
|
|
||||||
}
|
|
||||||
|
|
||||||
if user_input:
|
|
||||||
for key in [CONF_HOST, CONF_PORT]:
|
|
||||||
user_input[key] = self._discovery_info[key]
|
|
||||||
|
|
||||||
field = partial(self._field, user_input)
|
|
||||||
data_schema = vol.Schema({
|
|
||||||
field(CONF_NAME, vol.Required, f"Airco {self._discovery_info[CONF_NAME]}") : str,
|
|
||||||
})
|
|
||||||
|
|
||||||
return await self._async_create_common(
|
|
||||||
step_id="discovery_confirm",
|
|
||||||
data_schema=data_schema,
|
|
||||||
user_input=user_input,
|
|
||||||
description_placeholders=description_placeholders
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_step_user(self, user_input=None):
|
async def async_step_user(self, user_input=None):
|
||||||
"""Handle adding device manually."""
|
"""Handle adding device manually."""
|
||||||
|
|
||||||
@@ -190,36 +51,6 @@ class WfRacConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
user_input=user_input
|
user_input=user_input
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_step_zeroconf(
|
|
||||||
self, discovery_info: zeroconf.ZeroconfServiceInfo
|
|
||||||
) -> FlowResult:
|
|
||||||
"""Handle zeroconf discovery."""
|
|
||||||
|
|
||||||
local_name = discovery_info.hostname.rstrip(".")
|
|
||||||
node_name = local_name[: -len(".local")]
|
|
||||||
host = discovery_info.host
|
|
||||||
port = discovery_info.port
|
|
||||||
|
|
||||||
_LOGGER.debug("zeroconf discovery: hostname=%r, host=%r, port=%r",
|
|
||||||
discovery_info.hostname,
|
|
||||||
discovery_info.host,
|
|
||||||
discovery_info.port)
|
|
||||||
|
|
||||||
info = {CONF_HOST: host, CONF_PORT: port}
|
|
||||||
|
|
||||||
await self.async_set_unique_id(node_name)
|
|
||||||
self._abort_if_unique_id_configured(updates=info)
|
|
||||||
|
|
||||||
existing_entry = self._find_entry_matching(CONF_HOST, lambda h: h == host)
|
|
||||||
if existing_entry:
|
|
||||||
_LOGGER.debug("already configured!")
|
|
||||||
return self.async_abort(reason="already_configured")
|
|
||||||
|
|
||||||
info[CONF_NAME] = node_name
|
|
||||||
self._discovery_info = info
|
|
||||||
|
|
||||||
return await self.async_step_discovery_confirm()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _name(self) -> str | None:
|
def _name(self) -> str | None:
|
||||||
return self.context.get(CONF_NAME)
|
return self.context.get(CONF_NAME)
|
||||||
|
|||||||
Reference in New Issue
Block a user