diff --git a/homeassistant/components/zwave_js/api.py b/homeassistant/components/zwave_js/api.py index 5f6050b88e9..c1a24b6ea65 100644 --- a/homeassistant/components/zwave_js/api.py +++ b/homeassistant/components/zwave_js/api.py @@ -3113,6 +3113,27 @@ async def websocket_restore_nvm( with suppress(TimeoutError): async with asyncio.timeout(DRIVER_READY_TIMEOUT): await wait_driver_ready.wait() + + # When restoring the NVM to the controller, the controller home id is also changed. + # The controller state in the client is stale after restoring the NVM, + # so get the new home id with a new client using the helper function. + # The client state will be refreshed by reloading the config entry, + # after the unique id of the config entry has been updated. + try: + version_info = await async_get_version_info(hass, 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. + LOGGER.error( + "Failed to get server version, cannot update config entry" + "unique id with new home id, after controller NVM restore" + ) + else: + hass.config_entries.async_update_entry( + entry, unique_id=str(version_info.home_id) + ) + await hass.config_entries.async_reload(entry.entry_id) connection.send_message( diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index d2f0f205e8f..83a22cbee32 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -5567,8 +5567,12 @@ async def test_restore_nvm( integration, client, hass_ws_client: WebSocketGenerator, + get_server_version: AsyncMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test the restore NVM websocket command.""" + entry = integration + assert entry.unique_id == "3245146787" ws_client = await hass_ws_client(hass) # Set up mocks for the controller events @@ -5648,6 +5652,45 @@ async def test_restore_nvm( }, require_schema=14, ) + assert entry.unique_id == "1234" + + client.async_send_command.reset_mock() + + # Test client connect error when getting the server version. + + get_server_version.side_effect = ClientError("Boom!") + + # Send the subscription request + await ws_client.send_json_auto_id( + { + "type": "zwave_js/restore_nvm", + "entry_id": entry.entry_id, + "data": "dGVzdA==", # base64 encoded "test" + } + ) + + # Verify the finished event first + msg = await ws_client.receive_json() + assert msg["type"] == "event" + assert msg["event"]["event"] == "finished" + + # Verify subscription success + msg = await ws_client.receive_json() + assert msg["type"] == "result" + assert msg["success"] is True + + assert client.async_send_command.call_count == 3 + assert client.async_send_command.call_args_list[0] == call( + { + "command": "controller.restore_nvm", + "nvmData": "dGVzdA==", + }, + require_schema=14, + ) + assert ( + "Failed to get server version, cannot update config entry" + "unique id with new home id, after controller NVM restore" + ) in caplog.text client.async_send_command.reset_mock()