# This file was auto-generated by Fern from our API Definition.

import typing
from ..core.client_wrapper import SyncClientWrapper
from .types.auto_control_request_type_of_model import AutoControlRequestTypeOfModel
from ..core.request_options import RequestOptions
from ..types.status_response import StatusResponse
from ..core.pydantic_utilities import parse_obj_as
from ..errors.unprocessable_entity_error import UnprocessableEntityError
from ..types.http_validation_error import HttpValidationError
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from ..types.calibrate_response import CalibrateResponse
from ..types.end_effector_position import EndEffectorPosition
from ..types.joints_read_response import JointsReadResponse
from .types.unit import Unit
from .types.environment import Environment
from .types.source import Source
from ..types.torque_read_response import TorqueReadResponse
from ..types.voltage_read_response import VoltageReadResponse
from ..core.client_wrapper import AsyncClientWrapper

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class ControlClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def start_auto(
        self,
        *,
        type_of_model: AutoControlRequestTypeOfModel,
        robot_id: typing.Optional[int] = None,
        instruction: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Start automatic control of the robot using OpenVLA model outputs.

        Parameters
        ----------
        type_of_model : AutoControlRequestTypeOfModel
            Type of model, either OpenVLA or ACT

        robot_id : typing.Optional[int]

        instruction : typing.Optional[str]
            Prompt to be followed by the robot when using OpenVLA

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.start_auto(
            type_of_model="openvla",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "auto/start",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "instruction": instruction,
                "type_of_model": type_of_model,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def stop_auto(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> StatusResponse:
        """
        Stop the automatic control process.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.stop_auto()
        """
        _response = self._client_wrapper.httpx_client.request(
            "auto/stop",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def calibrate(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CalibrateResponse:
        """
        Start the calibration sequence for the robot.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        CalibrateResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.calibrate()
        """
        _response = self._client_wrapper.httpx_client.request(
            "calibrate",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CalibrateResponse,
                    parse_obj_as(
                        type_=CalibrateResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def end_effector_read(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EndEffectorPosition:
        """
        Retrieve the position, orientation, and open status of the robot's end effector.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        EndEffectorPosition
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.end_effector_read()
        """
        _response = self._client_wrapper.httpx_client.request(
            "end-effector/read",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EndEffectorPosition,
                    parse_obj_as(
                        type_=EndEffectorPosition,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def read_joints(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> JointsReadResponse:
        """
        Read the current positions of the robot's joints in radians and motor units.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        JointsReadResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.read_joints()
        """
        _response = self._client_wrapper.httpx_client.request(
            "joints/read",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    JointsReadResponse,
                    parse_obj_as(
                        type_=JointsReadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def write_joints(
        self,
        *,
        angles: typing.Sequence[float],
        robot_id: typing.Optional[int] = None,
        unit: typing.Optional[Unit] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Move the robot's joints to the specified angles.

        Parameters
        ----------
        angles : typing.Sequence[float]
            A list of length 7, with the position of each joint in radian.

        robot_id : typing.Optional[int]

        unit : typing.Optional[Unit]
            The unit of the angles. Defaults to radian.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.write_joints(
            angles=[1.1],
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "joints/write",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "angles": angles,
                "unit": unit,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def move_to_absolute_position(
        self,
        *,
        open: float,
        rx: float,
        ry: float,
        rz: float,
        x: float,
        y: float,
        z: float,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Move the robot to an absolute position specified by the end-effector.

        Parameters
        ----------
        open : float
            0 for closed, 1 for open

        rx : float
            Absolute Pitch in degrees

        ry : float
            Absolute Yaw in degrees

        rz : float
            Absolute Roll in degrees

        x : float

        y : float

        z : float

        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.move_to_absolute_position(
            open=1.1,
            rx=1.1,
            ry=1.1,
            rz=1.1,
            x=1.1,
            y=1.1,
            z=1.1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "move/absolute",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "open": open,
                "rx": rx,
                "ry": ry,
                "rz": rz,
                "x": x,
                "y": y,
                "z": z,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def move_init(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Initialize the robot to its initial position before starting the teleoperation.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.move_init()
        """
        _response = self._client_wrapper.httpx_client.request(
            "move/init",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def mimicking_robots(
        self,
        *,
        duration: int,
        environment: typing.Optional[Environment] = None,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Mimick the movements of a leader robot to a follower robot for a specified duration.

        Parameters
        ----------
        duration : int

        environment : typing.Optional[Environment]

        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.mimicking_robots(
            duration=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "move/mimick",
            method="POST",
            params={
                "duration": duration,
                "environment": environment,
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def move_relative(
        self,
        *,
        open: float,
        rx: float,
        ry: float,
        rz: float,
        x: float,
        y: float,
        z: float,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Move the robot to a relative position based on received delta values.

        Parameters
        ----------
        open : float

        rx : float
            Relative Pitch in radian

        ry : float
            Relative Yaw in radian

        rz : float
            Relative Roll in radian

        x : float

        y : float

        z : float

        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.move_relative(
            open=1.1,
            rx=1.1,
            ry=1.1,
            rz=1.1,
            x=1.1,
            y=1.1,
            z=1.1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "move/relative",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "open": open,
                "rx": rx,
                "ry": ry,
                "rz": rz,
                "x": x,
                "y": y,
                "z": z,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def move_teleoperation(
        self,
        *,
        open: float,
        rx: float,
        ry: float,
        rz: float,
        x: float,
        y: float,
        z: float,
        robot_id: typing.Optional[int] = None,
        source: typing.Optional[Source] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Update the robot position based on the received teleoperation data.

        Parameters
        ----------
        open : float
            0 for closed, 1 for open

        rx : float
            Absolute Pitch in degrees

        ry : float
            Absolute Yaw in degrees

        rz : float
            Absolute Roll in degrees

        x : float

        y : float

        z : float

        robot_id : typing.Optional[int]

        source : typing.Optional[Source]
            Which hand the data comes from. Can be left or right.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.move_teleoperation(
            open=1.1,
            rx=1.1,
            ry=1.1,
            rz=1.1,
            x=1.1,
            y=1.1,
            z=1.1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "move/teleop",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "open": open,
                "rx": rx,
                "ry": ry,
                "rz": rz,
                "source": source,
                "x": x,
                "y": y,
                "z": z,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def read_torque(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TorqueReadResponse:
        """
        Read the current torque of the robot's joints.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TorqueReadResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.read_torque()
        """
        _response = self._client_wrapper.httpx_client.request(
            "torque/read",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TorqueReadResponse,
                    parse_obj_as(
                        type_=TorqueReadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def toggle_torque(
        self,
        *,
        torque_status: bool,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Enable or disable the torque of the robot.

        Parameters
        ----------
        torque_status : bool

        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.toggle_torque(
            torque_status=True,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "torque/toggle",
            method="POST",
            params={
                "torque_status": torque_status,
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def read_voltage(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> VoltageReadResponse:
        """
        Read the current voltage of the robot's motors.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        VoltageReadResponse
            Successful Response

        Examples
        --------
        from phospho import PhosphobotApi

        client = PhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )
        client.control.read_voltage()
        """
        _response = self._client_wrapper.httpx_client.request(
            "voltage/read",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    VoltageReadResponse,
                    parse_obj_as(
                        type_=VoltageReadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncControlClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def start_auto(
        self,
        *,
        type_of_model: AutoControlRequestTypeOfModel,
        robot_id: typing.Optional[int] = None,
        instruction: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Start automatic control of the robot using OpenVLA model outputs.

        Parameters
        ----------
        type_of_model : AutoControlRequestTypeOfModel
            Type of model, either OpenVLA or ACT

        robot_id : typing.Optional[int]

        instruction : typing.Optional[str]
            Prompt to be followed by the robot when using OpenVLA

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.start_auto(
                type_of_model="openvla",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "auto/start",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "instruction": instruction,
                "type_of_model": type_of_model,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def stop_auto(
        self, *, request_options: typing.Optional[RequestOptions] = None
    ) -> StatusResponse:
        """
        Stop the automatic control process.

        Parameters
        ----------
        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.stop_auto()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "auto/stop",
            method="POST",
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def calibrate(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CalibrateResponse:
        """
        Start the calibration sequence for the robot.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        CalibrateResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.calibrate()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "calibrate",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    CalibrateResponse,
                    parse_obj_as(
                        type_=CalibrateResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def end_effector_read(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> EndEffectorPosition:
        """
        Retrieve the position, orientation, and open status of the robot's end effector.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        EndEffectorPosition
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.end_effector_read()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "end-effector/read",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    EndEffectorPosition,
                    parse_obj_as(
                        type_=EndEffectorPosition,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def read_joints(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> JointsReadResponse:
        """
        Read the current positions of the robot's joints in radians and motor units.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        JointsReadResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.read_joints()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "joints/read",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    JointsReadResponse,
                    parse_obj_as(
                        type_=JointsReadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def write_joints(
        self,
        *,
        angles: typing.Sequence[float],
        robot_id: typing.Optional[int] = None,
        unit: typing.Optional[Unit] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Move the robot's joints to the specified angles.

        Parameters
        ----------
        angles : typing.Sequence[float]
            A list of length 7, with the position of each joint in radian.

        robot_id : typing.Optional[int]

        unit : typing.Optional[Unit]
            The unit of the angles. Defaults to radian.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.write_joints(
                angles=[1.1],
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "joints/write",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "angles": angles,
                "unit": unit,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def move_to_absolute_position(
        self,
        *,
        open: float,
        rx: float,
        ry: float,
        rz: float,
        x: float,
        y: float,
        z: float,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Move the robot to an absolute position specified by the end-effector.

        Parameters
        ----------
        open : float
            0 for closed, 1 for open

        rx : float
            Absolute Pitch in degrees

        ry : float
            Absolute Yaw in degrees

        rz : float
            Absolute Roll in degrees

        x : float

        y : float

        z : float

        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.move_to_absolute_position(
                open=1.1,
                rx=1.1,
                ry=1.1,
                rz=1.1,
                x=1.1,
                y=1.1,
                z=1.1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "move/absolute",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "open": open,
                "rx": rx,
                "ry": ry,
                "rz": rz,
                "x": x,
                "y": y,
                "z": z,
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def move_init(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Initialize the robot to its initial position before starting the teleoperation.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.move_init()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "move/init",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def mimicking_robots(
        self,
        *,
        duration: int,
        environment: typing.Optional[Environment] = None,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Mimick the movements of a leader robot to a follower robot for a specified duration.

        Parameters
        ----------
        duration : int

        environment : typing.Optional[Environment]

        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.mimicking_robots(
                duration=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "move/mimick",
            method="POST",
            params={
                "duration": duration,
                "environment": environment,
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def move_relative(
        self,
        *,
        open: float,
        rx: float,
        ry: float,
        rz: float,
        x: float,
        y: float,
        z: float,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Move the robot to a relative position based on received delta values.

        Parameters
        ----------
        open : float

        rx : float
            Relative Pitch in radian

        ry : float
            Relative Yaw in radian

        rz : float
            Relative Roll in radian

        x : float

        y : float

        z : float

        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.move_relative(
                open=1.1,
                rx=1.1,
                ry=1.1,
                rz=1.1,
                x=1.1,
                y=1.1,
                z=1.1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "move/relative",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "open": open,
                "rx": rx,
                "ry": ry,
                "rz": rz,
                "x": x,
                "y": y,
                "z": z,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def move_teleoperation(
        self,
        *,
        open: float,
        rx: float,
        ry: float,
        rz: float,
        x: float,
        y: float,
        z: float,
        robot_id: typing.Optional[int] = None,
        source: typing.Optional[Source] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Update the robot position based on the received teleoperation data.

        Parameters
        ----------
        open : float
            0 for closed, 1 for open

        rx : float
            Absolute Pitch in degrees

        ry : float
            Absolute Yaw in degrees

        rz : float
            Absolute Roll in degrees

        x : float

        y : float

        z : float

        robot_id : typing.Optional[int]

        source : typing.Optional[Source]
            Which hand the data comes from. Can be left or right.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.move_teleoperation(
                open=1.1,
                rx=1.1,
                ry=1.1,
                rz=1.1,
                x=1.1,
                y=1.1,
                z=1.1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "move/teleop",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            json={
                "open": open,
                "rx": rx,
                "ry": ry,
                "rz": rz,
                "source": source,
                "x": x,
                "y": y,
                "z": z,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def read_torque(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TorqueReadResponse:
        """
        Read the current torque of the robot's joints.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TorqueReadResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.read_torque()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "torque/read",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TorqueReadResponse,
                    parse_obj_as(
                        type_=TorqueReadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def toggle_torque(
        self,
        *,
        torque_status: bool,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> StatusResponse:
        """
        Enable or disable the torque of the robot.

        Parameters
        ----------
        torque_status : bool

        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        StatusResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.toggle_torque(
                torque_status=True,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "torque/toggle",
            method="POST",
            params={
                "torque_status": torque_status,
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    StatusResponse,
                    parse_obj_as(
                        type_=StatusResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def read_voltage(
        self,
        *,
        robot_id: typing.Optional[int] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> VoltageReadResponse:
        """
        Read the current voltage of the robot's motors.

        Parameters
        ----------
        robot_id : typing.Optional[int]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        VoltageReadResponse
            Successful Response

        Examples
        --------
        import asyncio

        from phospho import AsyncPhosphobotApi

        client = AsyncPhosphobotApi(
            base_url="https://yourhost.com/path/to/api",
        )


        async def main() -> None:
            await client.control.read_voltage()


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "voltage/read",
            method="POST",
            params={
                "robot_id": robot_id,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    VoltageReadResponse,
                    parse_obj_as(
                        type_=VoltageReadResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    typing.cast(
                        HttpValidationError,
                        parse_obj_as(
                            type_=HttpValidationError,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
