Skip to content

Commit

Permalink
Simplify SkyConnect setup flow (#117868)
Browse files Browse the repository at this point in the history
* Delay firmware probing until after the user picks the firmware type

* Remove confirmation step

* Fix unit tests

* Simplify unit test patching logic

Further simplify unit tests

* Bump Zigbee firmware up to the first choice

* Reuse `async_step_pick_firmware` during options flow

* Proactively validate all ZHA entries, not just the first
There can only be one (for now) so this changes nothing functionally

* Add unit test for bad firmware when configuring Thread
  • Loading branch information
puddly committed May 22, 2024
1 parent 6113b58 commit 55c8ef1
Show file tree
Hide file tree
Showing 4 changed files with 293 additions and 699 deletions.
75 changes: 33 additions & 42 deletions homeassistant/components/homeassistant_sky_connect/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,17 @@ async def async_step_pick_firmware(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Pick Thread or Zigbee firmware."""
return self.async_show_menu(
step_id="pick_firmware",
menu_options=[
STEP_PICK_FIRMWARE_ZIGBEE,
STEP_PICK_FIRMWARE_THREAD,
],
description_placeholders=self._get_translation_placeholders(),
)

async def _probe_firmware_type(self) -> bool:
"""Probe the firmware currently on the device."""
assert self._usb_info is not None

self._probed_firmware_type = await probe_silabs_firmware_type(
Expand All @@ -134,29 +145,22 @@ async def async_step_pick_firmware(
),
)

if self._probed_firmware_type not in (
return self._probed_firmware_type in (
ApplicationType.EZSP,
ApplicationType.SPINEL,
ApplicationType.CPC,
):
return self.async_abort(
reason="unsupported_firmware",
description_placeholders=self._get_translation_placeholders(),
)

return self.async_show_menu(
step_id="pick_firmware",
menu_options=[
STEP_PICK_FIRMWARE_THREAD,
STEP_PICK_FIRMWARE_ZIGBEE,
],
description_placeholders=self._get_translation_placeholders(),
)

async def async_step_pick_firmware_zigbee(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Pick Zigbee firmware."""
if not await self._probe_firmware_type():
return self.async_abort(
reason="unsupported_firmware",
description_placeholders=self._get_translation_placeholders(),
)

# Allow the stick to be used with ZHA without flashing
if self._probed_firmware_type == ApplicationType.EZSP:
return await self.async_step_confirm_zigbee()
Expand Down Expand Up @@ -372,6 +376,12 @@ async def async_step_pick_firmware_thread(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Pick Thread firmware."""
if not await self._probe_firmware_type():
return self.async_abort(
reason="unsupported_firmware",
description_placeholders=self._get_translation_placeholders(),
)

# We install the OTBR addon no matter what, since it is required to use Thread
if not is_hassio(self.hass):
return self.async_abort(
Expand Down Expand Up @@ -528,17 +538,7 @@ async def async_step_confirm(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Confirm a discovery."""
self._set_confirm_only()

# Without confirmation, discovery can automatically progress into parts of the
# config flow logic that interacts with hardware.
if user_input is not None:
return await self.async_step_pick_firmware()

return self.async_show_form(
step_id="confirm",
description_placeholders=self._get_translation_placeholders(),
)
return await self.async_step_pick_firmware()

def _async_flow_finished(self) -> ConfigFlowResult:
"""Create the config entry."""
Expand Down Expand Up @@ -641,15 +641,7 @@ async def async_step_init(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Manage the options flow."""
# Don't probe the running firmware, we load it from the config entry
return self.async_show_menu(
step_id="pick_firmware",
menu_options=[
STEP_PICK_FIRMWARE_THREAD,
STEP_PICK_FIRMWARE_ZIGBEE,
],
description_placeholders=self._get_translation_placeholders(),
)
return await self.async_step_pick_firmware()

async def async_step_pick_firmware_zigbee(
self, user_input: dict[str, Any] | None = None
Expand Down Expand Up @@ -678,17 +670,16 @@ async def async_step_pick_firmware_thread(
"""Pick Thread firmware."""
assert self._usb_info is not None

zha_entries = self.hass.config_entries.async_entries(
for zha_entry in self.hass.config_entries.async_entries(
ZHA_DOMAIN,
include_ignore=False,
include_disabled=True,
)

if zha_entries and get_zha_device_path(zha_entries[0]) == self._usb_info.device:
raise AbortFlow(
"zha_still_using_stick",
description_placeholders=self._get_translation_placeholders(),
)
):
if get_zha_device_path(zha_entry) == self._usb_info.device:
raise AbortFlow(
"zha_still_using_stick",
description_placeholders=self._get_translation_placeholders(),
)

return await super().async_step_pick_firmware_thread(user_input)

Expand Down
14 changes: 3 additions & 11 deletions homeassistant/components/homeassistant_sky_connect/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,6 @@
"title": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::step::start_flasher_addon::title%]",
"description": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::step::start_flasher_addon::description%]"
},
"confirm": {
"title": "[%key:component::homeassistant_sky_connect::config::step::confirm::title%]",
"description": "[%key:component::homeassistant_sky_connect::config::step::confirm::description%]"
},
"pick_firmware": {
"title": "[%key:component::homeassistant_sky_connect::config::step::pick_firmware::title%]",
"description": "[%key:component::homeassistant_sky_connect::config::step::pick_firmware::description%]",
Expand Down Expand Up @@ -131,16 +127,12 @@
"config": {
"flow_title": "{model}",
"step": {
"confirm": {
"title": "Set up the {model}",
"description": "The {model} can be used as either a Thread border router or a Zigbee coordinator. In the next step, you will choose which firmware will be configured."
},
"pick_firmware": {
"title": "Pick your firmware",
"description": "The {model} can be used as a Thread border router or a Zigbee coordinator.",
"description": "Let's get started with setting up your {model}. Do you want to use it to set up a Zigbee or Thread network?",
"menu_options": {
"pick_firmware_thread": "Use as a Thread border router",
"pick_firmware_zigbee": "Use as a Zigbee coordinator"
"pick_firmware_zigbee": "Zigbee",
"pick_firmware_thread": "Thread"
}
},
"install_zigbee_flasher_addon": {
Expand Down
Loading

0 comments on commit 55c8ef1

Please sign in to comment.