Edge SDK (Python) — Models Reference

All public dataclasses are exported from the top-level edge_sdk package. They are plain @dataclass objects (not Pydantic), so construction is cheap and they serialize to/from protobuf via internal _converters.py modules you should not need to touch.

For Java, see edge-sdk-models.md.


Common request / response

RequestContext

@dataclass
class RequestContext:
    tid: str        # transaction id
    sn: str         # asset serial number the command is addressed to
    timestamp: datetime

EdgeResponse

@dataclass
class EdgeResponse:
    tid: str
    sn: str
    success: bool
    asset_id: str | None = None
    message: str | None = None
    error: ErrorMessage | None = None
    progress: CommandProgress | None = None
    stream_url: str | None = None   # populated only for StartLiveStream responses
    video_id: str | None = None
    external_execution_id: str | None = None  # set when this command keeps running asynchronously

Constructors — note these are named ok/fail, not success/error:

FactoryResult
EdgeResponse.ok(tid, sn, message=None, *, external_execution_id=None, ...)success=True
EdgeResponse.fail(tid, sn, error: ErrorMessage, asset_id=None)success=False, fills error
EdgeResponse.not_supported(tid, sn)success=False, error code SDK_ERROR
return EdgeResponse.ok(ctx.tid, ctx.sn, "Takeoff initiated")

return EdgeResponse.fail(ctx.tid, ctx.sn, ErrorMessage(message="Device busy", code=ErrorCode.HARDWARE_ERROR))

Set external_execution_id on ok(...) when the command you just accepted keeps running asynchronously — use your own vendor execution id if you have one (e.g. a DJI flightId); otherwise leave it unset and the platform falls back to its own correlation id.

ErrorMessage

@dataclass
class ErrorMessage:
    message: str
    code: ErrorCode
    timestamp: datetime | None = None

CommandProgress

@dataclass
class CommandProgress:
    progress: float          # 0.0-100.0
    state: str
    left_time_seconds: float

Coordinates

@dataclass
class Coordinates:
    latitude: float
    longitude: float
    altitude: float

Asset model

Asset

@dataclass
class Asset:
    id: str | None
    sn: str
    name: str
    type: AssetType
    vendor: AssetVendor
    connection: AssetConnection
    model: str
    organization: str
    system_connection_string: str | None = None
    external_device_type: str | None = None
    external_device_sub_type: str | None = None
    external_id: str | None = None
    live_stream_push_url: str | None = None
    live_stream_pull_url: str | None = None
    created_at: datetime | None = None

SubAsset

@dataclass
class SubAsset:
    id: str | None
    sn: str
    name: str
    type: AssetType
    vendor: AssetVendor
    connection: AssetConnection
    model: str
    system_connection_string: str | None = None
    external_device_type: str | None = None
    external_device_sub_type: str | None = None
    external_id: str | None = None
    stream_url_predefined: bool | None = None
    live_stream_push_url: str | None = None
    live_stream_pull_url: str | None = None
    created_at: datetime | None = None

SubAsset has no parent_sn field — the parent/sub-asset relationship is established through the Connector Service's registration call, not carried on the dataclass itself.


Telemetry

AssetTelemetry and SubAssetTelemetry are flat — position and movement fields (latitude, longitude, absolute_altitude, relative_altitude, ...) live directly on them, not nested in a separate position object.

AssetTelemetry

@dataclass
class AssetTelemetry:
    id: str
    timestamp: datetime | None = None
    latitude: float | None = None
    longitude: float | None = None
    absolute_altitude: float | None = None
    relative_altitude: float | None = None
    environment_temp: float | None = None
    inside_temp: float | None = None
    humidity: float | None = None
    mode: AssetMode | None = None
    rainfall: Rainfall | None = None
    sub_asset_info: AssetSubAssetInfo | None = None
    sub_asset_at_home: bool | None = None
    sub_asset_charging: bool | None = None
    sub_asset_percentage: float | None = None
    heading: float | None = None
    debug_mode_open: bool | None = None
    has_active_manual_control_session: bool | None = None
    cover_state: AssetCoverState | None = None
    working_voltage: int | None = None
    working_current: int | None = None
    supply_voltage: int | None = None
    wind_speed: float | None = None
    position_valid: bool | None = None
    network_info: AssetNetworkInfo | None = None
    air_conditioner: AssetAirConditioner | None = None
    manual_control_state: ManualControlState | None = None
    position_state: AssetPositionState | None = None

