async def call_method(
        self,
        name: str,
        params: _Any,
        resource: _Optional[_Path] = None,
    ) -> _Tuple[_Any, _Optional[_Path]]:
        """
        Asynchronously call a method on the remote device.

        This method sends a JSON-RPC request to the device and waits for the response.
        It handles the creation of the request, sending it through the socket, and polling
        for the response.

        Parameters
        ----------
        name: str
            The name of the method to call on the remote device.

        params: Any
            The parameters to pass to the method. Can be any JSON-serializable object.

        resource: Optional[Path]
            Path to a resource file to be sent with the request. Defaults to None.

        Returns
        -------
        Tuple[Any, Optional[Path]]
            A tuple containing:
            - The result of the method call (Any)
            - The path to any resource returned by the method (Optional[Path])
        """

        def should_throw_exception(attempt: int) -> bool:
            return not self.socket.is_alive or (attempt + 1) == self.max_attempts

        request = _JSONRPCRequest(
            id=str(_uuid.uuid4()),
            method=name,
            params=params,
        )

        for attempt in _tqdm.tqdm(
            range(self.max_attempts),
            desc=f"\033[1mInitiating data transfer to '{self.socket.device.name}' for {name}. Attempts \033[0m",
        ):
            if resource is not None and not resource.exists():
                raise _DeviceCtlError(f"Resource file {resource.absolute()} does not exist.")
            try:
                await self._event_loop.run_in_executor(None, self.socket.send, request, resource)
                break
            except _DeviceCtlError as e:
                _logger.info(
                    f"Failed to send request: {request}, code: {e.error_code}, message: {e.message}"
                )
                if should_throw_exception(attempt=attempt):
                    raise e

            await _asyncio.sleep(self.poll_time)

        response = None
        for attempt in _tqdm.tqdm(
            range(self.max_attempts),
            desc=f"\033[1mInitiating data transfer from {self.socket.device.name} for {name}. Attempts \033[0m",
        ):
            try:
                response = await self._event_loop.run_in_executor(
                    None, self.socket.receive, request.id
                )
                if response is not None:
                    break
            except _DeviceCtlError as e:
                _logger.info(
                    f"Failed to receive response of id: {request.id}, code: {e.error_code}, message: {e.message}"
                )
                if should_throw_exception(attempt=attempt):
                    raise e

            await _asyncio.sleep(self.poll_time)

        if response.error is not None:
            raise _DeviceCtlError(error_code=response.error.code, message=response.error.message)

        return (response.result, response.resource)

        Asynchronously call a method on the remote device.

        This method sends a JSON-RPC request to the device and waits for the response.
        It handles the creation of the request, sending it through the socket, and polling
        for the response.

        Parameters
        ----------
        name: str
            The name of the method to call on the remote device.

        params: Any
            The parameters to pass to the method. Can be any JSON-serializable object.

        resource: Optional[Path]
            Path to a resource file to be sent with the request. Defaults to None.

        Returns
        -------
        Tuple[Any, Optional[Path]]
            A tuple containing:
            - The result of the method call (Any)
            - The path to any resource returned by the method (Optional[Path])
        
coremltools/models/ml_program/experimental/remote_device.py