Skip to content

Node.js SDK

Node.js SDK 适合 TypeScript 或 JavaScript 设备程序。代码包基于 @device-agent/device-sdkBaseDevice,已处理 MQTT 连接、命令订阅、命令响应、状态上报和事件上报;真实设备逻辑在 src/device.ts 中补充。

适用场景

  • 使用 TypeScript/JavaScript 开发设备端、网关或边缘服务。
  • 需要接入已有 Node.js 服务、HTTP API、数据库或业务系统。
  • 希望用 Claude Code、Cursor 或 Codex 继续完善设备端逻辑。

代码包内容

内容作用
src/index.ts启动入口,读取 .env 并创建设备实例
src/device.ts设备逻辑入口,继承 BaseDevice
device-spec.json当前设备规格,作为命令校验和状态字段依据
packages/device-sdk本地复制的设备端 SDK,提供 BaseDevice、语音和视觉客户端
AGENTS.md / CLAUDE.md本地 AI 编程工具可以读取的实现上下文

真实接入时,修改 src/device.ts:处理命令、调用硬件或业务服务、更新状态,并在需要时上报事件。

接入步骤

  1. 下载 Node.js SDK 代码包。
  2. 复制 .env.example.env,按需替换 MQTT 地址和认证信息。
  3. 安装依赖并启动程序。
  4. src/device.ts 中把默认逻辑替换为真实设备逻辑。
  5. 回到设备智能体工作区,确认设备上线并测试控制命令。
bash
cp .env.example .env
npm install
npm run start

实现设备逻辑

src/device.ts 中的设备类继承 BaseDevice。设备连接成功后会发布状态快照;命令会进入 handleCommand()。在这里调用硬件接口或业务服务:

ts
protected override async handleCommand(command: DeviceCommandMessage) {
  if (command.cmd === "set_temperature") {
    const target = Number(command.params?.target_temperature);

    await thermostatClient.setTargetTemperature(target);
    this.patchState({ target_temperature: target });
    await this.publishStateSnapshot();

    return { code: 0, msg: "ok", data: { target_temperature: target } };
  }

  return { code: 404, msg: `Unknown command: ${command.cmd}` };
}

BaseDevice 会负责 MQTT 连接、命令订阅、响应发布和状态上报。命令名、参数名和状态字段需要与 device-spec.json 对齐。

状态变化后调用 publishStateSnapshot(),设备智能体就能看到最新数据。需要上报事件时,只上报设备规格中已经定义的事件:

ts
await this.sendEvent("temperature_alarm", {
  current_temperature: 32.5,
  level: "warning",
});

语音接入代码

Node.js SDK 中的 VoiceClient 用于设备端语音对话。设备连接 /ws/voice,发送 16 kHz 单声道 Int16LE PCM 音频,并监听识别文本、智能体回复和 TTS 音频事件。

ts
import { VoiceClient } from "@device-agent/device-sdk";

const voice = new VoiceClient({
  wsUrl: "ws://127.0.0.1:3001/ws/voice",
  deviceId: "device-001",
  productId: "agent-001",
});

voice.on("agentReply", (text) => console.log(text));

await voice.connect();
voice.startListening("manual");
voice.sendAudio(pcmChunk);
voice.stopListening();

代码包中的 packages/device-sdk/examples/voice-chat.ts 是完整示例。真实设备需要把麦克风采集和扬声器播放接到 sendAudio() 和 TTS 事件上。

视觉识别代码

Node.js 代码包会根据 VOICE_CHAT_HOST 派生 /api/vision/frames/api/chat。当设备规格中存在以下命令时,src/device.ts 会走拍照识别流程:

  • capture_and_recognize
  • take_photo_vision
  • vision_recognize
  • photo_identify

默认流程会先读取命令里的 imageDataUrlimageBase64,再读取 .env 中的 VISION_FALLBACK_IMAGE_DATA_URL。真实设备可以覆写 captureLocalVisionImage(),从摄像头、截图或图像文件读取一张图片。

ts
protected override async captureLocalVisionImage() {
  return {
    mimeType: "image/jpeg",
    imageBase64: await readCameraFrameAsBase64(),
    source: "sdk-camera",
  };
}

设备端会上传这张图片,调用 /api/chat 并携带 visionRefs,然后把识别结果作为命令响应返回。这适合命令触发的单帧识别,不是连续视频流。

使用本地 AI 编程工具继续开发

Node.js 代码包会包含 AGENTS.mdCLAUDE.md 和设备实现说明。可以在代码包目录中打开 Claude Code、Cursor 或 Codex,让它根据 device-spec.json 继续实现 src/device.ts

验证接入

启动程序后,回到设备智能体工作区确认:

  1. 设备列表中出现这台设备,并且状态为在线。
  2. 当前数据能看到 Node.js 程序上报的字段。
  3. 通过对话下发命令后,handleCommand() 中的逻辑被执行。
  4. 如果调用了 sendEvent(),最近上报事件中能看到对应记录。