Repository: home-assistant/core
Pull request: Do not factory reset old Z-Wave controller during migration
## Proposed change
<!--
  Describe the big picture of your changes here to communicate to the
  maintainers why we should accept this pull request. If it fixes a bug
  or resolves a feature request, be sure to link to that issue in the
  additional information section.
-->
Also removed the confirmation before that since the we are just creating a backup now and this is not destructive.
@MartinHjelmare am I correct that all of this home_id code can be removed when we don't reset anymore?

## Type of change
<!--
  What type of change does your PR introduce to Home Assistant?
  NOTE: Please, check only 1! box!
  If your PR requires multiple boxes to be checked, you'll most likely need to
  split it into multiple PRs. This makes things easier and faster to code review.
-->

- [ ] Dependency upgrade
- [x] Bugfix (non-breaking change which fixes an issue)
- [ ] New integration (thank you!)
- [ ] New feature (which adds functionality to an existing integration)
- [ ] Deprecation (breaking change to happen in the future)
- [ ] Breaking change (fix/feature causing existing functionality to break)
- [ ] Code quality improvements to existing code or addition of tests

## Additional information
<!--
  Details are important, and help maintainers processing your PR.
  Please be sure to fill out additional details, if applicable.
-->

- This PR fixes or closes issue: fixes https://github.com/zwave-js/backlog/issues/102
- This PR is related to issue: 
- Link to documentation pull request: 
- Link to developer documentation pull request: 
- Link to frontend pull request: 

## Checklist
<!--
  Put an `x` in the boxes that apply. You can also fill these out after
  creating the PR. If you're unsure about any of them, don't hesitate to ask.
  We're here to help! This is simply a reminder of what we are going to look
  for before merging your code.
-->

- [ ] The code change is tested and works locally.
- [x] Local tests pass. **Your PR cannot be merged unless tests pass**
- [x] There is no commented out code in this PR.
- [x] I have followed the [development checklist][dev-checklist]
- [x] I have followed the [perfect PR recommendations][perfect-pr]
- [x] The code has been formatted using Ruff (`ruff format homeassistant tests`)
- [x] Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

- [ ] Documentation added/updated for [www.home-assistant.io][docs-repository]

If the code communicates with devices, web services, or third-party tools:

- [ ] The [manifest file][manifest-docs] has all fields filled out correctly.  
      Updated and included derived files by running: `python3 -m script.hassfest`.
- [ ] New or updated dependencies have been added to `requirements_all.txt`.  
      Updated by running `python3 -m script.gen_requirements_all`.
- [ ] For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.

<!--
  This project is very active and we have a high turnover of pull requests.

  Unfortunately, the number of incoming pull requests is higher than what our
  reviewers can review and merge so there is a long backlog of pull requests
  waiting for review. You can help here!
  
  By reviewing another pull request, you will help raise the code quality of
  that pull request and the final review will be faster. This way the general
  pace of pull request reviews will go up and your wait time will go down.
  
  When picking a pull request to review, try to choose one that hasn't yet
  been reviewed.

  Thanks for helping out!
-->

To help with the load of incoming pull requests:

- [x] I have reviewed two other [open pull requests][prs] in this repository.

[prs]: https://github.com/home-assistant/core/pulls?q=is%3Aopen+is%3Apr+-author%3A%40me+-draft%3Atrue+-label%3Awaiting-for-upstream+sort%3Acreated-desc+review%3Anone+-status%3Afailure

<!--
  Thank you for contributing <3

  Below, some useful links you could explore:
-->
[dev-checklist]: https://developers.home-assistant.io/docs/development_checklist/
[manifest-docs]: https://developers.home-assistant.io/docs/creating_integration_manifest/
[quality-scale]: https://developers.home-assistant.io/docs/integration_quality_scale_index/
[docs-repository]: https://github.com/home-assistant/home-assistant.io
[perfect-pr]: https://developers.home-assistant.io/docs/review-process/#creating-the-perfect-pr


Problem statement:
Do not factory reset old controller during NVM migration
We decided that the risk of resetting a working controller before the replacement is up and running is more relevant than the potential issue of a user leaving the old controller plugged in and messing with communication.

