# Autopilot API

The Autopilot API defines the `autopilots` path under `self` (e.g. `/signalk/v2/api/vessels/self/autopilots`) for representing information from one or more autopilot devices.

The Autopilot API provides a mechanism for applications to issue requests to autopilot devices to perform common operations. Additionally, when multiple autopilot devices are present, each autopilot device is individually addressable.

Note: Autopilot provider plugins are required to enable the API operation and provide communication with autopilot devices. See Autopilot Provider Plugins for details.

## Common Operations

The following operations are supported:

- Setting the operating mode
- Engaging / Disengaging the pilot
- Setting / adjusting the course
- Dodging port / starboard
- Tacking / Gybing

## The Default Autopilot

To ensure a consistent API calling profile and to simplify client operations, the Autopilot API will assign a default autopilot device which is accessible using the path `/signalk/v2/api/vessels/self/autopilots/_default`.

- When only one autopilot is present, it will be automatically assigned as the default.

- When multiple autopilots are present, and a default is yet to be assigned, one will be assigned when:

  - An update is received from a provider plugin, the autopilot which is the source of the update will be assigned as the default.
  - An API request is received, the first autopilot device registered, is assigned as the default.
  - A request is sent to the `/_providers/_default` API endpoint (see Setting the Default Autopilot).

### Getting the Default Autopilot Identifier

To get the id of the default autopilot, submit an HTTP `GET` request to `/signalk/v2/api/vessels/self/autopilots/_providers/_default`.

Example:

    HTTP GET "/signalk/v2/api/vessels/self/autopilots/_providers/_default"

Response:

    {
      "id":"raymarine-id"
    }

### Setting an Autopilot as the Default

To set / change the default autopilot, submit an HTTP `POST` request to `/signalk/v2/api/vessels/self/autopilots/_providers/_default/{id}` where `{id}` is the identifier of the autopilot to use as the default.

Example:

    HTTP POST "/signalk/v2/api/vessels/self/autopilots/_providers/_default/raymarine-id"

The autopilot with the supplied id will now be the target of requests made to `/signalk/v2/api/vessels/self/autopilots/_default/*`.

## Listing the available Autopilots

To retrieve a list of installed autopilot devices, submit an HTTP `GET` request to `/signalk/v2/api/vessels/self/autopilots`.

The response will be an object containing all the registered autopilot devices, keyed by their identifier, detailing the `provider` it is registered by and whether it is assigned as the default.

    HTTP GET "/signalk/v2/api/vessels/self/autopilots"

Example: List of registered autopilots showing that `pypilot-id` is assigned as the default.

    {
      "pypilot-id": {
        "provider":"pypilot-provider",
        "isDefault": true
      },
      "raymarine-id": {
        "provider":"raymarine-provider",
        "isDefault": false
      }
    }

## Autopilot Deltas

Deltas emitted by the Autopilot API will have the base path `steering.autopilot` with the `$source` containing the autopilot device identifier.

Example: Deltas for `autopilot.engaged` from two autopilots (`raymarine-id`).

    {
      "context":"vessels.self",
      "updates":[
        {
          "$source":"pypilot-id",
          "timestamp":"2023-11-19T06:12:47.820Z",
          "values":[
            {"path":"steering.autopilot.engaged","value":false}
          ]
        },
        {
          "$source":"raymarine-id",
          "timestamp":"2023-11-19T06:12:47.820Z",
          "values":[
            {"path":"steering.autopilot.engaged","value":true}
          ]
        }
      ]
    }

## Autopilot Notifications

The Autopilot API will provide notifications under the path `notifications.steering.autopilot` with the `$source` containing the autopilot device identifier.

A set of normalised notification paths are defined to provide a consistant way for client apps to receive and process alarm messages.

- `waypointAdvance`
- `waypointArrival`
- `routeComplete`
- `xte`
- `heading`
- `wind`

Example:

    {
      "context":"vessels.self",
      "updates":[
        {
          "$source":"pypilot-id",
          "timestamp":"2023-11-19T06:12:47.820Z",
          "values":[
            {
              "path": "notifications.steering.autopilot.waypointAdvance",
              "value": {
                "state": "alert",
                "method": ["sound"],
                "message": "Waypoint Advance"
              }
            }
          ]
        }
      ]
    }

## Autopilot offline / unreachable

If an autopilot device is not connected or unreachable, the provider for that autopilot device will set the `state` of the device to `off-line`.

## Autopilot Operations

All API operations are invoked by issuing requests to:

1. `/signalk/v2/api/vessels/self/autopilots/_default/*`

Targets the default autopilot device.

OR

2. `/signalk/v2/api/vessels/self/autopilots/{id}/*`

Target the autopilot with the supplied `{id}`

Example:

    HTTP GET "/signalk/v2/api/vessels/self/autopilots/_default/state"

    HTTP GET "/signalk/v2/api/vessels/self/autopilots/pypilot-id/mode"

### Retrieving Autopilot Status

To retrieve the current autopilot configuration as well as a list of available options for `state` and `mode` selections, submit an HTTP `GET` request to `/signalk/v2/api/vessels/self/autopilots/{id}`.

    HTTP GET "/signalk/v2/api/vessels/self/autopilots/{id}"

Response:

    {
      "options":{
        "state":["enabled","disabled"],
        "mode":["gps","compass","wind"]
      },
      "state":"disabled",
      "mode":"gps",
      "target": 0,
      "engaged": false
    }

Where:

