SuperAPI AI Directory

cloudapi2-payload

Coding & development

View repository

Updated 11-12 16:17

About this skill

DJI Cloud API 2 PSDK payload domain integration assistant

What this Skill does

Helps integrator developers correctly write integration code that calls the DJI Cloud API 2 Java SDK PSDK payload module:PsdkControlModule(34 methods) and PsdkResourceModule(7 methods).

What both have in common is that they only serve third-party PSDK payloads(searchlight, speaker, Widget, etc.), which are two completely different models from camera/gimbal (CameraControlModule):

  • Different index types: the PSDK payload index is int psdkIndex; the camera payload index is String("99-0-0")
  • Different transmission channels: control commands go through DRC, resource management goes through HTTP, and status push goes through DRC Northbound / WebSocket
  • Different objects to obtain:getPsdkControlModule() is on Drone , andgetPsdkResourceModule() is on Workspace Up

Core value: The most costly pitfall in this domain is not the API signature, but thecapability boundary—a batch of methods in the Java SDK are commented out or never implemented (real-time speaking, drop device), while the enum and class javadoc still "over-declare", so generating code literally will inevitably fail to compile or be unavailable at runtime.

When to trigger

  • The user wants to write code to control the PSDK searchlight (on/off, brightness, mode, calibration, fine adjustment, wide angle, follow gimbal)
  • The user wants to write code to control the PSDK speaker (play audio / TTS, replay, stop, volume, playback mode, TTS parameters)
  • The user wants to subscribe to the PSDK device list, status summary, playback progress, floating window text, UI resources
  • The user wants to set PSDK Widget values / input boxes, or batch obtain Widget resource URLs
  • The user wants to upload speaker audio (STS credentials + direct upload to object storage) and perform resource CRUD
  • The user encounters related errors:psdkIndex not knowing where it comes from, listen returning -1, callback receiving null, cancel failing to compile

Not triggered:

  • The user wants tocall MCP Tool directly at runtime(fh_searchlight / fh_speaker / fh_psdk_widget / fh_camera)→ cloudapi2-mcp-guide
  • General SDK rules (initialization, authentication, callback order, listen/cancel pairing), flight control, waypoint missions, camera/gimbal control → cloudapi2-sdk-core
  • Map domain (flight areas, offline maps, unlock certificates, map elements) → cloudapi2-map
  • Device lifecycle, firmware upgrade, HMS alerts → cloudapi2-device-management
  • SEI/OSD telemetry, video streams → cloudapi2-sei-osd

Module location (confirm what it is attached to first)

// ✅ 控制模块在 Drone 上
PsdkControlModule control = drone.getPsdkControlModule();

// ✅ 资源模块在 Workspace 上
PsdkResourceModule resource = workspace.getPsdkResourceModule();

// ❌ 反过来取都不存在
// drone.getPsdkResourceModule()      —— 不存在
// workspace.getPsdkControlModule()   —— 不存在
Module Mounted object Method count (verified from source) Capabilities Detailed documentation
PsdkControlModule Drone 34 Searchlight / speaker / Widget / floating window / PSDK UI resources (DRC + DRC Northbound + WebSocket) references/psdk-control.md
PsdkResourceModule Workspace 7 Speaker resource CRUD / STS direct upload / Widget resources (HTTP) references/psdk-resource.md

The null-check behavior of the two differs:

  • workspace.getPsdkResourceModule() When the underlying module is missing,returns null and logs Logger.error → must null-check
  • drone.getPsdkControlModule() has no null return branch(if the underlying is null, construction fails) → null checks cannot defend against this; only ensure the business layer has performed PSDK checks

Core Rules

Rule 1: Control commands go through DRC and must first connectDrcLink

All 16 setters are delivered via DRC; the 6 DRC Northbound subscription groups also depend on the DRC link.

DrcModule drc = drone.getDrcModule();
drc.connectDrcLink(error -> {
    if (error.getErrorCode() != FlightHubSdkErrorCode.SUCCESS) {
        return;               // 建链失败,不要继续下发控制指令
    }
    // 建链成功后才能调用 PsdkControlModule 的 setter / listen
});
// 退出时
drc.disconnectDrcLink(error -> { /* 记录结果 */ });

Don't miss this step—HTTP-type interfaces (PsdkResourceModule) do not need DRC, butafter creating a resource and going to play, it returns to DRC。

Rule 2: The Java SDK has no real-time voice broadcast and no payload dropper

You think there is actually
speakerRealTimeStart / speakerRealTimeStop commented out and disabled in the source code. Real-time voice broadcast requires an RTC room + browser WebRTC + microphone capture; the Java side has no supporting capability
Payload dropper / dispenser control The class javadoc mentions "payload control such as payload droppers", butthere is no corresponding method in the class

