npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ljybill/dji-opencloud-sdk

v1.0.2

Published

DJI FlightHub 2 公有云 OpenAPI V2.0 JavaScript SDK - 用于前端项目快速集成司空2能力

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 | srs

4. 快捷初始化(自动设置项目)

如果只有一个项目,可以使用快捷方法自动设置:

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 build

2. 登录 npm

npm login

3. 发布

npm publish --access public

4. 其他项目安装使用

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