跳转至

03. 设备与配置

1. 设备动态码绑定(公开 + JWT)

POST /api/device/pre-check(公开)

请求:

{
  "mac": "AA:BB:CC:DD:EE:FF",
  "username": "alice",
  "device_password": "Ab12Cd34"
}

返回(已认证):

{ "code": 200, "data": { "status": "authenticated", "call_sign": "BG7XXX" } }

返回(需绑定):

{ "code": 200, "data": { "status": "need_bind", "message": "请使用动态码绑定设备" } }

POST /api/device/request-code(公开)

请求:

{ "mac": "AA:BB:CC:DD:EE:FF" }

返回:

{ "code": 200, "data": { "dynamic_code": "735921", "expires_in": 60 } }

POST /api/device/confirm-bind(公开)

请求:

{ "mac": "AA:BB:CC:DD:EE:FF" }

返回(等待中):

{ "code": 200, "data": { "status": "waiting", "message": "等待用户完成绑定" } }

返回(已就绪):

{
  "code": 200,
  "data": {
    "status": "ready",
    "username": "alice",
    "device_password": "Ab12Cd34",
    "ssid": 11,
    "dmr_id": 4601234
  }
}

POST /api/device/bind(JWT)

请求:

{ "dynamic_code": "735921" }

返回:

{
  "code": 200,
  "data": {
    "device_mac": "AA:BB:CC:DD:EE:FF",
    "call_sign": "BG7XXX",
    "message": "绑定成功,请配置设备参数",
    "available_ssids": [1, 2, 3, 4, 5, 106],
    "recommended_ssid": 1
  }
}

POST /api/device/submit-config(JWT)

请求:

{ "device_mac": "AA:BB:CC:DD:EE:FF", "ssid": 11 }

返回:

{
  "code": 200,
  "data": {
    "message": "配置已保存",
    "udp_auth_info": {
      "username": "alice",
      "device_password": "Ab12Cd34"
    },
    "dmr_id": 4601234
  }
}

说明:

  • ssid 仅允许普通设备范围:1-99106-254
  • 100-105 为幽灵设备保留段,255 为系统历史特殊保留值,均不可用于动态绑定。
  • available_ssids / recommended_ssid 已自动排除当前用户已有设备与待绑定配置,并按从小到大推荐。
  • 普通设备运行时唯一键为 owner_id + ssid;同一用户同一 SSID 同时只允许一台在线设备。
  • 设备端动态绑定接口里的 mac 仅用于“设备绑定 / 设备确认配置”流程;普通 UDP 设备上线后的快速重连判据由心跳包 DATA 扩展区中的可选 MAC 提供。

1.1 普通 UDP 设备快速重连补充说明

  • 心跳包固定 header 不变;MAC 不会写入 header,只会可选追加在心跳 DATAGPS(24B) 之后。
  • 服务端在普通 UDP 设备在线时,会记录 owner_id + ssid -> mac 的运行时映射。
  • 如果设备短暂断线后重新建立了新的 UDP 源端口,但心跳包携带的 MAC 与当前在线实例一致,服务端会视为同一物理设备重连,允许直接接管新地址。
  • 如果 MAC 不同,则仍按“同一用户同一 SSID 已有在线设备”拒绝新实例。
  • 当设备被彻底判定离线后,这条运行时 MAC 映射会被删除。

2. 用户设备密码(JWT)

GET /api/user/device-password

PUT /api/user/device-password

请求:

{ "new_password": "Ab12Cd34" }

POST /api/user/device-password/regenerate

返回示例:

{ "code": 200, "message": "设备密码已重新生成", "data": { "device_password": "Xy98Lm12" } }

3. 设备管理(JWT + Approved)

说明:设备收发控制仅设备级生效,统一通过 PUT /api/devices/:iddisable_send / disable_recv 字段更新。

GET /api/devices

参数:pagelimitcallsigngroup_id

返回项补充:

  • last_online_ip:设备最近一次上线客户端 IP
  • last_online_ip_location:根据 IP 计算的归属地(实时计算)

GET /api/devices/list(兼容旧路径)

GET /api/device/get?id=123

GET /api/device/qth?id=123(兼容)

GET /api/device/qths

返回:设备位置列表。

PUT /api/devices/:id

请求示例:

{
  "name": "My ESP32",
  "group_id": 1001,
  "status": 1,
  "priority": 100,
  "note": "备用机",
  "disable_send": false,
  "disable_recv": false
}

说明:

  • dev_model 由设备客户端通过 UDP 协议上报并由服务端校验后写入。
  • 该接口不支持设置/修改 dev_model(传入也会被忽略)。

DELETE /api/devices/:id

POST /api/device/changegroup

PUT /api/devices/:id/group

