mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Move SiLabs firmware probing helper from ZHA into homeassistant_hardware
(#131586)
* Move firmware probing helper out of ZHA and into hardware * Add a unit test
This commit is contained in:
parent
a53554dad3
commit
90265e2afd
@ -7,17 +7,12 @@ import asyncio
|
|||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
|
||||||
|
|
||||||
from homeassistant.components.hassio import (
|
from homeassistant.components.hassio import (
|
||||||
AddonError,
|
AddonError,
|
||||||
AddonInfo,
|
AddonInfo,
|
||||||
AddonManager,
|
AddonManager,
|
||||||
AddonState,
|
AddonState,
|
||||||
)
|
)
|
||||||
from homeassistant.components.zha.repairs.wrong_silabs_firmware import (
|
|
||||||
probe_silabs_firmware_type,
|
|
||||||
)
|
|
||||||
from homeassistant.config_entries import (
|
from homeassistant.config_entries import (
|
||||||
ConfigEntry,
|
ConfigEntry,
|
||||||
ConfigEntryBaseFlow,
|
ConfigEntryBaseFlow,
|
||||||
@ -32,9 +27,11 @@ from homeassistant.helpers.hassio import is_hassio
|
|||||||
from . import silabs_multiprotocol_addon
|
from . import silabs_multiprotocol_addon
|
||||||
from .const import ZHA_DOMAIN
|
from .const import ZHA_DOMAIN
|
||||||
from .util import (
|
from .util import (
|
||||||
|
ApplicationType,
|
||||||
get_otbr_addon_manager,
|
get_otbr_addon_manager,
|
||||||
get_zha_device_path,
|
get_zha_device_path,
|
||||||
get_zigbee_flasher_addon_manager,
|
get_zigbee_flasher_addon_manager,
|
||||||
|
probe_silabs_firmware_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"domain": "homeassistant_hardware",
|
"domain": "homeassistant_hardware",
|
||||||
"name": "Home Assistant Hardware",
|
"name": "Home Assistant Hardware",
|
||||||
"after_dependencies": ["hassio", "zha"],
|
"after_dependencies": ["hassio"],
|
||||||
"codeowners": ["@home-assistant/core"],
|
"codeowners": ["@home-assistant/core"],
|
||||||
"documentation": "https://www.home-assistant.io/integrations/homeassistant_hardware",
|
"documentation": "https://www.home-assistant.io/integrations/homeassistant_hardware",
|
||||||
"integration_type": "system"
|
"integration_type": "system",
|
||||||
|
"requirements": ["universal-silabs-flasher==0.0.25"]
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from collections.abc import Iterable
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from enum import StrEnum
|
||||||
import logging
|
import logging
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
from universal_silabs_flasher.const import ApplicationType as FlasherApplicationType
|
||||||
|
from universal_silabs_flasher.flasher import Flasher
|
||||||
|
|
||||||
from homeassistant.components.hassio import AddonError, AddonState
|
from homeassistant.components.hassio import AddonError, AddonState
|
||||||
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
|
||||||
@ -32,6 +35,26 @@ from .silabs_multiprotocol_addon import (
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ApplicationType(StrEnum):
|
||||||
|
"""Application type running on a device."""
|
||||||
|
|
||||||
|
GECKO_BOOTLOADER = "bootloader"
|
||||||
|
CPC = "cpc"
|
||||||
|
EZSP = "ezsp"
|
||||||
|
SPINEL = "spinel"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_flasher_application_type(
|
||||||
|
cls, app_type: FlasherApplicationType
|
||||||
|
) -> ApplicationType:
|
||||||
|
"""Convert a USF application type enum."""
|
||||||
|
return cls(app_type.value)
|
||||||
|
|
||||||
|
def as_flasher_application_type(self) -> FlasherApplicationType:
|
||||||
|
"""Convert the application type enum into one compatible with USF."""
|
||||||
|
return FlasherApplicationType(self.value)
|
||||||
|
|
||||||
|
|
||||||
def get_zha_device_path(config_entry: ConfigEntry) -> str | None:
|
def get_zha_device_path(config_entry: ConfigEntry) -> str | None:
|
||||||
"""Get the device path from a ZHA config entry."""
|
"""Get the device path from a ZHA config entry."""
|
||||||
return cast(str | None, config_entry.data.get("device", {}).get("path", None))
|
return cast(str | None, config_entry.data.get("device", {}).get("path", None))
|
||||||
@ -137,3 +160,27 @@ async def guess_firmware_type(hass: HomeAssistant, device_path: str) -> Firmware
|
|||||||
assert guesses
|
assert guesses
|
||||||
|
|
||||||
return guesses[-1]
|
return guesses[-1]
|
||||||
|
|
||||||
|
|
||||||
|
async def probe_silabs_firmware_type(
|
||||||
|
device: str, *, probe_methods: Iterable[ApplicationType] | None = None
|
||||||
|
) -> ApplicationType | 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 {}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
await flasher.probe_app_type()
|
||||||
|
except Exception: # noqa: BLE001
|
||||||
|
_LOGGER.debug("Failed to probe application type", exc_info=True)
|
||||||
|
|
||||||
|
if flasher.app_type is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return ApplicationType.from_flasher_application_type(flasher.app_type)
|
||||||
|
@ -5,13 +5,12 @@ from __future__ import annotations
|
|||||||
import logging
|
import logging
|
||||||
from typing import TYPE_CHECKING, Any, Protocol
|
from typing import TYPE_CHECKING, Any, Protocol
|
||||||
|
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
|
||||||
|
|
||||||
from homeassistant.components import usb
|
from homeassistant.components import usb
|
||||||
from homeassistant.components.homeassistant_hardware import (
|
from homeassistant.components.homeassistant_hardware import (
|
||||||
firmware_config_flow,
|
firmware_config_flow,
|
||||||
silabs_multiprotocol_addon,
|
silabs_multiprotocol_addon,
|
||||||
)
|
)
|
||||||
|
from homeassistant.components.homeassistant_hardware.util import ApplicationType
|
||||||
from homeassistant.config_entries import (
|
from homeassistant.config_entries import (
|
||||||
ConfigEntry,
|
ConfigEntry,
|
||||||
ConfigEntryBaseFlow,
|
ConfigEntryBaseFlow,
|
||||||
|
@ -8,7 +8,6 @@ import logging
|
|||||||
from typing import Any, final
|
from typing import Any, final
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.hassio import (
|
from homeassistant.components.hassio import (
|
||||||
@ -25,6 +24,7 @@ from homeassistant.components.homeassistant_hardware.silabs_multiprotocol_addon
|
|||||||
OptionsFlowHandler as MultiprotocolOptionsFlowHandler,
|
OptionsFlowHandler as MultiprotocolOptionsFlowHandler,
|
||||||
SerialPortSettings as MultiprotocolSerialPortSettings,
|
SerialPortSettings as MultiprotocolSerialPortSettings,
|
||||||
)
|
)
|
||||||
|
from homeassistant.components.homeassistant_hardware.util import ApplicationType
|
||||||
from homeassistant.config_entries import (
|
from homeassistant.config_entries import (
|
||||||
SOURCE_HARDWARE,
|
SOURCE_HARDWARE,
|
||||||
ConfigEntry,
|
ConfigEntry,
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"after_dependencies": ["hassio", "onboarding", "usb"],
|
"after_dependencies": ["hassio", "onboarding", "usb"],
|
||||||
"codeowners": ["@dmulcahey", "@adminiuga", "@puddly", "@TheJulianJES"],
|
"codeowners": ["@dmulcahey", "@adminiuga", "@puddly", "@TheJulianJES"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"dependencies": ["file_upload"],
|
"dependencies": ["file_upload", "homeassistant_hardware"],
|
||||||
"documentation": "https://www.home-assistant.io/integrations/zha",
|
"documentation": "https://www.home-assistant.io/integrations/zha",
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"loggers": [
|
"loggers": [
|
||||||
@ -21,7 +21,7 @@
|
|||||||
"zha",
|
"zha",
|
||||||
"universal_silabs_flasher"
|
"universal_silabs_flasher"
|
||||||
],
|
],
|
||||||
"requirements": ["universal-silabs-flasher==0.0.25", "zha==0.0.44"],
|
"requirements": ["zha==0.0.44"],
|
||||||
"usb": [
|
"usb": [
|
||||||
{
|
{
|
||||||
"vid": "10C4",
|
"vid": "10C4",
|
||||||
|
@ -5,9 +5,10 @@ from __future__ import annotations
|
|||||||
import enum
|
import enum
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
from homeassistant.components.homeassistant_hardware.util import (
|
||||||
from universal_silabs_flasher.flasher import Flasher
|
ApplicationType,
|
||||||
|
probe_silabs_firmware_type,
|
||||||
|
)
|
||||||
from homeassistant.components.homeassistant_sky_connect import (
|
from homeassistant.components.homeassistant_sky_connect import (
|
||||||
hardware as skyconnect_hardware,
|
hardware as skyconnect_hardware,
|
||||||
)
|
)
|
||||||
@ -74,23 +75,6 @@ def _detect_radio_hardware(hass: HomeAssistant, device: str) -> HardwareType:
|
|||||||
return HardwareType.OTHER
|
return HardwareType.OTHER
|
||||||
|
|
||||||
|
|
||||||
async def probe_silabs_firmware_type(
|
|
||||||
device: str, *, probe_methods: ApplicationType | None = None
|
|
||||||
) -> ApplicationType | None:
|
|
||||||
"""Probe the running firmware on a Silabs device."""
|
|
||||||
flasher = Flasher(
|
|
||||||
device=device,
|
|
||||||
**({"probe_methods": probe_methods} if probe_methods else {}),
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
await flasher.probe_app_type()
|
|
||||||
except Exception: # noqa: BLE001
|
|
||||||
_LOGGER.debug("Failed to probe application type", exc_info=True)
|
|
||||||
|
|
||||||
return flasher.app_type
|
|
||||||
|
|
||||||
|
|
||||||
async def warn_on_wrong_silabs_firmware(hass: HomeAssistant, device: str) -> bool:
|
async def warn_on_wrong_silabs_firmware(hass: HomeAssistant, device: str) -> bool:
|
||||||
"""Create a repair issue if the wrong type of SiLabs firmware is detected."""
|
"""Create a repair issue if the wrong type of SiLabs firmware is detected."""
|
||||||
# Only consider actual serial ports
|
# Only consider actual serial ports
|
||||||
|
@ -2942,7 +2942,7 @@ unifi_ap==0.0.2
|
|||||||
# homeassistant.components.unifiled
|
# homeassistant.components.unifiled
|
||||||
unifiled==0.11
|
unifiled==0.11
|
||||||
|
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.homeassistant_hardware
|
||||||
universal-silabs-flasher==0.0.25
|
universal-silabs-flasher==0.0.25
|
||||||
|
|
||||||
# homeassistant.components.upb
|
# homeassistant.components.upb
|
||||||
|
@ -2358,9 +2358,6 @@ ultraheat-api==0.5.7
|
|||||||
# homeassistant.components.unifiprotect
|
# homeassistant.components.unifiprotect
|
||||||
unifi-discovery==1.2.0
|
unifi-discovery==1.2.0
|
||||||
|
|
||||||
# homeassistant.components.zha
|
|
||||||
universal-silabs-flasher==0.0.25
|
|
||||||
|
|
||||||
# homeassistant.components.upb
|
# homeassistant.components.upb
|
||||||
upb-lib==0.5.9
|
upb-lib==0.5.9
|
||||||
|
|
||||||
|
@ -168,6 +168,7 @@ IGNORE_VIOLATIONS = {
|
|||||||
("zha", "homeassistant_sky_connect"),
|
("zha", "homeassistant_sky_connect"),
|
||||||
("zha", "homeassistant_yellow"),
|
("zha", "homeassistant_yellow"),
|
||||||
("homeassistant_sky_connect", "zha"),
|
("homeassistant_sky_connect", "zha"),
|
||||||
|
("homeassistant_hardware", "zha"),
|
||||||
# This should become a helper method that integrations can submit data to
|
# This should become a helper method that integrations can submit data to
|
||||||
("websocket_api", "lovelace"),
|
("websocket_api", "lovelace"),
|
||||||
("websocket_api", "shopping_list"),
|
("websocket_api", "shopping_list"),
|
||||||
|
@ -7,7 +7,6 @@ from typing import Any
|
|||||||
from unittest.mock import AsyncMock, Mock, call, patch
|
from unittest.mock import AsyncMock, Mock, call, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
|
||||||
|
|
||||||
from homeassistant.components.hassio import AddonInfo, AddonState
|
from homeassistant.components.hassio import AddonInfo, AddonState
|
||||||
from homeassistant.components.homeassistant_hardware.firmware_config_flow import (
|
from homeassistant.components.homeassistant_hardware.firmware_config_flow import (
|
||||||
@ -17,6 +16,7 @@ from homeassistant.components.homeassistant_hardware.firmware_config_flow import
|
|||||||
BaseFirmwareOptionsFlow,
|
BaseFirmwareOptionsFlow,
|
||||||
)
|
)
|
||||||
from homeassistant.components.homeassistant_hardware.util import (
|
from homeassistant.components.homeassistant_hardware.util import (
|
||||||
|
ApplicationType,
|
||||||
get_otbr_addon_manager,
|
get_otbr_addon_manager,
|
||||||
get_zigbee_flasher_addon_manager,
|
get_zigbee_flasher_addon_manager,
|
||||||
)
|
)
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
|
||||||
|
|
||||||
from homeassistant.components.hassio import AddonError, AddonInfo, AddonState
|
from homeassistant.components.hassio import AddonError, AddonInfo, AddonState
|
||||||
from homeassistant.components.homeassistant_hardware.firmware_config_flow import (
|
from homeassistant.components.homeassistant_hardware.firmware_config_flow import (
|
||||||
STEP_PICK_FIRMWARE_THREAD,
|
STEP_PICK_FIRMWARE_THREAD,
|
||||||
STEP_PICK_FIRMWARE_ZIGBEE,
|
STEP_PICK_FIRMWARE_ZIGBEE,
|
||||||
)
|
)
|
||||||
|
from homeassistant.components.homeassistant_hardware.util import ApplicationType
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
|
|
||||||
from unittest.mock import AsyncMock, patch
|
from unittest.mock import AsyncMock, patch
|
||||||
|
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
|
||||||
|
|
||||||
from homeassistant.components.hassio import AddonError, AddonInfo, AddonState
|
from homeassistant.components.hassio import AddonError, AddonInfo, AddonState
|
||||||
from homeassistant.components.homeassistant_hardware.util import (
|
from homeassistant.components.homeassistant_hardware.util import (
|
||||||
|
ApplicationType,
|
||||||
FirmwareGuess,
|
FirmwareGuess,
|
||||||
|
FlasherApplicationType,
|
||||||
get_zha_device_path,
|
get_zha_device_path,
|
||||||
guess_firmware_type,
|
guess_firmware_type,
|
||||||
|
probe_silabs_firmware_type,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -156,3 +157,27 @@ async def test_guess_firmware_type(hass: HomeAssistant) -> None:
|
|||||||
assert (await guess_firmware_type(hass, path)) == FirmwareGuess(
|
assert (await guess_firmware_type(hass, path)) == FirmwareGuess(
|
||||||
is_running=True, firmware_type=ApplicationType.CPC, source="multiprotocol"
|
is_running=True, firmware_type=ApplicationType.CPC, source="multiprotocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_probe_silabs_firmware_type() -> None:
|
||||||
|
"""Test probing Silabs firmware type."""
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.homeassistant_hardware.util.Flasher.probe_app_type",
|
||||||
|
side_effect=RuntimeError,
|
||||||
|
):
|
||||||
|
assert (await probe_silabs_firmware_type("/dev/ttyUSB0")) is None
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.homeassistant_hardware.util.Flasher.probe_app_type",
|
||||||
|
side_effect=lambda self: setattr(self, "app_type", FlasherApplicationType.EZSP),
|
||||||
|
autospec=True,
|
||||||
|
) as mock_probe_app_type:
|
||||||
|
# The application type constant is converted back and forth transparently
|
||||||
|
result = await probe_silabs_firmware_type(
|
||||||
|
"/dev/ttyUSB0", probe_methods=[ApplicationType.EZSP]
|
||||||
|
)
|
||||||
|
assert result is ApplicationType.EZSP
|
||||||
|
|
||||||
|
flasher = mock_probe_app_type.mock_calls[0].args[0]
|
||||||
|
assert flasher._probe_methods == [FlasherApplicationType.EZSP]
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
from homeassistant.components.homeassistant_hardware.util import (
|
||||||
|
ApplicationType,
|
||||||
from homeassistant.components.homeassistant_hardware.util import FirmwareGuess
|
FirmwareGuess,
|
||||||
|
)
|
||||||
from homeassistant.components.homeassistant_sky_connect.const import DOMAIN
|
from homeassistant.components.homeassistant_sky_connect.const import DOMAIN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
"""Test ZHA repairs."""
|
"""Test ZHA repairs."""
|
||||||
|
|
||||||
from collections.abc import Callable
|
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
import logging
|
|
||||||
from unittest.mock import Mock, call, patch
|
from unittest.mock import Mock, call, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from universal_silabs_flasher.const import ApplicationType
|
|
||||||
from universal_silabs_flasher.flasher import Flasher
|
|
||||||
from zigpy.application import ControllerApplication
|
from zigpy.application import ControllerApplication
|
||||||
import zigpy.backups
|
import zigpy.backups
|
||||||
from zigpy.exceptions import NetworkSettingsInconsistent
|
from zigpy.exceptions import NetworkSettingsInconsistent
|
||||||
|
|
||||||
|
from homeassistant.components.homeassistant_hardware.util import ApplicationType
|
||||||
from homeassistant.components.homeassistant_sky_connect.const import ( # pylint: disable=hass-component-root-import
|
from homeassistant.components.homeassistant_sky_connect.const import ( # pylint: disable=hass-component-root-import
|
||||||
DOMAIN as SKYCONNECT_DOMAIN,
|
DOMAIN as SKYCONNECT_DOMAIN,
|
||||||
)
|
)
|
||||||
@ -25,7 +22,6 @@ from homeassistant.components.zha.repairs.wrong_silabs_firmware import (
|
|||||||
ISSUE_WRONG_SILABS_FIRMWARE_INSTALLED,
|
ISSUE_WRONG_SILABS_FIRMWARE_INSTALLED,
|
||||||
HardwareType,
|
HardwareType,
|
||||||
_detect_radio_hardware,
|
_detect_radio_hardware,
|
||||||
probe_silabs_firmware_type,
|
|
||||||
warn_on_wrong_silabs_firmware,
|
warn_on_wrong_silabs_firmware,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
@ -41,15 +37,6 @@ SKYCONNECT_DEVICE = "/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_9e2adbd75b8
|
|||||||
CONNECT_ZBT1_DEVICE = "/dev/serial/by-id/usb-Nabu_Casa_Home_Assistant_Connect_ZBT-1_9e2adbd75b8beb119fe564a0f320645d-if00-port0"
|
CONNECT_ZBT1_DEVICE = "/dev/serial/by-id/usb-Nabu_Casa_Home_Assistant_Connect_ZBT-1_9e2adbd75b8beb119fe564a0f320645d-if00-port0"
|
||||||
|
|
||||||
|
|
||||||
def set_flasher_app_type(app_type: ApplicationType) -> Callable[[Flasher], None]:
|
|
||||||
"""Set the app type on the flasher."""
|
|
||||||
|
|
||||||
def replacement(self: Flasher) -> None:
|
|
||||||
self.app_type = app_type
|
|
||||||
|
|
||||||
return replacement
|
|
||||||
|
|
||||||
|
|
||||||
def test_detect_radio_hardware(hass: HomeAssistant) -> None:
|
def test_detect_radio_hardware(hass: HomeAssistant) -> None:
|
||||||
"""Test logic to detect radio hardware."""
|
"""Test logic to detect radio hardware."""
|
||||||
skyconnect_config_entry = MockConfigEntry(
|
skyconnect_config_entry = MockConfigEntry(
|
||||||
@ -143,9 +130,8 @@ async def test_multipan_firmware_repair(
|
|||||||
# ZHA fails to set up
|
# ZHA fails to set up
|
||||||
with (
|
with (
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.zha.repairs.wrong_silabs_firmware.Flasher.probe_app_type",
|
"homeassistant.components.zha.repairs.wrong_silabs_firmware.probe_silabs_firmware_type",
|
||||||
side_effect=set_flasher_app_type(ApplicationType.CPC),
|
return_value=ApplicationType.CPC,
|
||||||
autospec=True,
|
|
||||||
),
|
),
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.zha.Gateway.async_initialize",
|
"homeassistant.components.zha.Gateway.async_initialize",
|
||||||
@ -194,9 +180,8 @@ async def test_multipan_firmware_no_repair_on_probe_failure(
|
|||||||
# ZHA fails to set up
|
# ZHA fails to set up
|
||||||
with (
|
with (
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.zha.repairs.wrong_silabs_firmware.Flasher.probe_app_type",
|
"homeassistant.components.zha.repairs.wrong_silabs_firmware.probe_silabs_firmware_type",
|
||||||
side_effect=set_flasher_app_type(None),
|
return_value=None,
|
||||||
autospec=True,
|
|
||||||
),
|
),
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.zha.Gateway.async_initialize",
|
"homeassistant.components.zha.Gateway.async_initialize",
|
||||||
@ -231,9 +216,8 @@ async def test_multipan_firmware_retry_on_probe_ezsp(
|
|||||||
# ZHA fails to set up
|
# ZHA fails to set up
|
||||||
with (
|
with (
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.zha.repairs.wrong_silabs_firmware.Flasher.probe_app_type",
|
"homeassistant.components.zha.repairs.wrong_silabs_firmware.probe_silabs_firmware_type",
|
||||||
side_effect=set_flasher_app_type(ApplicationType.EZSP),
|
return_value=ApplicationType.EZSP,
|
||||||
autospec=True,
|
|
||||||
),
|
),
|
||||||
patch(
|
patch(
|
||||||
"homeassistant.components.zha.Gateway.async_initialize",
|
"homeassistant.components.zha.Gateway.async_initialize",
|
||||||
@ -260,37 +244,12 @@ async def test_no_warn_on_socket(hass: HomeAssistant) -> None:
|
|||||||
"""Test that no warning is issued when the device is a socket."""
|
"""Test that no warning is issued when the device is a socket."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.zha.repairs.wrong_silabs_firmware.probe_silabs_firmware_type",
|
"homeassistant.components.zha.repairs.wrong_silabs_firmware.probe_silabs_firmware_type",
|
||||||
autospec=True,
|
|
||||||
) as mock_probe:
|
) as mock_probe:
|
||||||
await warn_on_wrong_silabs_firmware(hass, device="socket://1.2.3.4:5678")
|
await warn_on_wrong_silabs_firmware(hass, device="socket://1.2.3.4:5678")
|
||||||
|
|
||||||
mock_probe.assert_not_called()
|
mock_probe.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
async def test_probe_failure_exception_handling(
|
|
||||||
caplog: pytest.LogCaptureFixture,
|
|
||||||
) -> None:
|
|
||||||
"""Test that probe failures are handled gracefully."""
|
|
||||||
logger = logging.getLogger(
|
|
||||||
"homeassistant.components.zha.repairs.wrong_silabs_firmware"
|
|
||||||
)
|
|
||||||
orig_level = logger.level
|
|
||||||
|
|
||||||
with (
|
|
||||||
caplog.at_level(logging.DEBUG),
|
|
||||||
patch(
|
|
||||||
"homeassistant.components.zha.repairs.wrong_silabs_firmware.Flasher.probe_app_type",
|
|
||||||
side_effect=RuntimeError(),
|
|
||||||
) as mock_probe_app_type,
|
|
||||||
):
|
|
||||||
logger.setLevel(logging.DEBUG)
|
|
||||||
await probe_silabs_firmware_type("/dev/ttyZigbee")
|
|
||||||
logger.setLevel(orig_level)
|
|
||||||
|
|
||||||
mock_probe_app_type.assert_awaited()
|
|
||||||
assert "Failed to probe application type" in caplog.text
|
|
||||||
|
|
||||||
|
|
||||||
async def test_inconsistent_settings_keep_new(
|
async def test_inconsistent_settings_keep_new(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
hass_client: ClientSessionGenerator,
|
hass_client: ClientSessionGenerator,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user