1 """Config flow for the Home Assistant SkyConnect integration."""
3 from __future__
import annotations
5 from abc
import ABC, abstractmethod
10 from universal_silabs_flasher.const
import ApplicationType
19 probe_silabs_firmware_type,
32 from .
import silabs_multiprotocol_addon
33 from .const
import ZHA_DOMAIN
35 get_otbr_addon_manager,
37 get_zigbee_flasher_addon_manager,
40 _LOGGER = logging.getLogger(__name__)
42 STEP_PICK_FIRMWARE_THREAD =
"pick_firmware_thread"
43 STEP_PICK_FIRMWARE_ZIGBEE =
"pick_firmware_zigbee"
47 """Base flow to install firmware."""
49 _failed_addon_name: str
50 _failed_addon_reason: str
52 def __init__(self, *args: Any, **kwargs: Any) ->
None:
53 """Instantiate base flow."""
57 self._device: str |
None =
None
58 self._hardware_name: str =
"unknown"
65 """Shared translation placeholders."""
72 "model": self._hardware_name,
75 self.context[
"title_placeholders"] = placeholders
80 self, config: dict, addon_manager: AddonManager
82 """Set add-on config."""
84 await addon_manager.async_set_addon_options(config)
85 except AddonError
as err:
88 "addon_set_config_failed",
89 description_placeholders={
91 "addon_name": addon_manager.addon_name,
96 """Return add-on info."""
98 addon_info = await addon_manager.async_get_addon_info()
99 except AddonError
as err:
103 description_placeholders={
105 "addon_name": addon_manager.addon_name,
112 self, user_input: dict[str, Any] |
None =
None
113 ) -> ConfigFlowResult:
114 """Pick Thread or Zigbee firmware."""
116 step_id=
"pick_firmware",
118 STEP_PICK_FIRMWARE_ZIGBEE,
119 STEP_PICK_FIRMWARE_THREAD,
125 """Probe the firmware currently on the device."""
126 assert self._device
is not None
132 ApplicationType.GECKO_BOOTLOADER,
133 ApplicationType.EZSP,
134 ApplicationType.SPINEL,
140 ApplicationType.EZSP,
141 ApplicationType.SPINEL,
146 self, user_input: dict[str, Any] |
None =
None
147 ) -> ConfigFlowResult:
148 """Pick Zigbee firmware."""
151 reason=
"unsupported_firmware",
169 if addon_info.state == AddonState.NOT_INSTALLED:
172 if addon_info.state == AddonState.NOT_RUNNING:
177 reason=
"addon_already_running",
178 description_placeholders={
180 "addon_name": fw_flasher_manager.addon_name,
185 self, user_input: dict[str, Any] |
None =
None
186 ) -> ConfigFlowResult:
187 """Show progress dialog for installing the Zigbee flasher addon."""
190 "install_zigbee_flasher_addon",
191 "run_zigbee_flasher_addon",
196 addon_manager: silabs_multiprotocol_addon.WaitingAddonManager,
199 ) -> ConfigFlowResult:
200 """Show progress dialog for installing an addon."""
203 _LOGGER.debug(
"Flasher addon state: %s", addon_info)
207 addon_manager.async_install_addon_waiting(),
214 progress_action=
"install_addon",
215 description_placeholders={
217 "addon_name": addon_manager.addon_name,
224 except AddonError
as err:
235 self, user_input: dict[str, Any] |
None =
None
236 ) -> ConfigFlowResult:
237 """Abort when add-on installation or start failed."""
240 description_placeholders={
247 self, user_input: dict[str, Any] |
None =
None
248 ) -> ConfigFlowResult:
249 """Configure the flasher addon to point to the SkyConnect and run it."""
253 assert self._device
is not None
255 **addon_info.options,
256 "device": self._device,
258 "bootloader_baudrate": 115200,
259 "flow_control":
True,
262 _LOGGER.debug(
"Reconfiguring flasher addon with %s", new_addon_config)
267 async
def start_and_wait_until_done() -> None:
268 await fw_flasher_manager.async_start_addon_waiting()
270 await fw_flasher_manager.async_wait_until_addon_state(
271 AddonState.NOT_RUNNING
275 start_and_wait_until_done()
280 step_id=
"run_zigbee_flasher_addon",
281 progress_action=
"run_zigbee_flasher_addon",
282 description_placeholders={
284 "addon_name": fw_flasher_manager.addon_name,
291 except (AddonError, AbortFlow)
as err:
300 next_step_id=
"uninstall_zigbee_flasher_addon"
304 self, user_input: dict[str, Any] |
None =
None
305 ) -> ConfigFlowResult:
306 """Uninstall the flasher addon."""
310 _LOGGER.debug(
"Uninstalling flasher addon")
312 fw_flasher_manager.async_uninstall_addon_waiting()
317 step_id=
"uninstall_zigbee_flasher_addon",
318 progress_action=
"uninstall_zigbee_flasher_addon",
319 description_placeholders={
321 "addon_name": fw_flasher_manager.addon_name,
328 except (AddonError, AbortFlow)
as err:
337 self, user_input: dict[str, Any] |
None =
None
338 ) -> ConfigFlowResult:
339 """Confirm Zigbee setup."""
340 assert self._device
is not None
341 assert self._hardware_name
is not None
344 if user_input
is not None:
345 await self.hass.config_entries.flow.async_init(
347 context={
"source":
"hardware"},
349 "name": self._hardware_name,
351 "path": self._device,
353 "flow_control":
"hardware",
355 "radio_type":
"ezsp",
362 step_id=
"confirm_zigbee",
367 self, user_input: dict[str, Any] |
None =
None
368 ) -> ConfigFlowResult:
369 """Pick Thread firmware."""
372 reason=
"unsupported_firmware",
379 reason=
"not_hassio_thread",
386 if addon_info.state == AddonState.NOT_INSTALLED:
389 if addon_info.state == AddonState.NOT_RUNNING:
394 reason=
"otbr_addon_already_running",
395 description_placeholders={
397 "addon_name": otbr_manager.addon_name,
402 self, user_input: dict[str, Any] |
None =
None
403 ) -> ConfigFlowResult:
404 """Show progress dialog for installing the OTBR addon."""
410 self, user_input: dict[str, Any] |
None =
None
411 ) -> ConfigFlowResult:
412 """Configure OTBR to point to the SkyConnect and run the addon."""
416 assert self._device
is not None
418 **addon_info.options,
419 "device": self._device,
421 "flow_control":
True,
422 "autoflash_firmware":
True,
425 _LOGGER.debug(
"Reconfiguring OTBR addon with %s", new_addon_config)
430 otbr_manager.async_start_addon_waiting()
435 step_id=
"start_otbr_addon",
436 progress_action=
"start_otbr_addon",
437 description_placeholders={
439 "addon_name": otbr_manager.addon_name,
446 except (AddonError, AbortFlow)
as err:
457 self, user_input: dict[str, Any] |
None =
None
458 ) -> ConfigFlowResult:
459 """Confirm OTBR setup."""
460 assert self._device
is not None
464 if user_input
is not None:
469 step_id=
"confirm_otbr",
475 """Finish the flow."""
476 raise NotImplementedError
480 """Base config flow for installing firmware."""
486 config_entry: ConfigEntry,
488 """Return the options flow."""
489 raise NotImplementedError
492 self, user_input: dict[str, Any] |
None =
None
493 ) -> ConfigFlowResult:
494 """Confirm a discovery."""
499 """Zigbee and Thread options flow handlers."""
501 def __init__(self, config_entry: ConfigEntry, *args: Any, **kwargs: Any) ->
None:
502 """Instantiate options flow."""
515 self, user_input: dict[str, Any] |
None =
None
516 ) -> ConfigFlowResult:
517 """Manage the options flow."""
521 self, user_input: dict[str, Any] |
None =
None
522 ) -> ConfigFlowResult:
523 """Pick Zigbee firmware."""
524 assert self._device
is not None
531 otbr_addon_info.state != AddonState.NOT_INSTALLED
532 and otbr_addon_info.options.get(
"device") == self._device
535 "otbr_still_using_stick",
542 self, user_input: dict[str, Any] |
None =
None
543 ) -> ConfigFlowResult:
544 """Pick Thread firmware."""
545 assert self._device
is not None
547 for zha_entry
in self.hass.config_entries.async_entries(
549 include_ignore=
False,
550 include_disabled=
True,
554 "zha_still_using_stick",
ConfigFlowResult async_step_confirm(self, dict[str, Any]|None user_input=None)
OptionsFlow async_get_options_flow(ConfigEntry config_entry)
ConfigFlowResult async_step_install_zigbee_flasher_addon(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_run_zigbee_flasher_addon(self, dict[str, Any]|None user_input=None)
ConfigFlowResult _async_flow_finished(self)
AddonInfo _async_get_addon_info(self, AddonManager addon_manager)
dict[str, str] _get_translation_placeholders(self)
bool _probe_firmware_type(self)
ConfigFlowResult async_step_confirm_otbr(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_pick_firmware_zigbee(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_confirm_zigbee(self, dict[str, Any]|None user_input=None)
ConfigFlowResult _install_addon(self, silabs_multiprotocol_addon.WaitingAddonManager addon_manager, str step_id, str next_step_id)
ConfigFlowResult async_step_addon_operation_failed(self, dict[str, Any]|None user_input=None)
None _async_set_addon_config(self, dict config, AddonManager addon_manager)
ConfigFlowResult async_step_start_otbr_addon(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_pick_firmware(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_install_otbr_addon(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_pick_firmware_thread(self, dict[str, Any]|None user_input=None)
None __init__(self, *Any args, **Any kwargs)
ConfigFlowResult async_step_uninstall_zigbee_flasher_addon(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_pick_firmware_thread(self, dict[str, Any]|None user_input=None)
ConfigFlowResult async_step_init(self, dict[str, Any]|None user_input=None)
None __init__(self, ConfigEntry config_entry, *Any args, **Any kwargs)
ConfigFlowResult async_step_pick_firmware_zigbee(self, dict[str, Any]|None user_input=None)
ConfigEntry config_entry(self)
None config_entry(self, ConfigEntry value)
_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_show_progress(self, *str|None step_id=None, str progress_action, Mapping[str, str]|None description_placeholders=None, asyncio.Task[Any]|None progress_task=None)
_FlowResultT async_show_menu(self, *str|None step_id=None, Container[str] menu_options, Mapping[str, str]|None description_placeholders=None)
_FlowResultT async_show_progress_done(self, *str next_step_id)
_FlowResultT async_abort(self, *str reason, Mapping[str, str]|None description_placeholders=None)
bool is_hassio(HomeAssistant hass)
WaitingAddonManager get_zigbee_flasher_addon_manager(HomeAssistant hass)
WaitingAddonManager get_otbr_addon_manager(HomeAssistant hass)
str|None get_zha_device_path(ConfigEntry config_entry)
ApplicationType|None probe_silabs_firmware_type(str device, *ApplicationType|None probe_methods=None)