1 """Config flow for Aurora ABB PowerOne integration."""
3 from __future__
import annotations
5 from collections.abc
import Mapping
7 from typing
import TYPE_CHECKING, Any
9 from aurorapy.client
import AuroraError, AuroraSerialClient
10 import serial.tools.list_ports
11 import voluptuous
as vol
21 DEFAULT_INTEGRATION_TITLE,
27 _LOGGER = logging.getLogger(__name__)
31 hass: HomeAssistant, data: Mapping[str, Any]
33 """Validate the user input allows us to connect.
35 Data has the keys from DATA_SCHEMA with values provided by the user.
37 comport = data[CONF_PORT]
38 address = data[CONF_ADDRESS]
39 _LOGGER.debug(
"Initialising com port=%s", comport)
41 ret[
"title"] = DEFAULT_INTEGRATION_TITLE
43 client = AuroraSerialClient(address, comport, parity=
"N", timeout=1)
45 ret[ATTR_SERIAL_NUMBER] = client.serial_number()
46 ret[ATTR_MODEL] = f
"{client.version()} ({client.pn()})"
47 ret[ATTR_FIRMWARE] = client.firmware(1)
48 _LOGGER.debug(
"Returning device info=%s", ret)
50 _LOGGER.warning(
"Could not connect to device=%s", comport)
53 if client.serline.isOpen():
61 """Find and store available com ports for the GUI dropdown."""
62 com_ports = serial.tools.list_ports.comports(include_links=
True)
64 for port
in com_ports:
65 com_ports_list.append(port.device)
66 _LOGGER.debug(
"COM port option: %s", port.device)
67 if len(com_ports_list) > 0:
68 return com_ports_list, com_ports_list[0]
69 _LOGGER.warning(
"No com ports found. Need a valid RS485 device to communicate")
74 """Handle a config flow for Aurora ABB PowerOne."""
79 """Initialise the config flow."""
80 self._com_ports_list: list[str] |
None =
None
84 self, user_input: dict[str, Any] |
None =
None
85 ) -> ConfigFlowResult:
86 """Handle a flow initialised by the user."""
89 if self._com_ports_list
is None:
90 result = await self.hass.async_add_executor_job(scan_comports)
95 assert isinstance(self._com_ports_list, list)
98 if user_input
is not None:
100 info = await self.hass.async_add_executor_job(
101 validate_and_connect, self.hass, user_input
103 except OSError
as error:
104 if error.errno == 19:
105 errors[
"base"] =
"invalid_serial_port"
106 except AuroraError
as error:
107 if "could not open port" in str(error):
108 errors[
"base"] =
"cannot_open_serial_port"
109 elif "No response after" in str(error):
110 errors[
"base"] =
"cannot_connect"
113 "Unable to communicate with Aurora ABB Inverter at %s: %s %s",
114 user_input[CONF_PORT],
118 errors[
"base"] =
"cannot_connect"
120 info.update(user_input)
122 device_unique_id = info[
"serial_number"]
129 vol.Required(CONF_PORT, default=self.
_default_com_port_default_com_port): vol.In(
132 vol.Required(CONF_ADDRESS, default=DEFAULT_ADDRESS): vol.In(
133 range(MIN_ADDRESS, MAX_ADDRESS + 1)
136 schema = vol.Schema(config_options)
ConfigFlowResult async_step_user(self, dict[str, Any]|None user_input=None)
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)
ConfigFlowResult async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=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, str] validate_and_connect(HomeAssistant hass, Mapping[str, Any] data)
tuple[list[str]|None, str|None] scan_comports()