Alternatives: for TTS use speakerTTSPlayStart, for audio files use speakerAudioPlayStart(first via PsdkResourceModule upload).

MegaphoneWorkMode The enum still contains LIVE_VOICE(3) / REAL_TIME(4) / PLAYING_IN_TRANSMISSION(5), butno Java method can enter these modes. The existence of an enum value ≠ the existence of the capability.

Rule 3:psdkIndex is an int, from the state summary callback

int listListenId = control.listenDrcPsdkDeviceList(list -> {
    if (list == null) { return; }
    for (PsdkDeviceInfo device : list.getDeviceInfos()) {
        int psdkIndex = device.getPsdkIndex();   // int
    }
});

int summaryListenId = control.listenDrcPsdkStateSummaryInfo(psdkIndex, summary -> {
    if (summary == null) { return; }             // listenId == -1 时会收到 null
    PsdkType type = summary.getPsdkType();
});
Index Type Source
PSDK payload int PsdkStateSummaryInfo.getPsdkIndex() / PsdkDeviceInfo.getPsdkIndex()
Camera payload String "type-subtype-gimbalindex", such as "99-0-0"

Do not guess psdkIndexbased on device order, and do not interchange it with the camera payload index.

Rule 4: All listen methods take a single parameter with no error; failures are detected via return values and null checks

Family Behavior on failure
DRC Northbound (6) in catchwith null callback once with the converted bean, returns -1
WebSocket (3) in catchonly logs, does not call back, returns -1
int listenId = control.listenDrcPsdkStateSearchlightInfo(psdkIndex, info -> {
    if (info == null) {
        return;   // 订阅失败路径
    }
    // 正常推送
});
if (listenId < 0) {
    // 统一处理订阅失败(尤其 WebSocket,回调不会来)
}

Rule 5: The cancel signatures fall into two categories, with different parameter orders

// 带 psdkIndex 的(6 个 DRC 状态类):psdkIndex 在前,listenId 在后
control.cancelListenDrcPsdkStateSummaryInfo(psdkIndex, listenId);
control.cancelListenDrcPsdkStateSpeakerInfo(psdkIndex, listenId);
control.cancelListenDrcPsdkStateSearchlightInfo(psdkIndex, listenId);
control.cancelListenDrcPsdkSpeakerPlayProgressInfo(psdkIndex, listenId);
control.cancelListenDrcPsdkFloatingWindowTextInfo(psdkIndex, listenId);

// 只有 listenId 的(设备列表 + 3 个 WebSocket)
control.cancelListenDrcPsdkDeviceList(listenId);
control.cancelListenPsdkSpeakerAudioPlayStartProgress(listenId);
control.cancelListenPsdkSpeakerTtsPlayStartProgress(listenId);
control.cancelListenDronePsdkUiResource(listenId);

All cancel methods return void; internal exceptions are only logged,there is no error signal. You must save each listenId yourself and cancel it in pairs with @PreDestroy .

Rule 6: The input parameter types are asymmetric; do not copy them blindly

Method Should pass Common mistake
searchlightModeSet(psdkIndex, mode, cb) int(SearchLightWorkMode.getValue()) Passing an enum object → compilation failure
speakerPlayModeSet(psdkIndex, playMode, cb) MegaphonePlayMode enum Passing an int → compilation failure
speakerTTSSet(psdkIndex, config, cb) PsdkSpeakerTTSconfig Concatenating int parameters yourself
deletePsdkSpeakerResource(resourceId, cb) int Passing a String
EditPsdkSpeakerResourceParams.setId(...) String Passing an int

Two other bean field naming pitfalls:PsdkSpeakerResourceList uses getResources(), while PsdkWidgetResourceList uses getUiResourceUrls(); PsdkUiResourceItem.getPsdkIndex() returns long, while other PSDK beans are all int。

Rule 7: Audio resources follow a four-step process, and each step has its own point of failure

getSTS()                                   → STSInfo(临时凭证,会过期)
        ↓
uploadSpeakerAudioFile(path, stsInfo)      → 仅 error;SDK 内部直传对象存储,不经过后端
        ↓
createPsdkSpeakerResource(params)          → 登记元数据,得到 int id
        ↓
connectDrcLink → speakerAudioPlayStart     → 在 PsdkControlModule 上播放

create is not an upload;upload does not require a prior create; do not cache STS credentials long-term.

Decision Tree Routing

