mirror of
https://github.com/home-assistant/core.git
synced 2025-12-24 12:59:34 +00:00
Bump universal-silabs-flasher to v0.1.0 (#156291)
Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
This commit is contained in:
@@ -76,9 +76,18 @@ class ZBT2FirmwareMixin(ConfigEntryBaseFlow, FirmwareInstallFlowProtocol):
|
||||
"""Mixin for Home Assistant Connect ZBT-2 firmware methods."""
|
||||
|
||||
context: ConfigFlowContext
|
||||
BOOTLOADER_RESET_METHODS = [ResetTarget.RTS_DTR]
|
||||
|
||||
ZIGBEE_BAUDRATE = 460800
|
||||
|
||||
# Early ZBT-2 samples used RTS/DTR to trigger the bootloader, later ones use the
|
||||
# baudrate method. Since the two are mutually exclusive we just use both.
|
||||
BOOTLOADER_RESET_METHODS = [ResetTarget.RTS_DTR, ResetTarget.BAUDRATE]
|
||||
APPLICATION_PROBE_METHODS = [
|
||||
(ApplicationType.GECKO_BOOTLOADER, 115200),
|
||||
(ApplicationType.EZSP, ZIGBEE_BAUDRATE),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
]
|
||||
|
||||
async def async_step_install_zigbee_firmware(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -14,7 +14,6 @@ from homeassistant.components.homeassistant_hardware.update import (
|
||||
from homeassistant.components.homeassistant_hardware.util import (
|
||||
ApplicationType,
|
||||
FirmwareInfo,
|
||||
ResetTarget,
|
||||
)
|
||||
from homeassistant.components.update import UpdateDeviceClass
|
||||
from homeassistant.const import EntityCategory
|
||||
@@ -24,6 +23,7 @@ from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import HomeAssistantConnectZBT2ConfigEntry
|
||||
from .config_flow import ZBT2FirmwareMixin
|
||||
from .const import DOMAIN, FIRMWARE, FIRMWARE_VERSION, HARDWARE_NAME, SERIAL_NUMBER
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -134,7 +134,8 @@ async def async_setup_entry(
|
||||
class FirmwareUpdateEntity(BaseFirmwareUpdateEntity):
|
||||
"""Connect ZBT-2 firmware update entity."""
|
||||
|
||||
bootloader_reset_methods = [ResetTarget.RTS_DTR]
|
||||
BOOTLOADER_RESET_METHODS = ZBT2FirmwareMixin.BOOTLOADER_RESET_METHODS
|
||||
APPLICATION_PROBE_METHODS = ZBT2FirmwareMixin.APPLICATION_PROBE_METHODS
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -81,6 +81,7 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
||||
|
||||
ZIGBEE_BAUDRATE = 115200 # Default, subclasses may override
|
||||
BOOTLOADER_RESET_METHODS: list[ResetTarget] = [] # Default, subclasses may override
|
||||
APPLICATION_PROBE_METHODS: list[tuple[ApplicationType, int]] = []
|
||||
|
||||
_picked_firmware_type: PickedFirmwareType
|
||||
_zigbee_flow_strategy: ZigbeeFlowStrategy = ZigbeeFlowStrategy.RECOMMENDED
|
||||
@@ -230,7 +231,11 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
||||
# 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.
|
||||
self._probed_firmware_info = await probe_silabs_firmware_info(self._device)
|
||||
self._probed_firmware_info = await probe_silabs_firmware_info(
|
||||
self._device,
|
||||
bootloader_reset_methods=self.BOOTLOADER_RESET_METHODS,
|
||||
application_probe_methods=self.APPLICATION_PROBE_METHODS,
|
||||
)
|
||||
|
||||
firmware_install_required = self._probed_firmware_info is None or (
|
||||
self._probed_firmware_info.firmware_type != expected_installed_firmware_type
|
||||
@@ -295,6 +300,7 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
||||
fw_data=fw_data,
|
||||
expected_installed_firmware_type=expected_installed_firmware_type,
|
||||
bootloader_reset_methods=self.BOOTLOADER_RESET_METHODS,
|
||||
application_probe_methods=self.APPLICATION_PROBE_METHODS,
|
||||
progress_callback=lambda offset, total: self.async_update_progress(
|
||||
offset / total
|
||||
),
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"documentation": "https://www.home-assistant.io/integrations/homeassistant_hardware",
|
||||
"integration_type": "system",
|
||||
"requirements": [
|
||||
"universal-silabs-flasher==0.0.37",
|
||||
"universal-silabs-flasher==0.1.0",
|
||||
"ha-silabs-firmware-client==0.3.0"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -86,7 +86,8 @@ class BaseFirmwareUpdateEntity(
|
||||
|
||||
# Subclasses provide the mapping between firmware types and entity descriptions
|
||||
entity_description: FirmwareUpdateEntityDescription
|
||||
bootloader_reset_methods: list[ResetTarget] = []
|
||||
BOOTLOADER_RESET_METHODS: list[ResetTarget]
|
||||
APPLICATION_PROBE_METHODS: list[tuple[ApplicationType, int]]
|
||||
|
||||
_attr_supported_features = (
|
||||
UpdateEntityFeature.INSTALL | UpdateEntityFeature.PROGRESS
|
||||
@@ -278,7 +279,8 @@ class BaseFirmwareUpdateEntity(
|
||||
device=self._current_device,
|
||||
fw_data=fw_data,
|
||||
expected_installed_firmware_type=self.entity_description.expected_firmware_type,
|
||||
bootloader_reset_methods=self.bootloader_reset_methods,
|
||||
bootloader_reset_methods=self.BOOTLOADER_RESET_METHODS,
|
||||
application_probe_methods=self.APPLICATION_PROBE_METHODS,
|
||||
progress_callback=self._update_progress,
|
||||
domain=self._config_entry.domain,
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections import defaultdict
|
||||
from collections.abc import AsyncIterator, Callable, Iterable, Sequence
|
||||
from collections.abc import AsyncIterator, Callable, Sequence
|
||||
from contextlib import AsyncExitStack, asynccontextmanager
|
||||
from dataclasses import dataclass
|
||||
from enum import StrEnum
|
||||
@@ -309,15 +309,20 @@ async def guess_firmware_info(hass: HomeAssistant, device_path: str) -> Firmware
|
||||
|
||||
|
||||
async def probe_silabs_firmware_info(
|
||||
device: str, *, probe_methods: Iterable[ApplicationType] | None = None
|
||||
device: str,
|
||||
*,
|
||||
bootloader_reset_methods: Sequence[ResetTarget],
|
||||
application_probe_methods: Sequence[tuple[ApplicationType, int]],
|
||||
) -> FirmwareInfo | None:
|
||||
"""Probe the running firmware on a SiLabs device."""
|
||||
flasher = Flasher(
|
||||
device=device,
|
||||
**(
|
||||
{"probe_methods": [m.as_flasher_application_type() for m in probe_methods]}
|
||||
if probe_methods
|
||||
else {}
|
||||
probe_methods=tuple(
|
||||
(m.as_flasher_application_type(), baudrate)
|
||||
for m, baudrate in application_probe_methods
|
||||
),
|
||||
bootloader_reset=tuple(
|
||||
m.as_flasher_reset_target() for m in bootloader_reset_methods
|
||||
),
|
||||
)
|
||||
|
||||
@@ -343,11 +348,18 @@ async def probe_silabs_firmware_info(
|
||||
|
||||
|
||||
async def probe_silabs_firmware_type(
|
||||
device: str, *, probe_methods: Iterable[ApplicationType] | None = None
|
||||
device: str,
|
||||
*,
|
||||
bootloader_reset_methods: Sequence[ResetTarget],
|
||||
application_probe_methods: Sequence[tuple[ApplicationType, int]],
|
||||
) -> ApplicationType | None:
|
||||
"""Probe the running firmware type on a SiLabs device."""
|
||||
|
||||
fw_info = await probe_silabs_firmware_info(device, probe_methods=probe_methods)
|
||||
fw_info = await probe_silabs_firmware_info(
|
||||
device,
|
||||
bootloader_reset_methods=bootloader_reset_methods,
|
||||
application_probe_methods=application_probe_methods,
|
||||
)
|
||||
if fw_info is None:
|
||||
return None
|
||||
|
||||
@@ -359,12 +371,22 @@ async def async_flash_silabs_firmware(
|
||||
device: str,
|
||||
fw_data: bytes,
|
||||
expected_installed_firmware_type: ApplicationType,
|
||||
bootloader_reset_methods: Sequence[ResetTarget] = (),
|
||||
bootloader_reset_methods: Sequence[ResetTarget],
|
||||
application_probe_methods: Sequence[tuple[ApplicationType, int]],
|
||||
progress_callback: Callable[[int, int], None] | None = None,
|
||||
*,
|
||||
domain: str = DOMAIN,
|
||||
) -> FirmwareInfo:
|
||||
"""Flash firmware to the SiLabs device."""
|
||||
if not any(
|
||||
method == expected_installed_firmware_type
|
||||
for method, _ in application_probe_methods
|
||||
):
|
||||
raise ValueError(
|
||||
f"Expected installed firmware type {expected_installed_firmware_type!r}"
|
||||
f" not in application probe methods {application_probe_methods!r}"
|
||||
)
|
||||
|
||||
async with async_firmware_update_context(hass, device, domain):
|
||||
firmware_info = await guess_firmware_info(hass, device)
|
||||
_LOGGER.debug("Identified firmware info: %s", firmware_info)
|
||||
@@ -373,11 +395,9 @@ async def async_flash_silabs_firmware(
|
||||
|
||||
flasher = Flasher(
|
||||
device=device,
|
||||
probe_methods=(
|
||||
ApplicationType.GECKO_BOOTLOADER.as_flasher_application_type(),
|
||||
ApplicationType.EZSP.as_flasher_application_type(),
|
||||
ApplicationType.SPINEL.as_flasher_application_type(),
|
||||
ApplicationType.CPC.as_flasher_application_type(),
|
||||
probe_methods=tuple(
|
||||
(m.as_flasher_application_type(), baudrate)
|
||||
for m, baudrate in application_probe_methods
|
||||
),
|
||||
bootloader_reset=tuple(
|
||||
m.as_flasher_reset_target() for m in bootloader_reset_methods
|
||||
@@ -401,7 +421,13 @@ async def async_flash_silabs_firmware(
|
||||
|
||||
probed_firmware_info = await probe_silabs_firmware_info(
|
||||
device,
|
||||
probe_methods=(expected_installed_firmware_type,),
|
||||
bootloader_reset_methods=bootloader_reset_methods,
|
||||
# Only probe for the expected installed firmware type
|
||||
application_probe_methods=[
|
||||
(method, baudrate)
|
||||
for method, baudrate in application_probe_methods
|
||||
if method == expected_installed_firmware_type
|
||||
],
|
||||
)
|
||||
|
||||
if probed_firmware_info is None:
|
||||
|
||||
@@ -16,6 +16,7 @@ from homeassistant.components.homeassistant_hardware.helpers import (
|
||||
from homeassistant.components.homeassistant_hardware.util import (
|
||||
ApplicationType,
|
||||
FirmwareInfo,
|
||||
ResetTarget,
|
||||
)
|
||||
from homeassistant.components.usb import (
|
||||
usb_service_info_from_device,
|
||||
@@ -79,6 +80,20 @@ class SkyConnectFirmwareMixin(ConfigEntryBaseFlow, FirmwareInstallFlowProtocol):
|
||||
|
||||
context: ConfigFlowContext
|
||||
|
||||
ZIGBEE_BAUDRATE = 115200
|
||||
# There is no hardware bootloader trigger
|
||||
BOOTLOADER_RESET_METHODS: list[ResetTarget] = []
|
||||
APPLICATION_PROBE_METHODS = [
|
||||
(ApplicationType.GECKO_BOOTLOADER, 115200),
|
||||
(ApplicationType.EZSP, ZIGBEE_BAUDRATE),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
# CPC baudrates can be removed once multiprotocol is removed
|
||||
(ApplicationType.CPC, 115200),
|
||||
(ApplicationType.CPC, 230400),
|
||||
(ApplicationType.CPC, 460800),
|
||||
(ApplicationType.ROUTER, 115200),
|
||||
]
|
||||
|
||||
def _get_translation_placeholders(self) -> dict[str, str]:
|
||||
"""Shared translation placeholders."""
|
||||
placeholders = {
|
||||
|
||||
@@ -23,6 +23,7 @@ from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import HomeAssistantSkyConnectConfigEntry
|
||||
from .config_flow import SkyConnectFirmwareMixin
|
||||
from .const import (
|
||||
DOMAIN,
|
||||
FIRMWARE,
|
||||
@@ -151,8 +152,8 @@ async def async_setup_entry(
|
||||
class FirmwareUpdateEntity(BaseFirmwareUpdateEntity):
|
||||
"""SkyConnect firmware update entity."""
|
||||
|
||||
# The ZBT-1 does not have a hardware bootloader trigger
|
||||
bootloader_reset_methods = []
|
||||
BOOTLOADER_RESET_METHODS = SkyConnectFirmwareMixin.BOOTLOADER_RESET_METHODS
|
||||
APPLICATION_PROBE_METHODS = SkyConnectFirmwareMixin.APPLICATION_PROBE_METHODS
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -82,7 +82,18 @@ else:
|
||||
class YellowFirmwareMixin(ConfigEntryBaseFlow, FirmwareInstallFlowProtocol):
|
||||
"""Mixin for Home Assistant Yellow firmware methods."""
|
||||
|
||||
ZIGBEE_BAUDRATE = 115200
|
||||
BOOTLOADER_RESET_METHODS = [ResetTarget.YELLOW]
|
||||
APPLICATION_PROBE_METHODS = [
|
||||
(ApplicationType.GECKO_BOOTLOADER, 115200),
|
||||
(ApplicationType.EZSP, ZIGBEE_BAUDRATE),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
# CPC baudrates can be removed once multiprotocol is removed
|
||||
(ApplicationType.CPC, 115200),
|
||||
(ApplicationType.CPC, 230400),
|
||||
(ApplicationType.CPC, 460800),
|
||||
(ApplicationType.ROUTER, 115200),
|
||||
]
|
||||
|
||||
async def async_step_install_zigbee_firmware(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
@@ -146,7 +157,11 @@ class HomeAssistantYellowConfigFlow(
|
||||
assert self._device is not None
|
||||
|
||||
# We do not actually use any portion of `BaseFirmwareConfigFlow` beyond this
|
||||
self._probed_firmware_info = await probe_silabs_firmware_info(self._device)
|
||||
self._probed_firmware_info = await probe_silabs_firmware_info(
|
||||
self._device,
|
||||
bootloader_reset_methods=self.BOOTLOADER_RESET_METHODS,
|
||||
application_probe_methods=self.APPLICATION_PROBE_METHODS,
|
||||
)
|
||||
|
||||
# Kick off ZHA hardware discovery automatically if Zigbee firmware is running
|
||||
if (
|
||||
|
||||
@@ -14,7 +14,6 @@ from homeassistant.components.homeassistant_hardware.update import (
|
||||
from homeassistant.components.homeassistant_hardware.util import (
|
||||
ApplicationType,
|
||||
FirmwareInfo,
|
||||
ResetTarget,
|
||||
)
|
||||
from homeassistant.components.update import UpdateDeviceClass
|
||||
from homeassistant.const import EntityCategory
|
||||
@@ -24,6 +23,7 @@ from homeassistant.helpers.device_registry import DeviceInfo
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from . import HomeAssistantYellowConfigEntry
|
||||
from .config_flow import YellowFirmwareMixin
|
||||
from .const import DOMAIN, FIRMWARE, FIRMWARE_VERSION, MANUFACTURER, MODEL, RADIO_DEVICE
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@@ -150,7 +150,8 @@ async def async_setup_entry(
|
||||
class FirmwareUpdateEntity(BaseFirmwareUpdateEntity):
|
||||
"""Yellow firmware update entity."""
|
||||
|
||||
bootloader_reset_methods = [ResetTarget.YELLOW] # Triggers a GPIO reset
|
||||
BOOTLOADER_RESET_METHODS = YellowFirmwareMixin.BOOTLOADER_RESET_METHODS
|
||||
APPLICATION_PROBE_METHODS = YellowFirmwareMixin.APPLICATION_PROBE_METHODS
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
||||
@@ -71,7 +71,20 @@ async def warn_on_wrong_silabs_firmware(hass: HomeAssistant, device: str) -> boo
|
||||
if device.startswith("socket://"):
|
||||
return False
|
||||
|
||||
app_type = await probe_silabs_firmware_type(device)
|
||||
app_type = await probe_silabs_firmware_type(
|
||||
device,
|
||||
bootloader_reset_methods=(),
|
||||
application_probe_methods=[
|
||||
(ApplicationType.GECKO_BOOTLOADER, 115200),
|
||||
(ApplicationType.EZSP, 115200),
|
||||
(ApplicationType.EZSP, 460800),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
(ApplicationType.CPC, 460800),
|
||||
(ApplicationType.CPC, 230400),
|
||||
(ApplicationType.CPC, 115200),
|
||||
(ApplicationType.ROUTER, 115200),
|
||||
],
|
||||
)
|
||||
|
||||
if app_type is None:
|
||||
# Failed to probe, we can't tell if the wrong firmware is installed
|
||||
|
||||
2
requirements_all.txt
generated
2
requirements_all.txt
generated
@@ -3084,7 +3084,7 @@ unifi_ap==0.0.2
|
||||
unifiled==0.11
|
||||
|
||||
# homeassistant.components.homeassistant_hardware
|
||||
universal-silabs-flasher==0.0.37
|
||||
universal-silabs-flasher==0.1.0
|
||||
|
||||
# homeassistant.components.upb
|
||||
upb-lib==0.6.1
|
||||
|
||||
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@@ -2555,7 +2555,7 @@ ultraheat-api==0.5.7
|
||||
unifi-discovery==1.2.0
|
||||
|
||||
# homeassistant.components.homeassistant_hardware
|
||||
universal-silabs-flasher==0.0.37
|
||||
universal-silabs-flasher==0.1.0
|
||||
|
||||
# homeassistant.components.upb
|
||||
upb-lib==0.6.1
|
||||
|
||||
@@ -16,6 +16,7 @@ from homeassistant.components.homeassistant_hardware.helpers import (
|
||||
from homeassistant.components.homeassistant_hardware.util import (
|
||||
ApplicationType,
|
||||
FirmwareInfo,
|
||||
ResetTarget,
|
||||
)
|
||||
from homeassistant.components.usb import USBDevice
|
||||
from homeassistant.config_entries import ConfigFlowResult
|
||||
@@ -367,7 +368,10 @@ async def test_options_flow(
|
||||
|
||||
# Verify async_flash_silabs_firmware was called with ZBT-2's reset methods
|
||||
assert flash_mock.call_count == 1
|
||||
assert flash_mock.mock_calls[0].kwargs["bootloader_reset_methods"] == ["rts_dtr"]
|
||||
assert flash_mock.mock_calls[0].kwargs["bootloader_reset_methods"] == [
|
||||
ResetTarget.RTS_DTR,
|
||||
ResetTarget.BAUDRATE,
|
||||
]
|
||||
|
||||
flows = hass.config_entries.flow.async_progress()
|
||||
|
||||
|
||||
@@ -304,6 +304,7 @@ def mock_firmware_info(
|
||||
fw_data: bytes,
|
||||
expected_installed_firmware_type: ApplicationType,
|
||||
bootloader_reset_methods: Sequence[ResetTarget] = (),
|
||||
application_probe_methods: Sequence[tuple[ApplicationType, int]] = (),
|
||||
progress_callback: Callable[[int, int], None] | None = None,
|
||||
*,
|
||||
domain: str = "homeassistant_hardware",
|
||||
|
||||
@@ -173,7 +173,12 @@ async def mock_async_setup_update_entities(
|
||||
class MockFirmwareUpdateEntity(BaseFirmwareUpdateEntity):
|
||||
"""Mock SkyConnect firmware update entity."""
|
||||
|
||||
bootloader_reset_methods = []
|
||||
BOOTLOADER_RESET_METHODS = [ResetTarget.RTS_DTR]
|
||||
APPLICATION_PROBE_METHODS = [
|
||||
(ApplicationType.GECKO_BOOTLOADER, 115200),
|
||||
(ApplicationType.EZSP, 115200),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -320,6 +325,7 @@ async def test_update_entity_installation(
|
||||
fw_data: bytes,
|
||||
expected_installed_firmware_type: ApplicationType,
|
||||
bootloader_reset_methods: Sequence[ResetTarget] = (),
|
||||
application_probe_methods: Sequence[tuple[ApplicationType, int]] = (),
|
||||
progress_callback: Callable[[int, int], None] | None = None,
|
||||
*,
|
||||
domain: str = "homeassistant_hardware",
|
||||
|
||||
@@ -23,6 +23,7 @@ from homeassistant.components.homeassistant_hardware.util import (
|
||||
FirmwareInfo,
|
||||
OwningAddon,
|
||||
OwningIntegration,
|
||||
ResetTarget,
|
||||
async_flash_silabs_firmware,
|
||||
get_otbr_addon_firmware_info,
|
||||
guess_firmware_info,
|
||||
@@ -502,7 +503,14 @@ async def test_probe_silabs_firmware_info(
|
||||
"homeassistant.components.homeassistant_hardware.util.Flasher",
|
||||
return_value=mock_flasher,
|
||||
):
|
||||
result = await probe_silabs_firmware_info("/dev/ttyUSB0")
|
||||
result = await probe_silabs_firmware_info(
|
||||
"/dev/ttyUSB0",
|
||||
bootloader_reset_methods=[ResetTarget.RTS_DTR],
|
||||
application_probe_methods=[
|
||||
(ApplicationType.EZSP, 460800),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
],
|
||||
)
|
||||
assert result == expected_fw_info
|
||||
|
||||
|
||||
@@ -531,7 +539,14 @@ async def test_probe_silabs_firmware_type(
|
||||
autospec=True,
|
||||
return_value=probe_result,
|
||||
):
|
||||
result = await probe_silabs_firmware_type("/dev/ttyUSB0")
|
||||
result = await probe_silabs_firmware_type(
|
||||
"/dev/ttyUSB0",
|
||||
bootloader_reset_methods=[ResetTarget.RTS_DTR],
|
||||
application_probe_methods=[
|
||||
(ApplicationType.EZSP, 460800),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
],
|
||||
)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@@ -596,7 +611,11 @@ async def test_async_flash_silabs_firmware(hass: HomeAssistant) -> None:
|
||||
device="/dev/ttyUSB0",
|
||||
fw_data=b"firmware contents",
|
||||
expected_installed_firmware_type=ApplicationType.SPINEL,
|
||||
bootloader_reset_methods=(),
|
||||
bootloader_reset_methods=[ResetTarget.RTS_DTR],
|
||||
application_probe_methods=[
|
||||
(ApplicationType.EZSP, 460800),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
],
|
||||
progress_callback=progress_callback,
|
||||
)
|
||||
|
||||
@@ -605,7 +624,9 @@ async def test_async_flash_silabs_firmware(hass: HomeAssistant) -> None:
|
||||
|
||||
# Verify Flasher was called with correct bootloader_reset parameter
|
||||
assert flasher_mock.call_count == 1
|
||||
assert flasher_mock.mock_calls[0].kwargs["bootloader_reset"] == ()
|
||||
assert flasher_mock.mock_calls[0].kwargs["bootloader_reset"] == (
|
||||
ResetTarget.RTS_DTR.as_flasher_reset_target(),
|
||||
)
|
||||
|
||||
# Both owning integrations/addons are stopped and restarted
|
||||
assert owner1.temporarily_stop.mock_calls == [
|
||||
@@ -623,6 +644,28 @@ async def test_async_flash_silabs_firmware(hass: HomeAssistant) -> None:
|
||||
]
|
||||
|
||||
|
||||
async def test_async_flash_silabs_firmware_expected_type_not_probed(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
"""Test firmware flashing requires probing config to exist for firmware type."""
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=(
|
||||
r"Expected installed firmware type .*? not in application probe methods .*?"
|
||||
),
|
||||
):
|
||||
await async_flash_silabs_firmware(
|
||||
hass=hass,
|
||||
device="/dev/ttyUSB0",
|
||||
fw_data=b"firmware contents",
|
||||
expected_installed_firmware_type=ApplicationType.SPINEL,
|
||||
bootloader_reset_methods=[ResetTarget.RTS_DTR],
|
||||
application_probe_methods=[
|
||||
(ApplicationType.EZSP, 460800),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
async def test_async_flash_silabs_firmware_flash_failure(hass: HomeAssistant) -> None:
|
||||
"""Test async_flash_silabs_firmware flash failure."""
|
||||
await async_setup_component(hass, "homeassistant_hardware", {})
|
||||
@@ -659,7 +702,11 @@ async def test_async_flash_silabs_firmware_flash_failure(hass: HomeAssistant) ->
|
||||
device="/dev/ttyUSB0",
|
||||
fw_data=b"firmware contents",
|
||||
expected_installed_firmware_type=ApplicationType.SPINEL,
|
||||
bootloader_reset_methods=(),
|
||||
bootloader_reset_methods=[ResetTarget.RTS_DTR],
|
||||
application_probe_methods=[
|
||||
(ApplicationType.EZSP, 460800),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
],
|
||||
)
|
||||
|
||||
# Both owning integrations/addons are stopped and restarted
|
||||
@@ -719,7 +766,11 @@ async def test_async_flash_silabs_firmware_probe_failure(hass: HomeAssistant) ->
|
||||
device="/dev/ttyUSB0",
|
||||
fw_data=b"firmware contents",
|
||||
expected_installed_firmware_type=ApplicationType.SPINEL,
|
||||
bootloader_reset_methods=(),
|
||||
bootloader_reset_methods=[ResetTarget.RTS_DTR],
|
||||
application_probe_methods=[
|
||||
(ApplicationType.EZSP, 460800),
|
||||
(ApplicationType.SPINEL, 460800),
|
||||
],
|
||||
)
|
||||
|
||||
# Both owning integrations/addons are stopped and restarted
|
||||
|
||||
Reference in New Issue
Block a user