@ljybill/dji-opencloud-sdk
v1.0.2
Published
DJI FlightHub 2 公有云 OpenAPI V2.0 JavaScript SDK - 用于前端项目快速集成司空2能力
Maintainers
Readme
DJI FlightHub 2 SDK
DJI 司空 2 公有云 OpenAPI V2.0 JavaScript SDK
基于 axios 封装的前端 SDK,提供完整的司空 2 OpenAPI 调用能力,支持 TypeScript,可用于 React/Vue/Angular 等各种前端项目快速集成无人机云管理能力。
目录
功能特性
- 模块化设计:按业务功能划分为 8 个独立模块,按需使用
- TypeScript 支持:完整的类型定义,IDE 智能提示
- 自动认证:请求拦截器自动注入 Token、项目 UUID、请求 ID
- 统一错误处理:根据 HTTP 状态码和业务错误码自动分类错误
- 调试模式:开启后输出详细请求/响应日志
- 动态配置:运行时切换 Token、项目、语言等
- 工具函数:UUID 生成、轮询等待、自动重试等便捷方法
安装
# npm
npm install dji-flighthub2-sdk axios
# yarn
yarn add dji-flighthub2-sdk axios
# pnpm
pnpm add dji-flighthub2-sdk axios
axios是 peerDependency,需要单独安装。
快速开始
1. 获取认证信息
在调用 API 前,需要准备以下信息:
- X-User-Token:JWT 格式的组织密钥
- 获取路径:司空 2 -> 我的组织 -> 组织设置 -> OpenAPI -> 复制密钥
- X-Project-Uuid:项目唯一标识
- 通过
获取组织下的项目列表接口获取data.list.uuid
- 通过
2. 初始化 SDK
import { FlightHub2SDK } from 'dji-flighthub2-sdk';
const sdk = new FlightHub2SDK({
baseURL: 'https://your-flighthub2-domain', // 私有化部署时修改
userToken: 'eyJhbGciOiJIUzUxMiIs...', // 组织密钥
projectUuid: '93df839d-ae74-4f04-842e-2f1f81c89a66', // 项目UUID
timeout: 30000, // 请求超时(毫秒)
language: 'zh', // 语言:zh 或 en
debug: true, // 开启调试日志(开发时建议开启)
});3. 调用 API
// 查询系统状态
const status = await sdk.system.getStatus();
console.log(status.code === 0 ? '系统正常' : '系统异常');
// 获取项目设备列表
const devices = await sdk.device.getProjectDevices({ page: 1, page_size: 50 });
devices.list.forEach((device) => {
console.log(device.sn, device.name, device.online_status);
});
// 开启设备直播
const liveInfo = await sdk.live.start({
sn: '7CTDM3Dxxxxxx',
camera_index: '165-0-7',
video_expire: 7200,
quality_type: 'adaptive',
});
console.log('拉流地址:', liveInfo.url);
console.log('供应商:', liveInfo.url_type); // volc | agora | srs4. 快捷初始化(自动设置项目)
如果只有一个项目,可以使用快捷方法自动设置:
const sdk = new FlightHub2SDK({ userToken: 'your-token' });
const projectUuid = await sdk.initWithFirstProject();
if (projectUuid) {
console.log('已自动设置项目:', projectUuid);
// 现在可以直接调用需要 projectUuid 的接口
const devices = await sdk.device.getProjectDevices();
}认证与鉴权
认证(Authentication)
SDK 通过 X-User-Token Header 进行用户身份认证。Token 是 JWT 格式,可通过 JWT Decoder 解析出用户信息。
// 运行时更新 Token(Token 过期或切换组织时使用)
sdk.setUserToken('new-jwt-token');
// 获取当前 Token
const token = sdk.getUserToken();鉴权(Authorization)
SDK 通过 X-Project-Uuid Header 进行项目级别的资源访问控制。确保 Token 对应的用户具有该项目的权限。
// 切换当前项目
sdk.setProjectUuid('new-project-uuid');
// 获取当前项目
const projectUuid = sdk.getProjectUuid();获取 Token 和 ProjectUuid 的完整流程
// 步骤1:初始化 SDK(只需要 userToken)
const sdk = new FlightHub2SDK({
userToken: 'your-jwt-token',
});
// 步骤2:获取组织列表
const orgs = await sdk.organization.getList();
console.log(orgs.list[0].uuid); // 组织 UUID
// 步骤3:获取项目列表(自动使用 userToken 对应的组织)
const projects = await sdk.project.getList({ usage: 'complete' });
const firstProject = projects.list[0];
console.log(firstProject.uuid); // 项目 UUID
// 步骤4:设置项目 UUID 到 SDK
sdk.setProjectUuid(firstProject.uuid);
// 步骤5:现在可以调用所有接口
const devices = await sdk.device.getProjectDevices();API 参考
系统状态
// 查询司空2系统状态(code为0表示正常)
const status = await sdk.system.getStatus();
// 查询健康状态
const health = await sdk.system.getHealth();组织管理
// 获取组织列表(支持分页、搜索、排序)
const orgs = await sdk.organization.getList({
page: 1,
page_size: 20,
q: '关键字搜索',
sort_column: 'create_time',
sort_type: 'desc',
});
// 获取组织详情
const org = await sdk.organization.getDetail('org-uuid');项目管理
// 获取项目列表
const projects = await sdk.project.getList({
usage: 'complete', // complete: 分页, simple: 不分页
page: 1,
page_size: 20,
sort_column: 'create_time',
sort_type: 'desc',
});
// 获取项目详情
const project = await sdk.project.getDetail('project-uuid');
// 快捷:获取第一个项目
const projectUuid = await sdk.project.useFirstProject();设备管理
// 获取项目下的设备列表(需要先设置 projectUuid)
const devices = await sdk.device.getProjectDevices({
page: 1,
page_size: 50,
});
// 获取组织下的设备列表
const orgDevices = await sdk.device.getOrganizationDevices('org-uuid');
// 获取设备详情
const device = await sdk.device.getDetail('device-sn');
// 获取设备相机列表(用于直播)
const cameras = await sdk.device.getCameras('device-sn');
// 返回: ["165-0-7", "165-0-8"]
// 获取设备直播流状态
const streams = await sdk.device.getStreams('device-sn');直播管理
// 开启直播(完整参数)
const live = await sdk.live.start({
sn: '7CTDM3Dxxxxxx',
camera_index: '165-0-7',
video_expire: 7200, // Token有效期(秒)
quality_type: 'adaptive', // adaptive | smooth | ultra_high_definition
});
// 便捷方法:快速开启直播
const live = await sdk.live.startSimple('7CTDM3Dxxxxxx', '165-0-7');
// live 返回值
// {
// expire_ts: 1779446430, // 过期时间戳
// url: "http://...", // 拉流地址(含鉴权token)
// url_type: "volc" // 供应商: volc | agora | srs
// }
// 获取直播分享列表
const shares = await sdk.live.getShares();
// 获取指定设备的直播分享
const share = await sdk.live.getShareDetail('device-sn');
// 获取码流转发器列表(旁路推流)
const converters = await sdk.live.getStreamConverters({
device_sn: 'device-sn',
});
// 删除码流转发器
await sdk.live.deleteStreamConverter('converter-id');直播集成说明:
司空 2 会动态选择直播供应商互为备份,返回的 url_type 字段标识了当前使用的供应商:
volc- 火山引擎agora- 声网srs- SRS
建议在前端同时集成多个供应商的 SDK,根据 url_type 调用对应的拉流接口。
飞行任务
// 步骤1:检查任务下发条件
const check = await sdk.flightTask.dispatchCheck('workspace-id', {
sn: '7CTDL9K00A0046',
wayline_uuid: 'wayline-uuid',
});
if (check.errors) {
console.warn('告警:', check.errors);
}
// 步骤2:创建飞行任务
const task = await sdk.flightTask.create({
name: '巡检任务-01',
sn: '7CTDL9K00A0046',
wayline_uuid: 'wayline-uuid',
planned_time: Date.now() + 3600000, // 1小时后执行(可选)
});
// 步骤3:查询任务状态
const taskInfo = await sdk.flightTask.getInfo(task.task_uuid);
console.log(taskInfo.status); // pending | running | success | failed...
// 便捷方法:轮询等待任务完成
const finalTask = await sdk.flightTask.waitForCompletion(task.task_uuid, {
interval: 5000, // 每5秒查询一次
timeout: 300000, // 最多等待5分钟
});
// 步骤4:获取任务媒体资源(任务完成后)
const medias = await sdk.flightTask.getMedia(task.task_uuid);
medias.forEach((media) => {
console.log(media.preview_url); // 预览图
console.log(media.original_url); // 原图
});
// 步骤5:获取飞行轨迹
const track = await sdk.flightTask.getTrack(task.task_uuid);
track.points.forEach((point) => {
console.log(point.coordinate.latitude, point.coordinate.longitude);
});航线管理
// 获取航线列表
const waylines = await sdk.wayline.getList({ page: 1, page_size: 20 });
// 获取航线详情
const detail = await sdk.wayline.getDetail('wayline-uuid');
console.log(detail.waypoint_count); // 航点数量
console.log(detail.estimated_distance); // 预估距离
// 航线上传完成通知
await sdk.wayline.finishUpload({
wayline_uuid: 'wayline-uuid',
upload_result: 'success',
});实时控制
// 查询控制权状态
const authority = await sdk.remoteControl.getAuthority('device-sn');
console.log(authority.status); // idle | occupied | locked
// 获取控制权
await sdk.remoteControl.acquireAuthority('device-sn');
// 释放控制权
await sdk.remoteControl.releaseAuthority('device-sn');
// 切换相机
await sdk.remoteControl.switchCamera({
sn: 'device-sn',
camera_index: '165-0-8',
});错误处理
SDK 对所有错误进行了统一封装,根据错误类型抛出不同的异常:
| 错误类 | 说明 | 场景 |
|--------|------|------|
| AuthenticationError | 认证失败 | Token 无效、过期或缺失 |
| AuthorizationError | 鉴权失败 | 用户无权限访问项目/资源 |
| ValidationError | 参数错误 | 请求参数不符合 API 要求 |
| NetworkError | 网络错误 | 请求超时、断网 |
| ServerError | 服务器错误 | 司空 2 服务端 5xx 错误 |
| FlightHubError | 通用错误 | 其他未分类错误 |
使用示例
import {
FlightHub2SDK,
AuthenticationError,
AuthorizationError,
ValidationError,
NetworkError,
} from 'dji-flighthub2-sdk';
try {
const devices = await sdk.device.getProjectDevices();
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Token 失效,请重新获取组织密钥');
// 引导用户重新登录或刷新 Token
} else if (error instanceof AuthorizationError) {
console.error('当前用户没有该项目的权限');
// 检查项目 UUID 是否正确,或联系组织管理员
} else if (error instanceof ValidationError) {
console.error('参数错误:', error.message);
// 检查传入的参数是否符合要求
} else if (error instanceof NetworkError) {
console.error('网络异常,请检查网络连接');
// 提示用户检查网络
} else {
console.error('未知错误:', error);
}
// 所有错误都包含以下属性
console.log(error.statusCode); // HTTP 状态码
console.log(error.code); // 业务错误码
console.log(error.response); // 原始响应数据
}常见业务错误码
| 错误码 | 说明 | |--------|------| | 200101 | 请求参数错误 | | 212015 | 设备已离线 | | 212018 | 设备离线或网络异常 | | 212024 | 设备端执行指令超时 | | 219007 | 任务已开始/结束,不能编辑 | | 219008 | 任务已开始/结束,不能删除 | | 228413 | 控制权被锁定,无法获取 |
完整错误码列表请参考司空 2 官方文档。
高级配置
调试模式
// 开启调试(输出请求/响应日志)
sdk.setDebug(true);
// 关闭调试
sdk.setDebug(false);多语言
sdk.setLanguage('en'); // 切换为英文
sdk.setLanguage('zh'); // 切换为中文获取原始 axios 实例
如需自定义请求行为,可直接操作 axios 实例:
const axiosInstance = sdk.getAxiosInstance();
// 添加自定义拦截器
axiosInstance.interceptors.request.use((config) => {
// 自定义逻辑
return config;
});工具函数
SDK 提供了一些实用的工具函数:
import { generateUUID, retry, removeEmptyValues } from 'dji-flighthub2-sdk';
// 生成 UUID(用于手动构造请求)
const uuid = generateUUID();
// 自动重试函数
const result = await retry(
() => sdk.system.getStatus(),
3, // 最多重试3次
1000 // 每次间隔1秒
);
// 清理对象中的空值
const clean = removeEmptyValues({ a: 1, b: undefined, c: null });
// 结果: { a: 1 }发布 npm 包
如需将此 SDK 发布为 npm 包供其他项目使用:
1. 构建
cd dji-flighthub2-sdk
npm install
npm run build2. 登录 npm
npm login3. 发布
npm publish --access public4. 其他项目安装使用
npm install dji-flighthub2-sdk axios项目结构
dji-flighthub2-sdk/
├── src/
│ ├── index.ts # 主入口:FlightHub2SDK 类
│ ├── client.ts # HTTP 客户端核心(axios 封装)
│ ├── types.ts # TypeScript 类型定义
│ ├── error.ts # 错误类定义
│ ├── utils.ts # 工具函数
│ └── modules/
│ ├── system.ts # 系统状态
│ ├── organization.ts # 组织管理
│ ├── project.ts # 项目管理
│ ├── device.ts # 设备管理
│ ├── live.ts # 直播管理
│ ├── flightTask.ts # 飞行任务
│ ├── wayline.ts # 航线管理
│ └── remoteControl.ts # 实时控制
├── package.json
├── tsconfig.json
├── rollup.config.js
└── README.md许可证
MIT