请求体(以 body device_id 为准):

{
  "device_id": 123,
  "group_id": 1002,
  "password": "private_group_pwd"
}

说明:私有群组且用户未验证时,需要 password

4. 设备配置同步(UDP 普通设备)

GET /api/devices/:id/config

PUT /api/devices/:id/config

请求示例:

{
  "rx_freq": "439500000",
  "tx_freq": "431500000",
  "rx_ctcss": "88.5",
  "tx_ctcss": "88.5",
  "rx_tone_mode": "ctcss",
  "rx_tone_value": "88.5",
  "tx_tone_mode": "ctcss",
  "tx_tone_value": "88.5",
  "sql_level": "4",
  "power_level": "3",
  "tx_bandwidth": "1",
  "rf_guard_enabled": "1",
  "rf_guard_single_tx_limit_s": "30",
  "rf_guard_window_s": "300",
  "rf_guard_max_tx_in_window_s": "60"
}

说明:

  • power_level 当前按设备能力归一化为 1(低)或 3(高),历史值 2 会兼容映射为 3
  • rx_tone_mode / tx_tone_mode 支持 offctcsscdcss_ncdcss_i;对应的 *_tone_value 为 CTCSS 频率或 3 位 DCS 码值。
  • rf_guard_enabled 支持 0/1;为空时按默认开启处理。
  • rf_guard_single_tx_limit_s 范围 1-1800,默认 30
  • rf_guard_window_s 范围 5-3600,默认 300
  • rf_guard_max_tx_in_window_s 范围 1-rf_guard_window_s,默认 60,超过窗口值时会自动收敛到窗口上限。

POST /api/devices/:id/config/sync

返回示例:

{ "code": 200, "message": "配置已发送到设备" }

离线时:

{ "code": 200, "message": "设备离线,配置将在设备上线时自动同步" }

5. 管理员设备配置(Admin)

  • GET /api/admin/devices/:id/config
  • PUT /api/admin/devices/:id/config
  • POST /api/admin/devices/:id/config/sync

与前台配置接口字段一致,但无设备归属限制。

6. 固件管理

POST /api/firmware(Admin)

multipart/form-data 字段:

  • file:固件二进制文件(最大 16MB)
  • dev_model:设备型号(白名单:1=ESP32 1W射频版, 2=ESP32 无射频版)
  • version:版本号,semver 格式如 1.0.01.0.0-beta.1
  • changelog:更新日志(可选)

返回示例:

{
  "code": 200,
  "message": "固件上传成功",
  "data": {
    "id": 1,
    "dev_model": 1,
    "version": "1.2.0",
    "changelog": "修复WiFi重连问题",
    "file_name": "firmware.bin",
    "minio_path": "uploads/firmware/2026/04/xxx.bin",
    "file_size": 1048576,
    "file_hash": "sha256hex...",
    "is_latest": true,
    "created_by": 1,
    "create_time": "2026-04-20T10:00:00Z"
  }
}

说明:

  • 同一 dev_model + version 组合不可重复,否则返回 409
  • 上传新版本后,该型号旧版本的 is_latest 自动置为 false

GET /api/firmware(Admin)

参数:dev_model(可选,0=全部)、pagepage_size

每条记录额外返回 download_url 字段(MinIO 永久链接)。

DELETE /api/firmware/:id(Admin)

删除固件记录及 MinIO 文件。若删除的是最新版本,自动将次新版本提升为 is_latest

GET /api/public/firmware/latest(Public)

参数:dev_model(必填)

返回示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "id": 1,
    "dev_model": 1,
    "version": "1.2.0",
    "changelog": "修复WiFi重连问题",
    "file_name": "firmware.bin",
    "file_size": 1048576,
    "file_hash": "sha256hex...",
    "download_url": "https://...presigned...",
    "create_time": "2026-04-20T10:00:00Z"
  }
}

说明:

  • download_url 通过 MinIO BasePath(若已配置)拼接生成;未配置时回退为 MinIO 直链。
  • file_hash 为 SHA-256,设备端可用于校验下载完整性。
  • 该型号无固件时返回 404

7. 设备 AT/参数接口(JWT + Approved,历史业务码)

  • POST /api/device/at
  • POST /api/device/query
  • POST /api/device/change
  • POST /api/device/change1w
  • POST /api/device/change2w

示例(/api/device/at):

{
  "callsign": "BG7XXX",
  "ssid": 11,
  "type": 1,
  "atcommand": "AT+VERSION?"
}

返回示例:

{
  "code": 20000,
  "data": {
    "message": "AT命令执行成功",
    "items": { "callsign": "BG7XXX", "ssid": 11, "version": "DraARL AT V1.0" }
  }
}