SubAssetTelemetry

@dataclass
class SubAssetTelemetry:
    id: str
    timestamp: datetime | None = None
    latitude: float | None = None
    longitude: float | None = None
    absolute_altitude: float | None = None
    relative_altitude: float | None = None
    horizontal_speed: float | None = None
    vertical_speed: float | None = None
    wind_speed: float | None = None
    wind_direction: str | None = None
    heading: float | None = None
    gear: int | None = None
    payload: PayloadTelemetry | None = None
    battery: SubAssetBatteryInfo | None = None
    height_limit: int | None = None
    home_distance: float | None = None
    total_movement_distance: float | None = None
    total_movement_time: float | None = None
    mode: SubAssetMode | None = None
    country: str | None = None

PayloadTelemetry

@dataclass
class PayloadTelemetry:
    id: str
    name: str
    timestamp: datetime | None = None
    camera: CameraData | None = None
    range_finder: RangeFinderData | None = None
    sensor: SensorData | None = None

Helper data classes

  • AssetPositionState(gps_number=None, rtk_number=None, quality=None) — GNSS fix quality, not a coordinate
  • SubAssetBatteryInfo(percentage=None, remaining_time=None, return_to_home_power=None)
  • AssetNetworkInfo(type: NetworkType, rate=None, quality: NetworkStateQuality)
  • AssetAirConditioner(state: AssetAirConditionerState, switch_time=None)
  • AssetSubAssetInfo(sn=None, model=None, paired=None, online=None)
  • CameraData(current_lens=None, gimbal_pitch=None, gimbal_yaw=None, zoom_factor=None, gimbal_roll=None)
  • RangeFinderData(target_latitude=None, target_longitude=None, target_distance=None, target_altitude=None)
  • SensorData(target_temperature=None)

Tasks and missions

Most edge adapters never construct these directly — the platform drives task execution by passing your adapter a task_id: str, and you fetch whatever detail you need through ConnectorClient (see Mission Autonomy). These dataclasses exist if you need the richer, vendor-specific task shape (e.g. mirroring a DJI wayline mission).

Task

@dataclass
class Task:
    status: TaskStatus
    id: str | None = None
    mission_id: str | None = None
    name: str | None = None
    task_type: TaskType | None = None
    asset_id: str | None = None
    sn_number: str | None = None
    current_progress: int | None = None
    current_step: str | None = None
    waypoint_config: WaypointTaskConfig | None = None
    detect_config: DetectTaskConfig | None = None
    area_mapping_config: AreaMappingTaskConfig | None = None
    poi_config: PoiTaskConfig | None = None
    follow_config: FollowTaskConfig | None = None
    track_config: TrackTaskConfig | None = None
    created_at: datetime | None = None
    modified_at: datetime | None = None
    # additional fields: description, config, break_reason, external_command_type, modified_from

At most one *_config is populated based on task_type.

Mission

@dataclass
class Mission:
    name: str
    description: str
    status: MissionStatus
    type: MissionType
    id: str | None = None
    tasks: list[Task] = field(default_factory=list)
    assigned_assets: list[str] = field(default_factory=list)
    start_date: datetime | None = None
    end_date: datetime | None = None

Task config variants (representative fields — each has 10-25 fields; see the SDK source for the full list)

ClassRepresentative fields
WaypointTaskConfigflight_id, waypoints: list[Waypoint], global_speed, rth_altitude, rth_mode
DetectTaskConfigai_model_id, detection_targets, min_confidence, detection_parameters: list[DetectionParameter]
AreaMappingTaskConfigsurvey_altitude, area_vertices: list[AreaVertex], front_overlap, side_overlap, flight_pattern
PoiTaskConfigpoi_latitude, poi_longitude, poi_altitude, orbit_radius, orbit_speed, number_of_orbits
FollowTaskConfigtarget_type, follow_distance, follow_mode, max_speed, lost_target_action
TrackTaskConfigtarget_type, tracking_mode, confidence_threshold, max_movement_radius, lost_target_action

Waypoint and AreaVertex

@dataclass
class Waypoint:
    latitude: float
    longitude: float
    altitude: float | None = None
    speed: float | None = None
    fly_through: bool | None = None
    vehicle_action: VehicleAction | None = None
    wp_order: int | None = None
    gimbal_pitch: int | None = None

