mirror of
https://github.com/home-assistant/core.git
synced 2025-07-07 21:37:07 +00:00
Handle all firmware types for ZBT-1 and Yellow update entities (#141674)
Handle other firmware types
This commit is contained in:
parent
17c56208ee
commit
5283e1a39f
@ -199,7 +199,7 @@ class BaseFirmwareUpdateEntity(
|
||||
# This entity is not currently associated with a device so we must manually
|
||||
# give it a name
|
||||
self._attr_name = f"{self._config_entry.title} Update"
|
||||
self._attr_title = self.entity_description.firmware_name or "unknown"
|
||||
self._attr_title = self.entity_description.firmware_name or "Unknown"
|
||||
|
||||
if (
|
||||
self._current_firmware_info is None
|
||||
|
@ -64,6 +64,28 @@ FIRMWARE_ENTITY_DESCRIPTIONS: dict[
|
||||
expected_firmware_type=ApplicationType.SPINEL,
|
||||
firmware_name="OpenThread RCP",
|
||||
),
|
||||
ApplicationType.CPC: FirmwareUpdateEntityDescription(
|
||||
key="firmware",
|
||||
display_precision=0,
|
||||
device_class=UpdateDeviceClass.FIRMWARE,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
version_parser=lambda fw: fw,
|
||||
fw_type="skyconnect_multipan",
|
||||
version_key="cpc_version",
|
||||
expected_firmware_type=ApplicationType.CPC,
|
||||
firmware_name="Multiprotocol",
|
||||
),
|
||||
ApplicationType.GECKO_BOOTLOADER: FirmwareUpdateEntityDescription(
|
||||
key="firmware",
|
||||
display_precision=0,
|
||||
device_class=UpdateDeviceClass.FIRMWARE,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
version_parser=lambda fw: fw,
|
||||
fw_type=None, # We don't want to update the bootloader
|
||||
version_key="gecko_bootloader_version",
|
||||
expected_firmware_type=ApplicationType.GECKO_BOOTLOADER,
|
||||
firmware_name="Gecko Bootloader",
|
||||
),
|
||||
None: FirmwareUpdateEntityDescription(
|
||||
key="firmware",
|
||||
display_precision=0,
|
||||
@ -86,9 +108,16 @@ def _async_create_update_entity(
|
||||
) -> FirmwareUpdateEntity:
|
||||
"""Create an update entity that handles firmware type changes."""
|
||||
firmware_type = config_entry.data[FIRMWARE]
|
||||
entity_description = FIRMWARE_ENTITY_DESCRIPTIONS[
|
||||
ApplicationType(firmware_type) if firmware_type is not None else None
|
||||
]
|
||||
|
||||
try:
|
||||
entity_description = FIRMWARE_ENTITY_DESCRIPTIONS[
|
||||
ApplicationType(firmware_type)
|
||||
]
|
||||
except (KeyError, ValueError):
|
||||
_LOGGER.debug(
|
||||
"Unknown firmware type %r, using default entity description", firmware_type
|
||||
)
|
||||
entity_description = FIRMWARE_ENTITY_DESCRIPTIONS[None]
|
||||
|
||||
entity = FirmwareUpdateEntity(
|
||||
device=config_entry.data["device"],
|
||||
|
@ -64,6 +64,28 @@ FIRMWARE_ENTITY_DESCRIPTIONS: dict[
|
||||
expected_firmware_type=ApplicationType.SPINEL,
|
||||
firmware_name="OpenThread RCP",
|
||||
),
|
||||
ApplicationType.CPC: FirmwareUpdateEntityDescription(
|
||||
key="firmware",
|
||||
display_precision=0,
|
||||
device_class=UpdateDeviceClass.FIRMWARE,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
version_parser=lambda fw: fw,
|
||||
fw_type="yellow_multipan",
|
||||
version_key="cpc_version",
|
||||
expected_firmware_type=ApplicationType.CPC,
|
||||
firmware_name="Multiprotocol",
|
||||
),
|
||||
ApplicationType.GECKO_BOOTLOADER: FirmwareUpdateEntityDescription(
|
||||
key="firmware",
|
||||
display_precision=0,
|
||||
device_class=UpdateDeviceClass.FIRMWARE,
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
version_parser=lambda fw: fw,
|
||||
fw_type=None, # We don't want to update the bootloader
|
||||
version_key="gecko_bootloader_version",
|
||||
expected_firmware_type=ApplicationType.GECKO_BOOTLOADER,
|
||||
firmware_name="Gecko Bootloader",
|
||||
),
|
||||
None: FirmwareUpdateEntityDescription(
|
||||
key="radio_firmware",
|
||||
display_precision=0,
|
||||
@ -86,9 +108,16 @@ def _async_create_update_entity(
|
||||
) -> FirmwareUpdateEntity:
|
||||
"""Create an update entity that handles firmware type changes."""
|
||||
firmware_type = config_entry.data[FIRMWARE]
|
||||
entity_description = FIRMWARE_ENTITY_DESCRIPTIONS[
|
||||
ApplicationType(firmware_type) if firmware_type is not None else None
|
||||
]
|
||||
|
||||
try:
|
||||
entity_description = FIRMWARE_ENTITY_DESCRIPTIONS[
|
||||
ApplicationType(firmware_type)
|
||||
]
|
||||
except (KeyError, ValueError):
|
||||
_LOGGER.debug(
|
||||
"Unknown firmware type %r, using default entity description", firmware_type
|
||||
)
|
||||
entity_description = FIRMWARE_ENTITY_DESCRIPTIONS[None]
|
||||
|
||||
entity = FirmwareUpdateEntity(
|
||||
device=RADIO_DEVICE,
|
||||
|
@ -1,5 +1,7 @@
|
||||
"""Test SkyConnect firmware update entity."""
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.homeassistant_hardware.helpers import (
|
||||
async_notify_firmware_info,
|
||||
)
|
||||
@ -84,3 +86,47 @@ async def test_zbt1_update_entity(hass: HomeAssistant) -> None:
|
||||
assert state_spinel.attributes["title"] == "OpenThread RCP"
|
||||
assert state_spinel.attributes["installed_version"] == "2.4.4.0"
|
||||
assert state_spinel.attributes["latest_version"] is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("firmware", "version", "expected"),
|
||||
[
|
||||
("ezsp", "7.3.1.0 build 0", "EmberZNet Zigbee 7.3.1.0"),
|
||||
("spinel", "SL-OPENTHREAD/2.4.4.0_GitHub-7074a43e4", "OpenThread RCP 2.4.4.0"),
|
||||
("bootloader", "2.4.2", "Gecko Bootloader 2.4.2"),
|
||||
("cpc", "4.3.2", "Multiprotocol 4.3.2"),
|
||||
("router", "1.2.3.4", "Unknown 1.2.3.4"), # Not supported but still shown
|
||||
],
|
||||
)
|
||||
async def test_zbt1_update_entity_state(
|
||||
hass: HomeAssistant, firmware: str, version: str, expected: str
|
||||
) -> None:
|
||||
"""Test the ZBT-1 firmware update entity with different firmware types."""
|
||||
await async_setup_component(hass, "homeassistant", {})
|
||||
|
||||
zbt1_config_entry = MockConfigEntry(
|
||||
domain="homeassistant_sky_connect",
|
||||
data={
|
||||
"firmware": firmware,
|
||||
"firmware_version": version,
|
||||
"device": USB_DATA_ZBT1.device,
|
||||
"manufacturer": USB_DATA_ZBT1.manufacturer,
|
||||
"pid": USB_DATA_ZBT1.pid,
|
||||
"product": USB_DATA_ZBT1.description,
|
||||
"serial_number": USB_DATA_ZBT1.serial_number,
|
||||
"vid": USB_DATA_ZBT1.vid,
|
||||
},
|
||||
version=1,
|
||||
minor_version=3,
|
||||
)
|
||||
zbt1_config_entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(zbt1_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(UPDATE_ENTITY_ID)
|
||||
assert state is not None
|
||||
assert (
|
||||
f"{state.attributes['title']} {state.attributes['installed_version']}"
|
||||
== expected
|
||||
)
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.homeassistant_hardware.helpers import (
|
||||
async_notify_firmware_info,
|
||||
)
|
||||
@ -90,3 +92,53 @@ async def test_yellow_update_entity(hass: HomeAssistant) -> None:
|
||||
assert state_spinel.attributes["title"] == "OpenThread RCP"
|
||||
assert state_spinel.attributes["installed_version"] == "2.4.4.0"
|
||||
assert state_spinel.attributes["latest_version"] is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("firmware", "version", "expected"),
|
||||
[
|
||||
("ezsp", "7.3.1.0 build 0", "EmberZNet Zigbee 7.3.1.0"),
|
||||
("spinel", "SL-OPENTHREAD/2.4.4.0_GitHub-7074a43e4", "OpenThread RCP 2.4.4.0"),
|
||||
("bootloader", "2.4.2", "Gecko Bootloader 2.4.2"),
|
||||
("cpc", "4.3.2", "Multiprotocol 4.3.2"),
|
||||
("router", "1.2.3.4", "Unknown 1.2.3.4"), # Not supported but still shown
|
||||
],
|
||||
)
|
||||
async def test_yellow_update_entity_state(
|
||||
hass: HomeAssistant, firmware: str, version: str, expected: str
|
||||
) -> None:
|
||||
"""Test the Yellow firmware update entity with different firmware types."""
|
||||
await async_setup_component(hass, "homeassistant", {})
|
||||
|
||||
# Set up the Yellow integration
|
||||
yellow_config_entry = MockConfigEntry(
|
||||
title="Home Assistant Yellow",
|
||||
domain="homeassistant_yellow",
|
||||
data={
|
||||
"firmware": firmware,
|
||||
"firmware_version": version,
|
||||
"device": RADIO_DEVICE,
|
||||
},
|
||||
version=1,
|
||||
minor_version=3,
|
||||
)
|
||||
yellow_config_entry.add_to_hass(hass)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_yellow.is_hassio", return_value=True
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.homeassistant_yellow.get_os_info",
|
||||
return_value={"board": "yellow"},
|
||||
),
|
||||
):
|
||||
assert await hass.config_entries.async_setup(yellow_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(UPDATE_ENTITY_ID)
|
||||
assert state is not None
|
||||
assert (
|
||||
f"{state.attributes['title']} {state.attributes['installed_version']}"
|
||||
== expected
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user