用户问题
├─ 探照灯:开/关/亮度/模式/校准/微调/广角/随云台/灯类型
│    → references/psdk-control.md#3-探照灯控制drc7-个方法
├─ 喊话器:播放音频/TTS/重播/停止/音量/播放模式/TTS 参数
│    → references/psdk-control.md#2-喊话器控制与-widgetdrc9-个方法
├─ 实时喊话 / 边喊边播 / 对讲机模式
│    → 本文件「规则 2」(Java SDK 不支持,给替代方案)
├─ PSDK 设备发现 / 状态摘要 / 状态子集(喊话器、探照灯)
│    → references/psdk-control.md#1-psdk-设备发现与状态订阅drc-northbound6-组
├─ 播放进度 / 浮窗文本 / UI 资源订阅
│    → references/psdk-control.md#2-喊话器控制与-widgetdrc9-个方法 / #5-widget--输入框--ui-资源
├─ PSDK Widget 数值 / 输入框文本设置
│    → references/psdk-control.md#5-widget--输入框--ui-资源
├─ 音频资源上传(STS / 直传)/ 资源增删改查 / 资源列表
│    → references/psdk-resource.md
├─ Widget 资源 objectKey → 可访问 URL
│    → references/psdk-resource.md#3-widget-资源批量查询
├─ psdkIndex 从哪来 / 类型不对 / 和相机索引混用
│    → 本文件「规则 3」+ references/psdk-control.md#psdkindex-是什么
├─ listen 返回 -1 / 回调收到 null / cancel 编译不过
│    → 本文件「规则 4、5」
├─ 指令下发无反应
│    → 本文件「规则 1」(先检查 connectDrcLink)
└─ 要调 MCP 工具做运维(不写代码)
     → 转交 cloudapi2-mcp-guide

Workflow

This Skill follows the 7-chapter SOP defined by skills/_shared/sop-template.md , automatically selecting the level based on L1/L2/L3.

Ch2 Clarifying Questions

Points that must be clarified for PSDK payload requirements (missing any one may lead to incorrect implementation):

  1. Payload type: searchlight / speaker / Widget, or just querying the device list (determines which status group to subscribe to)
  2. psdkIndex whether it is known: if unknown, first write device discovery + status subscription; do not hard-code 0
  3. Audio source: TTS text, an existing resource ID, or a local file (local files go through the four-step STS upload process)
  4. Whether the DRC link has been established: control-type requirements must first connectDrcLink(HTTP resource management does not require it)
  5. Whether the runtime environment is server-side or browser: real-time speaking can only be implemented on the browser side; the server side can only provide TTS / audio playback

Ch5 Coding Constraints

See constraints.yaml; all critical rules must be satisfied when generating code; general SDK rules (initialization, authentication, null checks, listen/cancel pairing) reference _shared/constraints-common.yamland are not repeated in this file.

Ch6 Verification Extension

In addition to general verification, code in this domain must check:

  • the module getter uses the correct object (control -> drone, resource -> workspace), and the resource module has been null-checked
  • before control-type calls there is a connectDrcLink success branch, and on exit there is disconnectDrcLink
  • no speakerRealTimeStart / speakerRealTimeStop / dropper-related API is generated
  • psdkIndex comes from the status callback (int), and is not mixed with the camera payload index String Mixed use
  • all listen callbacks aresingle-parameter, and the DRC Northbound callback body has null null checks
  • each listenId has been saved and paired with cancel, and the cancel parameter count/order matches references/ consistent
  • searchlightModeSet passes int,speakerPlayModeSet passes enum, not reversed
  • the audio upload process includes three abort branches: getSTS failure, upload failure, and creation failure
  • the Widget resource list is read using getUiResourceUrls() read

Anti-hallucination rules (mandatory)

  1. Example code must come from this Skill's references/ or user-provided documentation, and API signatures, field names, and enum values must not be generated from model memory
  2. It is forbidden to infer APIs from enums or javadoc—this domain has confirmed three types of over-declaration: "enum has a value but no method" (MegaphoneWorkMode 3/4/5), "declared in javadoc but not implemented" (dropper), and "source comment disabled" (real-time speaking)
  3. References must be traceable—any suggestion must be traceable to a references/ documentation path or official SDK source code (core/PsdkControlModule.java、core/PsdkResourceModule.java)

Authoritative references

Document Content
references/psdk-control.md PsdkControlModule All 34 methods: DRC link-establishment prerequisites, 6 groups of DRC Northbound subscriptions, 3 groups of WebSocket subscriptions, 16 setters, bean/enum and input parameter type comparison
references/psdk-resource.md PsdkResourceModule All 7 methods: resource CRUD, the four-step STS direct upload process, Widget resource batch query, bean field table
skills/_shared/constraints-common.yaml Cross-Skill general constraints (callbacks/initialization/null checks)

Shared specifications

For cross-Skill shared constraints, see skills/_shared/constraints-common.yaml. For cross-Skill routing rules, see skills/_shared/skill-routing.md. When it is found that the user's intent falls under the responsibility of another Skill, switch according to the handover protocol. For the output format, see skills/_shared/output-format.md. References are lazily loaded as needed; do not read all references/ at once.