mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Await firmware installation task when flashing ZBT-1/Yellow firmware (#147824)
This commit is contained in:
parent
88feb5139b
commit
20f5d85800
@ -27,6 +27,7 @@ from homeassistant.config_entries import (
|
|||||||
)
|
)
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.data_entry_flow import AbortFlow
|
from homeassistant.data_entry_flow import AbortFlow
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.hassio import is_hassio
|
from homeassistant.helpers.hassio import is_hassio
|
||||||
|
|
||||||
@ -67,6 +68,7 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|||||||
self.addon_start_task: asyncio.Task | None = None
|
self.addon_start_task: asyncio.Task | None = None
|
||||||
self.addon_uninstall_task: asyncio.Task | None = None
|
self.addon_uninstall_task: asyncio.Task | None = None
|
||||||
self.firmware_install_task: asyncio.Task | None = None
|
self.firmware_install_task: asyncio.Task | None = None
|
||||||
|
self.installing_firmware_name: str | None = None
|
||||||
|
|
||||||
def _get_translation_placeholders(self) -> dict[str, str]:
|
def _get_translation_placeholders(self) -> dict[str, str]:
|
||||||
"""Shared translation placeholders."""
|
"""Shared translation placeholders."""
|
||||||
@ -152,8 +154,12 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|||||||
assert self._device is not None
|
assert self._device is not None
|
||||||
|
|
||||||
if not self.firmware_install_task:
|
if not self.firmware_install_task:
|
||||||
# We 100% need to install new firmware only if the wrong firmware is
|
# Keep track of the firmware we're working with, for error messages
|
||||||
# currently installed
|
self.installing_firmware_name = firmware_name
|
||||||
|
|
||||||
|
# Installing new firmware is only truly required if the wrong type is
|
||||||
|
# installed: upgrading to the latest release of the current firmware type
|
||||||
|
# isn't strictly necessary for functionality.
|
||||||
firmware_install_required = self._probed_firmware_info is None or (
|
firmware_install_required = self._probed_firmware_info is None or (
|
||||||
self._probed_firmware_info.firmware_type
|
self._probed_firmware_info.firmware_type
|
||||||
!= expected_installed_firmware_type
|
!= expected_installed_firmware_type
|
||||||
@ -167,7 +173,7 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|||||||
fw_manifest = next(
|
fw_manifest = next(
|
||||||
fw for fw in manifest.firmwares if fw.filename.startswith(fw_type)
|
fw for fw in manifest.firmwares if fw.filename.startswith(fw_type)
|
||||||
)
|
)
|
||||||
except (StopIteration, TimeoutError, ClientError, ManifestMissing) as err:
|
except (StopIteration, TimeoutError, ClientError, ManifestMissing):
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Failed to fetch firmware update manifest", exc_info=True
|
"Failed to fetch firmware update manifest", exc_info=True
|
||||||
)
|
)
|
||||||
@ -179,13 +185,9 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|||||||
)
|
)
|
||||||
return self.async_show_progress_done(next_step_id=next_step_id)
|
return self.async_show_progress_done(next_step_id=next_step_id)
|
||||||
|
|
||||||
raise AbortFlow(
|
return self.async_show_progress_done(
|
||||||
"fw_download_failed",
|
next_step_id="firmware_download_failed"
|
||||||
description_placeholders={
|
)
|
||||||
**self._get_translation_placeholders(),
|
|
||||||
"firmware_name": firmware_name,
|
|
||||||
},
|
|
||||||
) from err
|
|
||||||
|
|
||||||
if not firmware_install_required:
|
if not firmware_install_required:
|
||||||
assert self._probed_firmware_info is not None
|
assert self._probed_firmware_info is not None
|
||||||
@ -205,7 +207,7 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
fw_data = await client.async_fetch_firmware(fw_manifest)
|
fw_data = await client.async_fetch_firmware(fw_manifest)
|
||||||
except (TimeoutError, ClientError, ValueError) as err:
|
except (TimeoutError, ClientError, ValueError):
|
||||||
_LOGGER.warning("Failed to fetch firmware update", exc_info=True)
|
_LOGGER.warning("Failed to fetch firmware update", exc_info=True)
|
||||||
|
|
||||||
# If we cannot download new firmware, we shouldn't block setup
|
# If we cannot download new firmware, we shouldn't block setup
|
||||||
@ -216,13 +218,9 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|||||||
return self.async_show_progress_done(next_step_id=next_step_id)
|
return self.async_show_progress_done(next_step_id=next_step_id)
|
||||||
|
|
||||||
# Otherwise, fail
|
# Otherwise, fail
|
||||||
raise AbortFlow(
|
return self.async_show_progress_done(
|
||||||
"fw_download_failed",
|
next_step_id="firmware_download_failed"
|
||||||
description_placeholders={
|
)
|
||||||
**self._get_translation_placeholders(),
|
|
||||||
"firmware_name": firmware_name,
|
|
||||||
},
|
|
||||||
) from err
|
|
||||||
|
|
||||||
self.firmware_install_task = self.hass.async_create_task(
|
self.firmware_install_task = self.hass.async_create_task(
|
||||||
async_flash_silabs_firmware(
|
async_flash_silabs_firmware(
|
||||||
@ -249,8 +247,40 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|||||||
progress_task=self.firmware_install_task,
|
progress_task=self.firmware_install_task,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await self.firmware_install_task
|
||||||
|
except HomeAssistantError:
|
||||||
|
_LOGGER.exception("Failed to flash firmware")
|
||||||
|
return self.async_show_progress_done(next_step_id="firmware_install_failed")
|
||||||
|
|
||||||
return self.async_show_progress_done(next_step_id=next_step_id)
|
return self.async_show_progress_done(next_step_id=next_step_id)
|
||||||
|
|
||||||
|
async def async_step_firmware_download_failed(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Abort when firmware download failed."""
|
||||||
|
assert self.installing_firmware_name is not None
|
||||||
|
return self.async_abort(
|
||||||
|
reason="fw_download_failed",
|
||||||
|
description_placeholders={
|
||||||
|
**self._get_translation_placeholders(),
|
||||||
|
"firmware_name": self.installing_firmware_name,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_step_firmware_install_failed(
|
||||||
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
) -> ConfigFlowResult:
|
||||||
|
"""Abort when firmware install failed."""
|
||||||
|
assert self.installing_firmware_name is not None
|
||||||
|
return self.async_abort(
|
||||||
|
reason="fw_install_failed",
|
||||||
|
description_placeholders={
|
||||||
|
**self._get_translation_placeholders(),
|
||||||
|
"firmware_name": self.installing_firmware_name,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
async def async_step_pick_firmware_zigbee(
|
async def async_step_pick_firmware_zigbee(
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> ConfigFlowResult:
|
) -> ConfigFlowResult:
|
||||||
|
@ -37,7 +37,8 @@
|
|||||||
"zha_still_using_stick": "This {model} is in use by the Zigbee Home Automation integration. Please migrate your Zigbee network to another adapter or delete the integration and try again.",
|
"zha_still_using_stick": "This {model} is in use by the Zigbee Home Automation integration. Please migrate your Zigbee network to another adapter or delete the integration and try again.",
|
||||||
"otbr_still_using_stick": "This {model} is in use by the OpenThread Border Router add-on. If you use the Thread network, make sure you have alternative border routers. Uninstall the add-on and try again.",
|
"otbr_still_using_stick": "This {model} is in use by the OpenThread Border Router add-on. If you use the Thread network, make sure you have alternative border routers. Uninstall the add-on and try again.",
|
||||||
"unsupported_firmware": "The radio firmware on your {model} could not be determined. Make sure that no other integration or add-on is currently trying to communicate with the device. If you are running Home Assistant OS in a virtual machine or in Docker, please make sure that permissions are set correctly for the device.",
|
"unsupported_firmware": "The radio firmware on your {model} could not be determined. Make sure that no other integration or add-on is currently trying to communicate with the device. If you are running Home Assistant OS in a virtual machine or in Docker, please make sure that permissions are set correctly for the device.",
|
||||||
"fw_download_failed": "{firmware_name} firmware for your {model} failed to download. Make sure Home Assistant has internet access and try again."
|
"fw_download_failed": "{firmware_name} firmware for your {model} failed to download. Make sure Home Assistant has internet access and try again.",
|
||||||
|
"fw_install_failed": "{firmware_name} firmware failed to install, check Home Assistant logs for more information."
|
||||||
},
|
},
|
||||||
"progress": {
|
"progress": {
|
||||||
"install_firmware": "Please wait while {firmware_name} firmware is installed to your {model}, this will take a few minutes. Do not make any changes to your hardware or software until this finishes."
|
"install_firmware": "Please wait while {firmware_name} firmware is installed to your {model}, this will take a few minutes. Do not make any changes to your hardware or software until this finishes."
|
||||||
|
@ -93,7 +93,8 @@
|
|||||||
"zha_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::zha_still_using_stick%]",
|
"zha_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::zha_still_using_stick%]",
|
||||||
"otbr_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_still_using_stick%]",
|
"otbr_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_still_using_stick%]",
|
||||||
"unsupported_firmware": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::unsupported_firmware%]",
|
"unsupported_firmware": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::unsupported_firmware%]",
|
||||||
"fw_download_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_download_failed%]"
|
"fw_download_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_download_failed%]",
|
||||||
|
"fw_install_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_install_failed%]"
|
||||||
},
|
},
|
||||||
"progress": {
|
"progress": {
|
||||||
"install_addon": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::progress::install_addon%]",
|
"install_addon": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::progress::install_addon%]",
|
||||||
@ -147,7 +148,8 @@
|
|||||||
"zha_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::zha_still_using_stick%]",
|
"zha_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::zha_still_using_stick%]",
|
||||||
"otbr_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_still_using_stick%]",
|
"otbr_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_still_using_stick%]",
|
||||||
"unsupported_firmware": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::unsupported_firmware%]",
|
"unsupported_firmware": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::unsupported_firmware%]",
|
||||||
"fw_download_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_download_failed%]"
|
"fw_download_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_download_failed%]",
|
||||||
|
"fw_install_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_install_failed%]"
|
||||||
},
|
},
|
||||||
"progress": {
|
"progress": {
|
||||||
"install_addon": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::progress::install_addon%]",
|
"install_addon": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::progress::install_addon%]",
|
||||||
|
@ -118,7 +118,8 @@
|
|||||||
"zha_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::zha_still_using_stick%]",
|
"zha_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::zha_still_using_stick%]",
|
||||||
"otbr_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_still_using_stick%]",
|
"otbr_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_still_using_stick%]",
|
||||||
"unsupported_firmware": "The radio firmware on your {model} could not be determined. Make sure that no other integration or add-on is currently trying to communicate with the device.",
|
"unsupported_firmware": "The radio firmware on your {model} could not be determined. Make sure that no other integration or add-on is currently trying to communicate with the device.",
|
||||||
"fw_download_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_download_failed%]"
|
"fw_download_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_download_failed%]",
|
||||||
|
"fw_install_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_install_failed%]"
|
||||||
},
|
},
|
||||||
"progress": {
|
"progress": {
|
||||||
"install_addon": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::progress::install_addon%]",
|
"install_addon": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::progress::install_addon%]",
|
||||||
|
@ -339,7 +339,7 @@ async def test_config_flow_thread_confirmation_fails(hass: HomeAssistant) -> Non
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert pick_thread_progress_result["type"] is FlowResultType.ABORT
|
assert pick_thread_progress_result["type"] is FlowResultType.ABORT
|
||||||
assert pick_thread_progress_result["reason"] == "unsupported_firmware"
|
assert pick_thread_progress_result["reason"] == "fw_install_failed"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user