Hints from issue discussion:

Commit message: Do not factory reset old Z-Wave controller during migration

Patch to review:
diff --git a/homeassistant/components/zwave_js/config_flow.py b/homeassistant/components/zwave_js/config_flow.py
index 5e8e702283976f..8fe05f91f01a03 100644
--- a/homeassistant/components/zwave_js/config_flow.py
+++ b/homeassistant/components/zwave_js/config_flow.py
@@ -843,11 +843,8 @@ async def async_step_intent_migrate(
                 },
             )
 
-        if user_input is not None:
-            self._migrating = True
-            return await self.async_step_backup_nvm()
-
-        return self.async_show_form(step_id="intent_migrate")
+        self._migrating = True
+        return await self.async_step_backup_nvm()
 
     async def async_step_backup_nvm(
         self, user_input: dict[str, Any] | None = None
@@ -902,7 +899,7 @@ async def async_step_restore_nvm(
     async def async_step_instruct_unplug(
         self, user_input: dict[str, Any] | None = None
     ) -> ConfigFlowResult:
-        """Reset the current controller, and instruct the user to unplug it."""
+        """Instruct the user to unplug the old controller."""
 
         if user_input is not None:
             if self.usb_path:
@@ -912,63 +909,9 @@ async def async_step_instruct_unplug(
             # Now that the old controller is gone, we can scan for serial ports again
             return await self.async_step_choose_serial_port()
 
-        try:
-            driver = self._get_driver()
-        except AbortFlow:
-            return self.async_abort(reason="config_entry_not_loaded")
-
-        @callback
-        def set_driver_ready(event: dict) -> None:
-            "Set the driver ready event."
-            wait_driver_ready.set()
-
-        wait_driver_ready = asyncio.Event()
-
-        unsubscribe = driver.once("driver ready", set_driver_ready)
-
-        # reset the old controller
-        try:
-            await driver.async_hard_reset()
-        except FailedCommand as err:
-            unsubscribe()
-            _LOGGER.error("Failed to reset controller: %s", err)
-            return self.async_abort(reason="reset_failed")
-
-        # Update the unique id of the config entry
-        # to the new home id, which requires waiting for the driver
-        # to be ready before getting the new home id.
-        # If the backup restore, done later in the flow, fails,
-        # the config entry unique id should be the new home id
-        # after the controller reset.
-        try:
-            async with asyncio.timeout(DRIVER_READY_TIMEOUT):
-                await wait_driver_ready.wait()
-        except TimeoutError:
-            pass
-        finally:
-            unsubscribe()
-
         config_entry = self._reconfigure_config_entry
         assert config_entry is not None
 
-        try:
-            version_info = await async_get_version_info(
-                self.hass, config_entry.data[CONF_URL]
-            )
-        except CannotConnect:
-            # Just log this error, as there's nothing to do about it here.
-            # The stale unique id needs to be handled by a repair flow,
-            # after the config entry has been reloaded, if the backup restore
-            # also fails.
-            _LOGGER.debug(
-                "Failed to get server version, cannot update config entry "
-                "unique id with new home id, after controller reset"
-            )
-        else:
-            self.hass.config_entries.async_update_entry(
-                config_entry, unique_id=str(version_info.home_id)
-            )
-
         # Unload the config entry before asking the user to unplug the controller.
         await self.hass.config_entries.async_unload(config_entry.entry_id)
 
diff --git a/homeassistant/components/zwave_js/strings.json b/homeassistant/components/zwave_js/strings.json
index d9a3b82a47ca62..04bef3f8d25e4d 100644
--- a/homeassistant/components/zwave_js/strings.json
+++ b/homeassistant/components/zwave_js/strings.json
@@ -109,12 +109,11 @@
         }
       },
       "intent_migrate": {
-        "title": "[%key:component::zwave_js::config::step::reconfigure::menu_options::intent_migrate%]",
-        "description": "Before setting up your new controller, your old controller needs to be reset. A backup will be performed first.\n\nDo you wish to continue?"
+        "title": "[%key:component::zwave_js::config::step::reconfigure::menu_options::intent_migrate%]"
       },
       "instruct_unplug": {
         "title": "Unplug your old controller",
-        "description": "Backup saved to \"{file_path}\"\n\nYour old controller has been reset. If the hardware is no longer needed, you can now unplug it.\n\nPlease make sure your new controller is plugged in before continuing."
+        "description": "Backup saved to \"{file_path}\"\n\nYour old controller has not been reset. You should now unplug it to prevent it from interfering with the new controller.\n\nPlease make sure your new controller is plugged in before continuing."
       },
       "restore_failed": {
         "title": "Restoring unsuccessful",
diff --git a/tests/components/zwave_js/test_config_flow.py b/tests/components/zwave_js/test_config_flow.py
index dd8838e0775d09..3c5f9a2c8b8bbd 100644
--- a/tests/components/zwave_js/test_config_flow.py
+++ b/tests/components/zwave_js/test_config_flow.py
@@ -864,11 +864,8 @@ async def test_usb_discovery_migration(
     restart_addon: AsyncMock,
     client: MagicMock,
     integration: MockConfigEntry,
-    get_server_version: AsyncMock,
 ) -> None:
     """Test usb discovery migration."""
-    version_info = get_server_version.return_value
-    version_info.home_id = 4321
     addon_options["device"] = "/dev/ttyUSB0"
     entry = integration
     assert client.connect.call_count == 1
@@ -893,13 +890,6 @@ async def mock_backup_nvm_raw():
         side_effect=mock_backup_nvm_raw
     )
 
-    async def mock_reset_controller():
-        client.driver.emit(
-            "driver ready", {"event": "driver ready", "source": "driver"}
-        )
-
-    client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
-
     async def mock_restore_nvm(data: bytes):
         client.driver.controller.emit(
             "nvm convert progress",
@@ -927,10 +917,6 @@ async def mock_restore_nvm(data: bytes):
     )
 
     assert mock_usb_serial_by_id.call_count == 2
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
 
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "backup_nvm"
@@ -947,7 +933,6 @@ async def mock_restore_nvm(data: bytes):
 
     assert result["type"] is FlowResultType.FORM
     assert result["step_id"] == "instruct_unplug"
-    assert entry.unique_id == "4321"
 
     result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
 
@@ -962,8 +947,6 @@ async def mock_restore_nvm(data: bytes):
 
     assert restart_addon.call_args == call("core_zwave_js")
 
-    version_info.home_id = 5678
-
     result = await hass.config_entries.flow.async_configure(result["flow_id"])
 
     assert result["type"] is FlowResultType.SHOW_PROGRESS
@@ -986,7 +969,6 @@ async def mock_restore_nvm(data: bytes):
     assert entry.data["usb_path"] == USB_DISCOVERY_INFO.device
     assert entry.data["use_addon"] is True
     assert "keep_old_devices" not in entry.data
-    assert entry.unique_id == "5678"
 
 
 @pytest.mark.usefixtures("supervisor", "addon_running")
@@ -1024,13 +1006,6 @@ async def mock_backup_nvm_raw():
         side_effect=mock_backup_nvm_raw
     )
 