- `options` contains arrays of valid `state` and `mode` selection options
- `state` represents the current state of the device
- `mode` represents the current mode of the device
- `target` represents the current target value with respect to the selected `mode`
- `engaged` will be true when the autopilot is actively steering the vessel.

### Setting the Autopilot State

Autopilot state can be set by submitting an HTTP `PUT` request to the `/signalk/v2/api/vessels/self/autopilots/{id}/state` endpoint containing a value from the list of available states.

    HTTP PUT "/signalk/v2/api/vessels/self/autopilots/{id}/state" {"value": "disabled"}

### Getting the Autopilot State

The current autopilot state can be retrieved by submitting an HTTP `GET` request to the `/signalk/v2/api/vessels/self/autopilots/{id}/state` endpoint.

    HTTP GET "/signalk/v2/api/vessels/self/autopilots/{id}/state"

Response:

    {
      "value":"enabled",
    }

### Setting the Autopilot Mode

Autopilot mode can be set by submitting an HTTP `PUT` request to the `/signalk/v2/api/vessels/self/autopilots/{id}/mode` endpoint containing a value from the list of available modes.

    HTTP PUT "/signalk/v2/api/vessels/self/autopilots/{id}/mode" {"value": "gps"}

### Getting the Autopilot Mode

The current autopilot mode can be retrieved by submitting an HTTP `GET` request to the `mode` endpoint.

    HTTP GET "/signalk/v2/api/vessels/self/autopilots/{id}/mode"

Response:

    {
      "value":"gps",
    }

### Setting the Target value

Autopilot target value can be set by submitting an HTTP `PUT` request to the `/signalk/v2/api/vessels/self/autopilots/{id}/target` endpoint containing the desired value.

Note: The value supplied should be a number within the valid range for the selected `mode`.

    // Set target to 129 degrees
    HTTP PUT "signalk/v2/api/vessels/self/autopilots/{id}/target" {"value": 129, "units": "deg"}

    // Set target to 0.349066 radians (20 degrees)
    HTTP PUT "signalk/v2/api/vessels/self/autopilots/{id}/target" {"value": 0.349066}

The target value can be adjusted a +/- value by submitting an HTTP `PUT` request to the `/signalk/v2/api/vessels/self/autopilots/{id}/target/adjust` endpoint with the value to add to the current `target` value.

    // Adjust target 2 degrees port
    HTTP PUT "signalk/v2/api/vessels/self/autopilots/{id}/target/adjust" {"value": -2, , "units": "deg"}

    // Adjust target 0.0349066 radians (2 degrees) starboard
    HTTP PUT "signalk/v2/api/vessels/self/autopilots/{id}/target/adjust" {"value": 0.0349066}

### Getting the current Target value

The current autopilot target value (in radians) can be retrieved by submitting an HTTP `GET` request to the `target` endpoint.

    HTTP GET "/signalk/v2/api/vessels/self/autopilots/{id}/target"

Response:

    {
      "value": 2.2345,
    }

### Engaging / Disengaging the Autopilot

#### Engaging the autopilot

An autopilot can be engaged by setting it to a speciifc `state` but it can also be engaged more generically by submitting an HTTP `POST` request to the `/signalk/v2/api/vessels/self/autopilots/{id}/engage` endpoint.

    HTTP POST "/signalk/v2/api/vessels/self/autopilots/{id}/engage"

Note: The resultant `state` into which the autopilot is placed will be determined by the provider plugin and the autopilot device it is communicating with.

#### Disengaging the autopilot

An autopilot can be disengaged by setting it to a speciifc `state` but it can also be disengaged more generically by submitting an HTTP `POST` request to the `/signalk/v2/api/vessels/self/autopilots/{id}/disengage` endpoint.

    HTTP POST "/signalk/v2/api/vessels/self/autopilots/{id}/disengage"

Note: The resultant `state` into which the autopilot is placed will be determined by the provider plugin and the autopilot device it is communicating with.

### Perform a Tack

To send a command to the autopilot to perform a tack in the required direction, submit an HTTP `POST` request to `./autopilots/{id}/tack/{direction}` where direction is either `port` or `starboard`.

Example: Tack to Port

    HTTP POST "/signalk/v2/api/vessels/self/autopilots/{id}/tack/port"

Example: Tack to Starboard

    HTTP POST "/signalk/v2/api/vessels/self/autopilots/{id}/tack/starboard"

### Perform a Gybe

To send a command to the autopilot to perform a gybe in the required direction, submit an HTTP `POST` request to `/signalk/v2/api/vessels/self/autopilots/{id}/gybe/{direction}` where direction is either `port` or `starboard`.

Example: Gybe to Port

    HTTP POST "/signalk/v2/api/vessels/self/autopilots/{id}/gybe/port"

Example: Gybe to Starboard

    HTTP POST "/signalk/v2/api/vessels/self/autopilots/{id}/gybe/starboard"

### Dodging Obstacles

To address the various methods that the `dodge` function could be invoked on pilot devices, the API provides the following endpoints to provide the widest coverage possible:

To enter dodge mode at the current course

    POST / signalk / v2 / api / vessels / self / autopilots / { id } / dodge

To enter dodge mode and change course by 5 degrees starboard

    PUT /signalk/v2/api/vessels/self/autopilots/{id}/dodge {"value": 5, "units": "deg"}

To enter dodge mode and change course by 5 degrees port

    PUT /signalk/v2/api/vessels/self/autopilots/{id}/dodge {"value": -5, "units": "deg"}

To cancel dodge mode

    DELETE / signalk / v2 / api / vessels / self / autopilots / { id } / dodge