mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Handle Z-Wave migration low SDK version (#143936)
This commit is contained in:
parent
98cbc2a182
commit
04bea9c732
@ -9,6 +9,7 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
import aiohttp
|
||||
from awesomeversion import AwesomeVersion
|
||||
from serial.tools import list_ports
|
||||
import voluptuous as vol
|
||||
from zwave_js_server.client import Client
|
||||
@ -99,6 +100,7 @@ ADDON_USER_INPUT_MAP = {
|
||||
}
|
||||
|
||||
ON_SUPERVISOR_SCHEMA = vol.Schema({vol.Optional(CONF_USE_ADDON, default=True): bool})
|
||||
MIN_MIGRATION_SDK_VERSION = AwesomeVersion("6.61")
|
||||
|
||||
|
||||
def get_manual_schema(user_input: dict[str, Any]) -> vol.Schema:
|
||||
@ -810,6 +812,27 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
if not self._usb_discovery and not config_entry.data.get(CONF_USE_ADDON):
|
||||
return self.async_abort(reason="addon_required")
|
||||
|
||||
try:
|
||||
driver = self._get_driver()
|
||||
except AbortFlow:
|
||||
return self.async_abort(reason="config_entry_not_loaded")
|
||||
if (
|
||||
sdk_version := driver.controller.sdk_version
|
||||
) is not None and sdk_version < MIN_MIGRATION_SDK_VERSION:
|
||||
_LOGGER.warning(
|
||||
"Migration from this controller that has SDK version %s "
|
||||
"is not supported. If possible, update the firmware "
|
||||
"of the controller to a firmware built using SDK version %s or higher",
|
||||
sdk_version,
|
||||
MIN_MIGRATION_SDK_VERSION,
|
||||
)
|
||||
return self.async_abort(
|
||||
reason="migration_low_sdk_version",
|
||||
description_placeholders={
|
||||
"ok_sdk_version": str(MIN_MIGRATION_SDK_VERSION)
|
||||
},
|
||||
)
|
||||
|
||||
if user_input is not None:
|
||||
self._migrating = True
|
||||
return await self.async_step_backup_nvm()
|
||||
|
@ -12,8 +12,10 @@
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"backup_failed": "Failed to back up network.",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"config_entry_not_loaded": "The Z-Wave configuration entry is not loaded. Please try again when the configuration entry is loaded.",
|
||||
"different_device": "The connected USB device is not the same as previously configured for this config entry. Please instead create a new config entry for the new device.",
|
||||
"discovery_requires_supervisor": "Discovery requires the supervisor.",
|
||||
"migration_low_sdk_version": "The SDK version of the old controller is lower than {ok_sdk_version}. This means it's not possible to migrate the Non Volatile Memory (NVM) of the old controller to another controller.\n\nCheck the documentation on the manufacturer support pages of the old controller, if it's possible to upgrade the firmware of the old controller to a version that is build with SDK version {ok_sdk_version} or higher.",
|
||||
"migration_successful": "Migration successful.",
|
||||
"not_zwave_device": "Discovered device is not a Z-Wave device.",
|
||||
"not_zwave_js_addon": "Discovered add-on is not the official Z-Wave add-on.",
|
||||
|
@ -180,6 +180,16 @@ def mock_usb_serial_by_id_fixture() -> Generator[MagicMock]:
|
||||
yield mock_usb_serial_by_id
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_sdk_version(client: MagicMock) -> Generator[None]:
|
||||
"""Mock the SDK version of the controller."""
|
||||
original_sdk_version = client.driver.controller.data.get("sdkVersion")
|
||||
client.driver.controller.data["sdkVersion"] = "6.60"
|
||||
yield
|
||||
if original_sdk_version is not None:
|
||||
client.driver.controller.data["sdkVersion"] = original_sdk_version
|
||||
|
||||
|
||||
async def test_manual(hass: HomeAssistant) -> None:
|
||||
"""Test we create an entry with manual step."""
|
||||
|
||||
@ -3478,6 +3488,30 @@ async def test_reconfigure_migrate_no_addon(hass: HomeAssistant, integration) ->
|
||||
assert result["reason"] == "addon_required"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("mock_sdk_version")
|
||||
async def test_reconfigure_migrate_low_sdk_version(
|
||||
hass: HomeAssistant,
|
||||
integration: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test migration flow fails with too low controller SDK version."""
|
||||
entry = integration
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, unique_id="1234", data={**entry.data, "use_addon": True}
|
||||
)
|
||||
|
||||
result = await entry.start_reconfigure_flow(hass)
|
||||
|
||||
assert result["type"] is FlowResultType.MENU
|
||||
assert result["step_id"] == "reconfigure"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "migration_low_sdk_version"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"discovery_info",
|
||||
[
|
||||
@ -3906,7 +3940,7 @@ async def test_get_driver_failure(hass: HomeAssistant, integration, client) -> N
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] == FlowResultType.ABORT
|
||||
assert result["reason"] == "backup_failed"
|
||||
assert result["reason"] == "config_entry_not_loaded"
|
||||
|
||||
|
||||
async def test_hard_reset_failure(hass: HomeAssistant, integration, client) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user