-    async def mock_reset_controller():
-        client.driver.emit(
-            "driver ready", {"event": "driver ready", "source": "driver"}
-        )
-
-    client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
-
     async def mock_restore_nvm(data: bytes):
         client.driver.controller.emit(
             "nvm convert progress",
@@ -1055,10 +1030,6 @@ async def mock_restore_nvm(data: bytes):
     )
 
     assert mock_usb_serial_by_id.call_count == 2
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
 
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "backup_nvm"
@@ -3399,25 +3370,6 @@ async def test_reconfigure_migrate_low_sdk_version(
 
 
 @pytest.mark.usefixtures("supervisor", "addon_running")
-@pytest.mark.parametrize(
-    (
-        "reset_server_version_side_effect",
-        "reset_unique_id",
-        "restore_server_version_side_effect",
-        "final_unique_id",
-    ),
-    [
-        (None, "4321", None, "3245146787"),
-        (aiohttp.ClientError("Boom"), "3245146787", None, "3245146787"),
-        (None, "4321", aiohttp.ClientError("Boom"), "5678"),
-        (
-            aiohttp.ClientError("Boom"),
-            "3245146787",
-            aiohttp.ClientError("Boom"),
-            "5678",
-        ),
-    ],
-)
 async def test_reconfigure_migrate_with_addon(
     hass: HomeAssistant,
     client: MagicMock,
@@ -3427,16 +3379,8 @@ async def test_reconfigure_migrate_with_addon(
     restart_addon: AsyncMock,
     addon_options: dict[str, Any],
     set_addon_options: AsyncMock,
-    get_server_version: AsyncMock,
-    reset_server_version_side_effect: Exception | None,
-    reset_unique_id: str,
-    restore_server_version_side_effect: Exception | None,
-    final_unique_id: str,
 ) -> None:
     """Test migration flow with add-on."""
-    get_server_version.side_effect = reset_server_version_side_effect
-    version_info = get_server_version.return_value
-    version_info.home_id = 4321
     entry = integration
     assert client.connect.call_count == 1
     assert client.driver.controller.home_id == 3245146787
@@ -3494,13 +3438,6 @@ async def mock_backup_nvm_raw():
         side_effect=mock_backup_nvm_raw
     )
 
-    async def mock_reset_controller():
-        client.driver.emit(
-            "driver ready", {"event": "driver ready", "source": "driver"}
-        )
-
-    client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
-
     async def mock_restore_nvm(data: bytes):
         client.driver.controller.emit(
             "nvm convert progress",
@@ -3531,11 +3468,6 @@ async def mock_restore_nvm(data: bytes):
         result["flow_id"], {"next_step_id": "intent_migrate"}
     )
 
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "backup_nvm"
 
@@ -3552,7 +3484,6 @@ async def mock_restore_nvm(data: bytes):
     assert result["type"] is FlowResultType.FORM
     assert result["step_id"] == "instruct_unplug"
     assert entry.state is config_entries.ConfigEntryState.NOT_LOADED
-    assert entry.unique_id == reset_unique_id
 
     result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
 
@@ -3565,10 +3496,6 @@ async def mock_restore_nvm(data: bytes):
     with pytest.raises(InInvalid):
         data_schema.schema[CONF_USB_PATH](addon_options["device"])
 
-    # Reset side effect before starting the add-on.
-    get_server_version.side_effect = None
-    version_info.home_id = 5678
-
     result = await hass.config_entries.flow.async_configure(
         result["flow_id"],
         user_input={
@@ -3599,10 +3526,6 @@ async def mock_restore_nvm(data: bytes):
 
     result = await hass.config_entries.flow.async_configure(result["flow_id"])
 
-    assert entry.unique_id == "5678"
-    get_server_version.side_effect = restore_server_version_side_effect
-    version_info.home_id = 3245146787
-
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "restore_nvm"
     assert client.connect.call_count == 2
@@ -3623,7 +3546,6 @@ async def mock_restore_nvm(data: bytes):
     assert entry.data["usb_path"] == "/test"
     assert entry.data["use_addon"] is True
     assert "keep_old_devices" not in entry.data
-    assert entry.unique_id == final_unique_id
 
     assert len(device_registry.devices) == 2
     controller_device_id_ext = (
@@ -3653,11 +3575,8 @@ async def test_reconfigure_migrate_reset_driver_ready_timeout(
     integration: MockConfigEntry,
     restart_addon: AsyncMock,
     set_addon_options: AsyncMock,
-    get_server_version: AsyncMock,
 ) -> None:
     """Test migration flow with driver ready timeout after controller reset."""
-    version_info = get_server_version.return_value
-    version_info.home_id = 4321
     entry = integration
     assert client.connect.call_count == 1
     hass.config_entries.async_update_entry(
@@ -3681,11 +3600,6 @@ async def mock_backup_nvm_raw():
         side_effect=mock_backup_nvm_raw
     )
 
-    async def mock_reset_controller():
-        await asyncio.sleep(0)
-
-    client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
-
     async def mock_restore_nvm(data: bytes):
         client.driver.controller.emit(
             "nvm convert progress",
@@ -3715,9 +3629,6 @@ async def mock_restore_nvm(data: bytes):
         result["flow_id"], {"next_step_id": "intent_migrate"}
     )
 
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
     with (
         patch(
             ("homeassistant.components.zwave_js.config_flow.DRIVER_READY_TIMEOUT"),
@@ -3742,7 +3653,6 @@ async def mock_restore_nvm(data: bytes):
     assert result["type"] is FlowResultType.FORM
     assert result["step_id"] == "instruct_unplug"
     assert entry.state is config_entries.ConfigEntryState.NOT_LOADED
-    assert entry.unique_id == "4321"
 
     result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
 
@@ -3769,8 +3679,6 @@ async def mock_restore_nvm(data: bytes):
 
     assert restart_addon.call_args == call("core_zwave_js")
 
-    version_info.home_id = 5678
-
     result = await hass.config_entries.flow.async_configure(result["flow_id"])
 
     assert result["type"] is FlowResultType.SHOW_PROGRESS
@@ -3792,7 +3700,6 @@ async def mock_restore_nvm(data: bytes):
     assert entry.data["url"] == "ws://host1:3001"
     assert entry.data["usb_path"] == "/test"
     assert entry.data["use_addon"] is True
-    assert entry.unique_id == "5678"
     assert "keep_old_devices" not in entry.data
 
 
@@ -3828,13 +3735,6 @@ async def mock_backup_nvm_raw():
         side_effect=mock_backup_nvm_raw
     )
 
-    async def mock_reset_controller():
-        client.driver.emit(
-            "driver ready", {"event": "driver ready", "source": "driver"}
-        )
-
-    client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
-
     async def mock_restore_nvm(data: bytes):
         client.driver.controller.emit(
             "nvm convert progress",
@@ -3861,11 +3761,6 @@ async def mock_restore_nvm(data: bytes):
         result["flow_id"], {"next_step_id": "intent_migrate"}
     )
 
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "backup_nvm"
 
@@ -3960,11 +3855,6 @@ async def test_reconfigure_migrate_backup_failure(
         result["flow_id"], {"next_step_id": "intent_migrate"}
     )
 
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
     assert result["type"] is FlowResultType.ABORT
     assert result["reason"] == "backup_failed"
     assert "keep_old_devices" not in entry.data
@@ -3998,11 +3888,6 @@ async def mock_backup_nvm_raw():
         result["flow_id"], {"next_step_id": "intent_migrate"}
     )
 
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "backup_nvm"
 
@@ -4040,13 +3925,6 @@ async def mock_backup_nvm_raw():
         side_effect=mock_backup_nvm_raw
     )
 
-    async def mock_reset_controller():
-        client.driver.emit(
-            "driver ready", {"event": "driver ready", "source": "driver"}
-        )
-
-    client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
-
     result = await entry.start_reconfigure_flow(hass)
 
     assert result["type"] is FlowResultType.MENU
@@ -4056,11 +3934,6 @@ async def mock_reset_controller():
         result["flow_id"], {"next_step_id": "intent_migrate"}
     )
 
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "backup_nvm"
 
@@ -4124,12 +3997,6 @@ async def mock_backup_nvm_raw():
         side_effect=mock_backup_nvm_raw
     )
 
-    async def mock_reset_controller():
-        client.driver.emit(
-            "driver ready", {"event": "driver ready", "source": "driver"}
-        )
-
-    client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
     client.driver.controller.async_restore_nvm = AsyncMock(
         side_effect=FailedCommand("test_error", "unknown_error")
     )
@@ -4143,11 +4010,6 @@ async def mock_reset_controller():
         result["flow_id"], {"next_step_id": "intent_migrate"}
     )
 
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "backup_nvm"
 
