asyncapi: 2.2.0
info:
  title: GCS RealTime API
  version: 1.3.1
defaultContentType: application/json
servers:
  production:
    url: ssl://portal.demo.unifly.tech:8883
    protocol: mqtt
    security:
      - 'apiKeyUser': [ ]
      - 'apiKeyPassword': [ ]
channels:
  telemetry/{companyUid}/{uasSerialNumber}/location:
    description: "Location of the UAS"
    bindings:
      mqtt:
        retain: false
        qos: 1
    parameters:
      companyUid:
        $ref: '#/components/parameters/companyUid'
      uasSerialNumber:
        schema:
          description: The serial number of the UAS
          type: string
    publish:
      operationId: sendTelemetryLocation
      message:
        $ref: '#/components/messages/telemetryLocationMessage'
  telemetry/{companyUid}/{uasSerialNumber}/heading:
    description: "Heading of the UAS"
    bindings:
      mqtt:
        retain: false
        qos: 1
    parameters:
      companyUid:
        $ref: '#/components/parameters/companyUid'
      uasSerialNumber:
        schema:
          description: The serial number of the UAS
          type: string
    publish:
      operationId: sendTelemetryHeading
      message:
        $ref: '#/components/messages/telemetryHeadingMessage'
  telemetry/{companyUid}/{uasSerialNumber}/velocity:
    description: "Velocity of the UAS"
    bindings:
      mqtt:
        retain: false
        qos: 1
    parameters:
      companyUid:
        $ref: '#/components/parameters/companyUid'
      uasSerialNumber:
        schema:
          description: The serial number of the UAS
          type: string
    publish:
      operationId: sendTelemetryVelocity
      message:
        $ref: '#/components/messages/telemetryVelocityMessage'
  telemetry/{companyUid}/{uasSerialNumber}/emergencyStatus:
    description: "Emergency status of the UAS"
    bindings:
      mqtt:
        retain: true
        qos: 1
    parameters:
      companyUid:
        $ref: '#/components/parameters/companyUid'
      uasSerialNumber:
        schema:
          description: The serial number of the UAS
          type: string
    publish:
      operationId: sendTelemetryEmergencyStatus
      message:
        $ref: '#/components/messages/telemetryEmergencyStatusMessage'

  tracking/nearby/{companyUid}/{uasSerialNumber}/{trackId}:
    description: "Tracking information relevant to the specified UAS, grouped by track id. Use the multi-level wildcard # (`/tracking/nearby/#`) to subscribe to all tracking information (restricted by security)."
    bindings:
      mqtt:
        retain: true
        qos: 1
    parameters:
      companyUid:
        $ref: '#/components/parameters/companyUid'
      uasSerialNumber:
        $ref: '#/components/parameters/uasSerialNumber'
      trackId:
        schema:
          description: The id of the track
          type: string
    subscribe:
      operationId: receiveNearbyTracking
      message:
        $ref: '#/components/messages/nearbyTrackingMessage'
  alerts/nearby/{companyUid}/{uasSerialNumber}/{alertId}:
    description: "Alert information relevant to the specified UAS, grouped by alert id. Use the multi-level wildcard # (`/alerts/nearby/#`) to subscribe to all alerts (restricted by security)."
    bindings:
      mqtt:
        retain: true
        qos: 1
    parameters:
      companyUid:
        $ref: '#/components/parameters/companyUid'
      uasSerialNumber:
        $ref: '#/components/parameters/uasSerialNumber'
      alertId:
        schema:
          description: The id of the alert
          type: string
    subscribe:
      operationId: receiveNearbyAlerts
      message:
        $ref: '#/components/messages/nearbyAlertMessage'
  operations/{operationId}:
    description: "Operation information, grouped by operation id. Use the single-level wildcard + (`/operations/+`) to subscribe to all operations (restricted by security)."
    bindings:
      mqtt:
        retain: true
        qos: 1
    parameters:
      operationId:
        schema:
          description: The id of the operation
          type: string
    subscribe:
      operationId: receiveOperations
      message:
        $ref: '#/components/messages/operationMessage'
  operations/{operationId}/instructions/{instructionId}:
    description: "Instruction information, grouped by instruction id and operation id. Use the single-level wildcard + (`/operations/{operationId}/instructions/+`) to subscribe to all instructions for an operation, or (`/operations/+/instructions/+`) to all instructions for all operations"
    bindings:
      mqtt:
        retain: true
        qos: 1
    parameters:
      operationId:
        schema:
          description: The id of the operation
          type: string
      instructionId:
        schema:
          description: The id of the instruction
          type: string
    subscribe:
      operationId: receiveOperationInstructions
      message:
        $ref: '#/components/messages/instructionMessage'
  operations/{operationId}/instructions/{instructionId}/transition/{transitionCode}:
    description: "Trigger a state transition on the instruction."
    bindings:
      mqtt:
        retain: false
        qos: 2
    parameters:
      operationId:
        schema:
          description: The id of the operation
          type: string
      instructionId:
        schema:
          description: The id of the instruction
          type: string
      transitionCode:
        schema:
          description: The code of the transition as given in the transition object
          type: string
    publish:
      operationId: sendOperationInstructionStateTransition
      message:
        $ref: '#/components/messages/instructionTransitionMessage'
  geofences/{geofenceId}:
    bindings:
      mqtt:
        retain: false
        qos: 1
    parameters:
      geofenceId:
        schema:
          description: The id of the geofence
          type: string
    subscribe:
      description: "Events related to changes, creation or removal of geofences"
      operationId: receiveGeofenceEvent
      message:
        $ref: '#/components/messages/geofenceEventMessage'