@dataclass
class AreaVertex:
    latitude: float
    longitude: float
    order: int | None = None

Detection

@dataclass
class BoundingBox:
    x: float
    y: float
    width: float
    height: float

@dataclass
class DetectionResult:
    object_id: str
    object_type: str
    confidence: float
    bounding_box: BoundingBox

@dataclass
class DetectionResponse:
    detections: list[DetectionResult] = field(default_factory=list)

@dataclass
class DetectionBatch:
    """Batch of detection results published via DetectionPublisher/LiveDataService.produce_detection."""
    sn: str = ""
    detections: list[DetectionResult] = field(default_factory=list)
    stream_url: str | None = None

Notifications

@dataclass
class AssetStatusEvent:
    sn: str
    online: bool
    asset_id: str | None = None
    message: str | None = None

@dataclass
class MissionEvent:
    mission_id: str
    mission_type: MissionType
    status: MissionStatus
    sn: str = ""
    message: str | None = None

@dataclass
class TaskEvent:
    """Task lifecycle event."""
    task_id: str
    task_type: TaskType
    status: TaskStatus
    sn: str = ""  # asset serial number - required for multi-asset adapters
    progress: float | None = None
    message: str | None = None
    external_task_type: str | None = None

See Live Data — Notifications.


Capabilities

@dataclass
class Capability:
    command: str       # e.g. "TakeOff", "GoTo"
    description: str
    available: bool
    unavailable_reason: str | None = None
    metadata: dict[str, str] = field(default_factory=dict)

@dataclass
class Capabilities:
    asset_sn: str
    asset_type: AssetType
    capabilities: list[Capability] = field(default_factory=list)
    timestamp: datetime | None = None

Use EdgeAdapter._auto_capabilities(sn, asset_type) to construct one based on which methods you've overridden.


Enums

IntEnum types from edge_sdk.models.common:

EnumValues
AssetTypeUNKNOWN, AIRCRAFT, DOCK, SENSOR, CAMERA, OTHER, JAMMER, CYBER_ATTACK, SAPIENT
AssetVendorDJI, AUTEL, ROS, MAVLINK, RTMP_RTSP, SAPIENT, BETAFLIGHT
AssetConnectionMQTT, TCP, SERIAL
LiveStreamTypeUNKNOWN, RTMP, RTSP, WEBRTC
AssetModeIDLE, DEBUGGING, REMOTE_DEBUGGING, UPGRADING, WORKING, TO_BE_CALIBRATED, OFFLINE
SubAssetModeIDLE, TAKEOFF_PREPARE, TAKEOFF_FINISHED, MANUAL, TAKEOFF_AUTO, WAYLINE, PANORAMIC_SHOT, ACTIVE_TRACK, ADS_B_AVOIDANCE, RETURN_AUTO, LANDING_AUTO, LANDING_FORCE, and more (mirrors DJI's flight-mode set)
ManualControlStateDISCONNECTED, CONNECTING, CONNECTED
AssetCoverStateCLOSED, OPENED, HALF_OPEN, ABNORMAL
AssetAirConditionerStateIDLE, COOL, HEAT, DEHUMIDIFICATION, plus *_EXIT/*_PREPARATION transition states
TaskTypeUNSPECIFIED, DETECT, AREA_MAPPING, WAYPOINT, POI, FOLLOW, TRACK, COUNTER_DRONE
TaskStatusUNKNOWN, DRAFT, SCHEDULED, RUNNING, ERROR, COMPLETED, PREPARED, PAUSED
MissionTypeSTANDARD, REMOTE_OPS, DRF, MISSION
MissionStatusUNKNOWN, DRAFT, ACTIVE, INACTIVE, ERROR
TaskStatusUNKNOWN, DRAFT, SCHEDULED, RUNNING, ERROR, COMPLETED, PREPARED, PAUSED
ErrorCodeSYSTEM_ERROR, CLIENT_ERROR, SDK_ERROR, SERVICE_ERROR, ASSET_ERROR
RainfallNO, LIGHT, MODERATE, HEAVY
NetworkTypeNETWORK_4G, ETHERNET
NetworkStateQualityNO_SIGNAL, BAD, POOR, FAIR, GOOD, EXCELLENT

Pass them as actual enum members, not raw ints — the proto converters accept both, but explicit enums make your code self-documenting.

Was this page helpful?

© Copyright 2026 Zequent. All rights reserved.