@@ -4242,106 +4104,6 @@ async def test_get_driver_failure_intent_migrate(
     assert "keep_old_devices" not in entry.data
 
 
-async def test_get_driver_failure_instruct_unplug(
-    hass: HomeAssistant,
-    client: MagicMock,
-    integration: MockConfigEntry,
-) -> None:
-    """Test get driver failure in instruct unplug step."""
-
-    async def mock_backup_nvm_raw():
-        await asyncio.sleep(0)
-        client.driver.controller.emit(
-            "nvm backup progress", {"bytesRead": 100, "total": 200}
-        )
-        return b"test_nvm_data"
-
-    client.driver.controller.async_backup_nvm_raw = AsyncMock(
-        side_effect=mock_backup_nvm_raw
-    )
-    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.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
-    assert result["type"] is FlowResultType.SHOW_PROGRESS
-    assert result["step_id"] == "backup_nvm"
-
-    with patch("pathlib.Path.write_bytes") as mock_file:
-        await hass.async_block_till_done()
-        assert client.driver.controller.async_backup_nvm_raw.call_count == 1
-        assert mock_file.call_count == 1
-
-    await hass.config_entries.async_unload(entry.entry_id)
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"])
-
-    assert result["type"] is FlowResultType.ABORT
-    assert result["reason"] == "config_entry_not_loaded"
-
-
-async def test_hard_reset_failure(
-    hass: HomeAssistant,
-    integration: MockConfigEntry,
-    client: MagicMock,
-) -> None:
-    """Test hard reset failure."""
-    entry = integration
-    hass.config_entries.async_update_entry(
-        entry, unique_id="1234", data={**entry.data, "use_addon": True}
-    )
-
-    async def mock_backup_nvm_raw():
-        await asyncio.sleep(0)
-        return b"test_nvm_data"
-
-    client.driver.controller.async_backup_nvm_raw = AsyncMock(
-        side_effect=mock_backup_nvm_raw
-    )
-    client.driver.async_hard_reset = AsyncMock(
-        side_effect=FailedCommand("test_error", "unknown_error")
-    )
-
-    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.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
-    assert result["type"] is FlowResultType.SHOW_PROGRESS
-    assert result["step_id"] == "backup_nvm"
-
-    with patch("pathlib.Path.write_bytes") as mock_file:
-        await hass.async_block_till_done()
-        assert client.driver.controller.async_backup_nvm_raw.call_count == 1
-        assert mock_file.call_count == 1
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"])
-
-    assert result["type"] is FlowResultType.ABORT
-    assert result["reason"] == "reset_failed"
-
-
 async def test_choose_serial_port_usb_ports_failure(
     hass: HomeAssistant,
     integration: MockConfigEntry,
@@ -4361,13 +4123,6 @@ async def mock_backup_nvm_raw():
         side_effect=mock_backup_nvm_raw
     )
 
-    async def mock_reset_controller():
-        client.driver.emit(
-            "driver ready", {"event": "driver ready", "source": "driver"}
-        )
-
-    client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
-
     result = await entry.start_reconfigure_flow(hass)
 
     assert result["type"] is FlowResultType.MENU
@@ -4377,11 +4132,6 @@ async def mock_reset_controller():
         result["flow_id"], {"next_step_id": "intent_migrate"}
     )
 
-    assert result["type"] is FlowResultType.FORM
-    assert result["step_id"] == "intent_migrate"
-
-    result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
-
     assert result["type"] is FlowResultType.SHOW_PROGRESS
     assert result["step_id"] == "backup_nvm"
 


Code review comments:
diff_hunk: @@ -3399,25 +3370,6 @@ async def test_reconfigure_migrate_low_sdk_version(
 
 
 @pytest.mark.usefixtures("supervisor", "addon_running")
-@pytest.mark.parametrize(
path: tests/components/zwave_js/test_config_flow.py
text: @user1:
Don't remove all of this. Just remove the reset side effects and corresponding unique id.

diff_hunk: @@ -109,12 +109,11 @@
         }
       },
       "intent_migrate": {
-        "title": "[%key:component::zwave_js::config::step::reconfigure::menu_options::intent_migrate%]",
-        "description": "Before setting up your new controller, your old controller needs to be reset. A backup will be performed first.\n\nDo you wish to continue?"
+        "title": "[%key:component::zwave_js::config::step::reconfigure::menu_options::intent_migrate%]"
path: homeassistant/components/zwave_js/strings.json
text: @user1:
There's no form at all in the intent_migrate step now, right? Then we can remove the strings for that step.