components:
  messages:
    telemetryLocationMessage:
      title: Telemetry Location
      description: Submit a change in location of a UAS.
      payload:
        $ref: '#/components/schemas/location'
    telemetryHeadingMessage:
      title: Telemetry Heading
      description: Submit a change in the heading of a UAS.
      payload:
        $ref: '#/components/schemas/heading'
    telemetryVelocityMessage:
      title: Telemetry Velocity
      description: Submit a change in the velocity of a UAS.
      payload:
        $ref: '#/components/schemas/velocity'
    telemetryEmergencyStatusMessage:
      title: Telemetry
      description: Submit a change in the emergency status of a UAS.
      payload:
        $ref: '#/components/schemas/emergency'
    nearbyTrackingMessage:
      title: Nearby Tracking
      description: Anonymized information about tracks that are of importance to the user (due to proximity).
      payload:
        $ref: '#/components/schemas/nearbyTracking'
    nearbyAlertMessage:
      title: Nearby Alert
      description: Anonymized information about alerts that are of importance to the user (due to proximity or involvement)
      payload:
        $ref: '#/components/schemas/nearbyAlert'
    operationMessage:
      title: Operation
      description: Indicates a change in properties of an operation. Access to operations is limited by security.
      payload:
        $ref: '#/components/schemas/operation'
    instructionMessage:
      title: Instruction
      description: Indicates a change or arrival of an instruction to the operator.
      payload:
        $ref: '#/components/schemas/instruction'
    instructionTransitionMessage:
      title: Instruction state transition
      description: Triggers a state transition on the instruction
      payload:
        $ref: '#/components/schemas/instructionTransition'
    geofenceEventMessage:
      title: Geofence event
      description: Describes an update, creation or removal of a geofence. The messages includes a bounding box; use this to determine whether the event is relevant (e.g. inside your viewport) and use the REST call to refresh the information if necessary.
      payload:
        $ref: '#/components/schemas/geofenceEvent'

  parameters:
    companyUid:
      schema:
        description: The company unique identifier of the UAS
        type: string
    uasSerialNumber:
      schema:
        description: The serial number of the UAS
        type: string

  schemas:
    timestamp:
      type: string
      format: date-time
      example: '2022-02-17T15:41:12.00Z'
    coordinates:
      description: The WGS84 coordinates of the UAS
      type: object
      required: [lon, lat]
      properties:
        lon:
          description: Longitude of the location
          type: number
          example: 4.4520369
          minimum: -180
          maximum: 180
        lat:
          description: Latitude of the location
          type: number
          example: 51.293816
          minimum: -90
          maximum: 90
    operation:
      description: The properties of an operation
      type: object
      required: [status]
      properties:
        status:
          type: string
          description: The status of the operation
          enum: [DRAFT,PENDING_ACCEPTANCE,ACCEPTED,PENDING_ACTIVATION,ACTIVATED,ENDED,WITHDRAWN]
        validationResult:
          $ref: '#/components/schemas/validationStatus'

    validationStatus:
      type: object
      properties:
        status:
          description: The validation status
          enum: [OK, FATAL, WARNING, INFORMATIONAL, ERROR, DISCLAIMER, ACTION_REQUIRED, AUTHORIZATION_REQUIRED, AUTHORIZATION_REJECTED, AUTHORIZATION_PENDING]
    altitude:
      $ref: './schemas/altitude.yml'
    bbox:
      $ref: './schemas/bbox.yml'
    location:
      description: Describes where the UAS is flying.
      type: object
      required: [timestamp, coordinates, altitude]
      properties:
        timestamp:
          $ref: '#/components/schemas/timestamp'
        coordinates:
          $ref: '#/components/schemas/coordinates'
        altitude:
          $ref: '#/components/schemas/altitude'
    groundSpeed:
      description: The speed at which the UAS is moving relative to the ground, in meters per second.
      type: number
      example: 0.5
    velocity:
      description: The speed at which the UAS is moving
      type: object
      required: [timestamp, groundSpeed]
      properties:
        timestamp:
          $ref: '#/components/schemas/timestamp'
        groundSpeed:
          $ref: '#/components/schemas/groundSpeed'
    trueHeading:
      description: The true heading of the UAS, relative to geographical north
      type: number
      minimum: 0
      exclusiveMaximum: 360
    magneticHeading:
      description: The magnetic heading of the UAS, relative to magnetic north
      type: number
      minimum: 0
      exclusiveMaximum: 360
    heading:
      description: The heading in which the UAS is moving
      type: object
      required: [timestamp]
      properties:
        timestamp:
          $ref: '#/components/schemas/timestamp'
        "true":
          $ref: '#/components/schemas/trueHeading'
        magnetic:
          $ref: '#/components/schemas/magneticHeading'
    emergency:
      type: object
      required: [timestamp, emergencyStatus]
      properties:
        timestamp:
          $ref: '#/components/schemas/timestamp'
        emergencyStatus:
          description: A list of emergency situations occurring with the drone.
          type: array
          items:
            $ref: '#/components/schemas/emergencyStatus'

    emergencyStatus:
      type: string
      description: Emergency state occurring with the drone
      enum:
        - LOSS_OF_LINK
        - LOSS_OF_SIGNAL
        - LOSS_OF_GPS
        - LOSS_OF_ENGINE
        - LOSS_OF_POWER
        - LOSS_OF_OWNERSHIP
    nearbyTracking:
      type: object
      properties:
        timestamp:
          $ref: '#/components/schemas/timestamp'
        vehicle:
          $ref: '#/components/schemas/vehicle'
        coordinates:
          $ref: '#/components/schemas/coordinates'
        altitude:
          $ref: '#/components/schemas/altitude'
        emergency:
          $ref: '#/components/schemas/emergency'
        velocity:
          $ref: '#/components/schemas/groundSpeed'
        heading:
          description: The heading in which the UAS is moving
          type: object
          properties:
            "true":
              $ref: '#/components/schemas/trueHeading'
            magnetic:
              $ref: '#/components/schemas/magneticHeading'
    vehicle:
      type: object
      properties:
        type:
          type: string
          description: Indicates the type of vehicle
          enum: [UAS, AIRPLANE, HELICOPTER, VESSEL]
    nearbyAlert:
      type: object
      required:
        - type
        - subjects
        - timestamp
        - severity
      properties:
        type:
          type: string
          enum:
            - LOW_ALTITUDE
            - HIGH_ALTITUDE
            - INTRUSION
            - UAS_COLLISION
            - NO_OPERATION
            - AIRCRAFT_COLLISION
            - OUTSIDE_OPERATION
            - BUILDING_COLLISION
            - LOW_BATTERY
            - OBSTRUCTED_LOS
            - UNAUTHORIZED_FLIGHT
            - OUTSIDE_PLANNED_OPERATION_TIME
            - EMERGENCY_LOSS_OF_LINK
            - EMERGENCY_LOSS_OF_SIGNAL
            - EMERGENCY_LOSS_OF_GPS
            - EMERGENCY_LOSS_OF_ENGINE
            - EMERGENCY_LOSS_OF_POWER
            - EMERGENCY_LOSS_OF_OWNERSHIP
            - EMERGENCY_GENERAL_EMERGENCY
            - EMERGENCY_LIFEGUARD_OR_MEDICAL_EMERGENCY
            - EMERGENCY_MINIMUM_FUEL
            - EMERGENCY_NO_COMMUNICATIONS
            - EMERGENCY_UNLAWFUL_INTERFERENCE
            - EMERGENCY_DOWNED_AIRCRAFT
            - EMERGENCY_RESERVED
        subjects:
          type: array
          maxItems: 2
          minItems: 1
          items:
            $ref: '#/components/schemas/alertSubject'
        timestamp:
          $ref: '#/components/schemas/timestamp'
        severity:
          type: string
          enum: [WARNING, CRITICAL, NONE]
        message:
          type: string
        distance:
          type: number
          description: Distance between the subjects (if applicable), in meter
    alertSubject:
      type: object
      properties:
        identifier:
          description: Identifier of the subject in case of geozone or airport
          type: string
        name:
          type: string
        type:
          $ref: '#/components/schemas/subjectType'
        coordinates:
          $ref: '#/components/schemas/coordinates'
        altitude:
          $ref: '#/components/schemas/altitude'
        trackId:
          type: string
          description: If applicable, id of the track related to this subject

    subjectType:
      type: string
      enum:
        - UAS
        - GEOZONE
        - AIRCRAFT
        - UASOPERATION
        - AIRPORT
        - HELICOPTER
        - VESSEL

    instruction:
      type: object
      properties:
        state:
          description: State of the instruction
          type: string
        type:
          description: Description of the type of instruction
          type: string
        transitions:
          description: The possible state transitions; this describes the possible actions the operator can take on this instruction.
          type: array
          items:
            $ref: '#/components/schemas/transitionDescription'
        form:
          $ref: '#/components/schemas/formDefinition'

    transitionDescription:
      type: object
      properties:
        code:
          description: Technical identifier of the state transition, to be used to send the appropriate message.
          type: string
        description:
          description: Human readable meaning the strate transition (e.g. Confirm landing, ...)
          type: string

    instructionTransition:
      type: object
      properties:
        formdata:
          $ref: '#/components/schemas/formData'

    formData:
      type: object
      description: The data that is entered by the user in the form according to the form definition in the instruction. Key/value map, where the key is the id of the form field.
      additionalProperties:
        type: string

    formDefinition:
      type: object
      description: Describes a form that can be shown to a user.
      properties:
        fields:
          type: array
          items:
            $ref: '#/components/schemas/formField'

    formField:
      type: object
      properties:
        id:
          type: string
          description: The id of the form field, to be used as the property name in the data object
        type:
          type: string
          enum: [ boolean, date, string, number, enum ]
        label:
          type: string
          description: Human readable description of what needs to be filled in by the user
        defaultValue:
          description: Default value that can be presented to the user
        constraints:
          type: array
          description: Describes the constraints that apply to the value
          items:
            $ref: '#/components/schemas/formFieldConstraint'

    formFieldConstraint:
      type: object
      properties:
        name:
          type: string
          description: The type of constraint
          enum: [ max, min, maxLength, minLength, required ]
        value:
          description: If relevant, the value for the constraint (e.g. the maximum length, or the minimum value, ...)
    geofenceEvent:
      type: object
      properties:
        event:
          type: string
          enum: [ UPDATE,CREATE,DELETE,ACTIVATE,DEACTIVATE,ACTIVATION_THRESHOLD_REACHED ]
          description: Indicates whether this event indicates a new, updated or deleted geofence
        bbox:
          $ref: '#/components/schemas/bbox'

  securitySchemes:
    apiKeyPassword:
      in: password
      type: apiKey
    apiKeyUser:
      in: user
      type: apiKey
