服务默认地址:
http://{host}:{port}(默认http://0.0.0.0:2101)
交互式 API 文档:启动服务后访问/docs
协议版本:HTTP API v1 / MQTT snlp/v1
| 环境 | 地址 |
|---|---|
| 本地开发 | http://124.222.109.197:2101 |
| 生产部署 | 由 .env 中 BASE_URL 配置,终端下载资源须使用该地址 |
JSON 接口统一使用:
Content-Type: application/json
SSE 对话流接口返回:
Content-Type: text/event-stream
FastAPI 标准错误格式:
{
"detail": "Course not found: course99"
}
常见 HTTP 状态码:
| 状态码 | 说明 |
|---|---|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 404 | 资源不存在 |
| 422 | 请求体校验失败 |
健康检查,查看服务与 MQTT 连接状态。
请求示例:
curl http://124.222.109.197:2101/health
响应示例:
{
"status": "ok",
"mqtt_connected": true
}
| 字段 | 类型 | 说明 |
|---|---|---|
| status | string | 服务状态,固定 "ok" |
| mqtt_connected | boolean | MQTT Broker 是否已连接 |
托管 data/ 目录下的课程文件,供终端 HTTP 下载。
URL 规则:
{BASE_URL}/static/{相对路径}
示例:
| 资源 | URL |
|---|---|
| 课程索引 | http://124.222.109.197:2101/static/courses/index.json |
| 课程配置 | http://124.222.109.197:2101/static/courses/course01/course.json |
| 课程任务包 | http://124.222.109.197:2101/static/courses/course01/courseTask.json |
| 音频 | http://124.222.109.197:2101/static/courses/course01/chapter01/resources/001.mp3 |
| 封面 | http://124.222.109.197:2101/static/courses/course01/chapter01/resources/001.png |
请求示例:
curl -O http://124.222.109.197:2101/static/courses/course01/courseTask.json
响应: 对应文件的二进制/JSON 内容。
根据设备上下文进行场景识别,返回问候策略与建议意图。
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| timestamp | int | 是 | Unix 时间戳 |
| audio_blob | string | 是 | Base64 音频或占位符 |
| device_id | string | 是 | 设备 ID |
| context_hints | object | 否 | 场景提示,如 {"scene":"dining","confidence":0.9} |
请求示例:
curl -X POST http://124.222.109.197:2101/api/v1/scene/analyze \
-H "Content-Type: application/json" \
-d '{
"timestamp": 1718365200,
"audio_blob": "",
"device_id": "SN-88293021",
"context_hints": {
"scene": "dining",
"confidence": 0.9
}
}'
响应示例:
{
"scene": "用餐",
"confidence": 0.9,
"greeting_strategy": "contextual",
"suggested_intent": "What are you having for dinner?"
}
| 字段 | 类型 | 说明 |
|---|---|---|
| scene | string | 场景名称 |
| confidence | float | 置信度 0~1 |
| greeting_strategy | string | "contextual" 场景问候 / "generic" 通用问候(置信度 < 0.7) |
| suggested_intent | string | 建议的开场白或提问 |
低置信度响应示例:
{
"scene": "通勤",
"confidence": 0.62,
"greeting_strategy": "generic",
"suggested_intent": "Hello! How can I help you practice English today?"
}
SSE(Server-Sent Events)流式返回教学对话内容。
Query 参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| dialogue_id | string | 否 | 自动生成 UUID | 对话 ID |
| user_text | string | 否 | — | 用户回复文本(ASR 结果) |
| scene_prompt | string | 否 | — | 场景开场白(来自 scene/analyze) |
| difficulty | string | 否 | A2 | CEFR 难度等级 |
请求示例:
# 仅开场问候
curl -N "http://124.222.109.197:2101/api/v1/dialogue/stream?scene_prompt=What%20are%20you%20having%20for%20dinner?&difficulty=A2"
# 含用户回复的反馈
curl -N "http://124.222.109.197:2101/api/v1/dialogue/stream?user_text=Good%20morning.&difficulty=A2"
响应格式(SSE):
event: message
data: {"dialogue_id":"a1b2c3d4-...","text":"What are you having for dinner?","audio_url":null,"intent_type":"greeting","difficulty_level":"A2"}
event: message
data: {"dialogue_id":"a1b2c3d4-...","text":"Great job! Your sentence looks correct.","audio_url":null,"intent_type":"praise","difficulty_level":"A2"}
event: message
data: {"dialogue_id":"a1b2c3d4-...","text":"What would you do differently next time?","audio_url":null,"intent_type":"question","difficulty_level":"A2"}
event: done
data: {"dialogue_id":"a1b2c3d4-..."}
message 事件 data 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| dialogue_id | string | 对话 ID |
| text | string | 对话文本 |
| audio_url | string | null | 音频 URL(当前为 null) |
| intent_type | string | greeting / praise / correction / question |
| difficulty_level | string | 难度等级 |
获取已发布课程索引(对应 data/courses/index.json)。
请求示例:
curl http://124.222.109.197:2101/api/v1/courses
响应示例:
{
"courses": [
{
"course_id": "course01",
"config": "courses/course01/course.json"
},
{
"course_id": "course02",
"config": "courses/course02/course.json"
}
]
}
获取单门课程详情(章节与视频列表)。
请求示例:
curl http://124.222.109.197:2101/api/v1/courses/course01
响应示例:
{
"course_id": "course01",
"course_name": "小智学习课程01",
"description": "课程01",
"chapters": [
{
"chapter_id": "chapter01",
"chapter_name": "第一章",
"videos": [
{
"id": "001",
"title": "课程001",
"path": "courses/course01/chapter01/resources/001.mp3"
}
]
}
]
}
预览全部基础课程同步包(MQTT 下发前的完整 payload,url 已补全)。
请求示例:
curl http://124.222.109.197:2101/api/v1/courses/base-manifest
响应示例:
{
"scope": "base",
"course_count": 2,
"courses": [
{
"version": "1.0",
"course_id": "course01",
"course_name": "小智学习课程01",
"description": "课程01终端初始化任务:下载章节视频并更新本地资源清单",
"assets": [
{
"url": "http://124.222.109.197:2101/static/courses/course01/chapter01/resources/001.mp3",
"md5": "...",
"title": "第一章 课程001",
"target_path": "courses/course01/chapter01/resources/001.mp3",
"cover_url": "http://124.222.109.197:2101/static/courses/course01/chapter01/resources/001.png",
"cover_target_path": "courses/course01/chapter01/resources/001.png"
}
]
}
]
}
获取单门课程的同步包(url / cover_url 已补全为完整 HTTP 地址)。
请求示例:
curl http://124.222.109.197:2101/api/v1/courses/course01/manifest
响应示例:
{
"version": "1.0",
"course_id": "course01",
"course_name": "小智学习课程01",
"description": "课程01终端初始化任务:下载章节视频并更新本地资源清单",
"assets": [
{
"url": "http://124.222.109.197:2101/static/courses/course01/chapter01/resources/001.mp3",
"md5": "...",
"title": "第一章 课程001",
"target_path": "courses/course01/chapter01/resources/001.mp3",
"cover_url": "http://124.222.109.197:2101/static/courses/course01/chapter01/resources/001.png",
"cover_target_path": "courses/course01/chapter01/resources/001.png"
}
]
}
获取原始 courseTask.json(本地文件内容,url 为相对路径)。
请求示例:
curl http://124.222.109.197:2101/api/v1/courses/course01/tasks
响应示例:
{
"version": "1.0",
"course_id": "course01",
"course_name": "小智学习课程01",
"description": "课程01终端初始化任务:下载章节视频并更新本地资源清单",
"assets": [
{
"url": "courses/course01/chapter01/resources/001.mp3",
"md5": "...",
"title": "第一章 课程001",
"target_path": "courses/course01/chapter01/resources/001.mp3",
"cover_url": "courses/course01/chapter01/resources/001.png",
"cover_target_path": "courses/course01/chapter01/resources/001.png"
}
]
}
获取设备开机初始化任务清单(data/tasklist.json)。
请求示例:
curl http://124.222.109.197:2101/api/v1/tasklist
响应示例:
{
"version": "1.0",
"description": "终端设备初始化任务清单,开机后由服务端下发执行",
"tasks": [
{
"task_id": "init_001",
"name": "同步系统时钟",
"action": "SET_CLOCK",
"channel": "ctl",
"ttl": 60,
"payload": { "ts": 0 }
},
{
"task_id": "init_002",
"name": "设置默认音量",
"action": "SET_VOLUME",
"channel": "ctl",
"ttl": 60,
"payload": { "level": 50 }
},
{
"task_id": "init_003",
"name": "唤醒设备",
"action": "SET_POWER",
"channel": "ctl",
"ttl": 60,
"payload": { "state": "wake" }
}
]
}
手动触发设备完整初始化(基础 ctl 指令 + 全部基础课程 SYNC_COURSE_TASK)。
请求体:
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| device_id | string | 是 | — | 设备 ID |
| force | boolean | 否 | false | 强制重新初始化(忽略已初始化记录) |
| course_id | string | 否 | — | 本接口不使用 |
请求示例:
curl -X POST http://124.222.109.197:2101/api/v1/devices/init \
-H "Content-Type: application/json" \
-d '{
"device_id": "SN-88293021",
"force": true
}'
响应示例(成功下发):
{
"device_id": "SN-88293021",
"commands": [
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "8f932149-719c-4464-99be-66dfcfa14f29",
"timestamp": 1718365200,
"ttl": 60
},
"action": "SET_CLOCK",
"payload": { "ts": 1718365200 }
},
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "e1c1de2a-3067-417d-b533-67c9a9827a8e",
"timestamp": 1718365201,
"ttl": 7200
},
"action": "SYNC_COURSE_TASK",
"payload": {
"version": "1.0",
"course_id": "course01",
"course_name": "小智学习课程01",
"assets": []
}
}
],
"status": "dispatched"
}
响应示例(已初始化且未 force):
{
"device_id": "SN-88293021",
"commands": [],
"status": "already_initialized"
}
| status 值 | 说明 |
|---|---|
| dispatched | 指令已下发 |
| already_initialized | 设备已在初始化记录中,跳过 |
手动触发单门课程资源同步(下发 1 条 SYNC_COURSE_TASK)。
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | string | 是 | 设备 ID |
| course_id | string | 是 | 课程 ID,如 course01 |
请求示例:
curl -X POST http://124.222.109.197:2101/api/v1/devices/course-init \
-H "Content-Type: application/json" \
-d '{
"device_id": "SN-88293021",
"course_id": "course01"
}'
响应示例:
{
"device_id": "SN-88293021",
"course_id": "course01",
"commands": [
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": 1718365300,
"ttl": 7200
},
"action": "SYNC_COURSE_TASK",
"payload": {
"version": "1.0",
"course_id": "course01",
"course_name": "小智学习课程01",
"description": "课程01终端初始化任务:下载章节视频并更新本地资源清单",
"assets": [
{
"url": "http://124.222.109.197:2101/static/courses/course01/chapter01/resources/001.mp3",
"md5": "...",
"title": "第一章 课程001",
"target_path": "courses/course01/chapter01/resources/001.mp3",
"cover_url": "http://124.222.109.197:2101/static/courses/course01/chapter01/resources/001.png",
"cover_target_path": "courses/course01/chapter01/resources/001.png"
}
]
}
}
],
"status": "dispatched"
}
获取当前在线设备列表(来自 MQTT rpt/state 上报)。
请求示例:
curl http://124.222.109.197:2101/api/v1/devices
响应示例:
{
"devices": [
{
"device_id": "SN-88293021",
"cpu": 15.0,
"mem": 45.0,
"battery": 80.0,
"net": "wifi",
"mode": "idle",
"last_seen": 1718365205
}
]
}
获取已完成初始化的设备记录。
请求示例:
curl http://124.222.109.197:2101/api/v1/devices/initialized
响应示例:
{
"devices": {
"SN-88293021": {
"initialized_at": 1718365200,
"source": "auto",
"mode": "idle",
"courses_synced": true,
"courses_sync_at": 1718365201,
"courses_sync_count": 2
}
}
}
获取单个设备最新状态。
请求示例:
curl http://124.222.109.197:2101/api/v1/devices/SN-88293021
响应示例:
{
"device_id": "SN-88293021",
"cpu": 15.0,
"mem": 45.0,
"battery": 80.0,
"net": "wifi",
"mode": "idle",
"last_seen": 1718365205
}
404 响应:
{
"detail": "Device not found"
}
查询设备初始化状态。
请求示例:
curl http://124.222.109.197:2101/api/v1/devices/SN-88293021/init-status
响应示例(已初始化):
{
"device_id": "SN-88293021",
"initialized": true,
"record": {
"initialized_at": 1718365200,
"source": "auto",
"mode": "idle",
"courses_synced": true,
"courses_sync_at": 1718365201,
"courses_sync_count": 2
}
}
响应示例(未初始化):
{
"device_id": "SN-88293021",
"initialized": false,
"record": null
}
清除设备初始化记录,下次上报 rpt/state 时将重新触发自动初始化。
请求示例:
curl -X DELETE http://124.222.109.197:2101/api/v1/devices/initialized/SN-88293021
响应示例:
{
"device_id": "SN-88293021",
"status": "removed"
}
获取设备指令回执历史。
请求示例:
curl http://124.222.109.197:2101/api/v1/devices/SN-88293021/acks
响应示例:
{
"device_id": "SN-88293021",
"acks": [
{
"req_id": "8f932149-719c-4464-99be-66dfcfa14f29",
"status": "success",
"error_code": 0
}
]
}
获取设备事件与进度上报历史。
请求示例:
curl http://124.222.109.197:2101/api/v1/devices/SN-88293021/events
响应示例:
{
"device_id": "SN-88293021",
"events": [
{
"event": "asr_result",
"text": "Good morning",
"confidence": 0.95,
"_type": "event"
},
{
"task_id": "uuid",
"status": "downloading",
"progress": 45,
"info": "Downloading assets...",
"_type": "progress"
}
]
}
手动向设备下发实时控制指令(MQTT cmd/ctl)。
请求体:
{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365200,
"ttl": 60
},
"action": "SET_VOLUME",
"payload": { "level": 80 }
}
请求示例:
curl -X POST http://124.222.109.197:2101/api/v1/devices/SN-88293021/cmd \
-H "Content-Type: application/json" \
-d '{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365200,
"ttl": 60
},
"action": "SET_VOLUME",
"payload": { "level": 80 }
}'
响应示例(返回实际下发的完整指令):
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"timestamp": 1718365200,
"ttl": 60
},
"action": "SET_VOLUME",
"payload": { "level": 80 }
}
手动向设备下发异步任务指令(MQTT cmd/task)。
请求示例:
curl -X POST http://124.222.109.197:2101/api/v1/devices/SN-88293021/task \
-H "Content-Type: application/json" \
-d '{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365200,
"ttl": 7200
},
"action": "SYNC_COURSE_TASK",
"payload": {
"version": "1.0",
"course_id": "course01",
"course_name": "小智学习课程01",
"assets": []
}
}'
响应示例:
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": 1718365200,
"ttl": 7200
},
"action": "SYNC_COURSE_TASK",
"payload": {
"version": "1.0",
"course_id": "course01",
"course_name": "小智学习课程01",
"assets": []
}
}
snlp/v1/{device_id}/{direct}/{msg_type}
| 方向 | Topic | QoS | 说明 |
|---|---|---|---|
| 终端 → 云 | snlp/v1/{device_id}/rpt/state |
0 | 心跳/状态上报 |
| 终端 → 云 | snlp/v1/{device_id}/rpt/event |
0 | 事件上报 |
| 终端 → 云 | snlp/v1/{device_id}/rpt/ack |
1 | 指令执行回执 |
| 终端 → 云 | snlp/v1/{device_id}/rpt/progress |
0 | 异步任务进度 |
| 终端 → 云 | snlp/v1/{device_id}/rpt/log |
0 | 系统日志 |
| 云 → 终端 | snlp/v1/{device_id}/cmd/ctl |
1 | 实时控制指令 |
| 云 → 终端 | snlp/v1/{device_id}/cmd/task |
1 | 异步任务指令 |
参数说明:
| 参数 | 说明 |
|---|---|
| v1 | 协议版本号 |
| device_id | 设备唯一 ID,不可修改 |
| direct | rpt(终端上报)/ cmd(云端下发) |
| msg_type | state / event / ack / progress / log / ctl / task |
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "550e8400-e29b-41d4-a716-446655440000",
"timestamp": 1718365200,
"ttl": 3600
},
"action": "ACTION_TYPE",
"payload": {}
}
| header 字段 | 类型 | 说明 |
|---|---|---|
| version | string | 协议语义版本,固定 "1.0" |
| device_id | string | 目标设备 ID |
| req_id | string | 指令唯一 ID(UUID),终端 ack 时须回传 |
| timestamp | int | Unix 时间戳 |
| ttl | int | 指令有效期(秒) |
{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365205
},
"msg_type": "state",
"payload": {}
}
Topic: snlp/v1/{device_id}/rpt/state
发布示例(终端 → 云):
{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365205
},
"msg_type": "state",
"payload": {
"cpu": 15,
"mem": 45,
"battery": 80,
"net": "wifi",
"mode": "idle"
}
}
服务端行为:
mode 常见值: idle / dialogue / translate / study / sleep
Topic: snlp/v1/{device_id}/rpt/event
发布示例:
{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365210
},
"msg_type": "event",
"payload": {
"event": "asr_result",
"text": "Good morning",
"confidence": 0.95
}
}
常见 event 类型:
| event | 说明 |
|---|---|
| wake | 唤醒触发 |
| sleep | 休眠触发 |
| asr_result | ASR 识别结果 |
| alarm | 异常报警 |
Topic: snlp/v1/{device_id}/rpt/ack
发布示例:
{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365215
},
"msg_type": "ack",
"payload": {
"req_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "success",
"error_code": 0
}
}
| payload 字段 | 说明 |
|---|---|
| req_id | 对应下发指令的 req_id |
| status | success / failed |
| error_code | 0 表示成功,非 0 为错误码 |
Topic: snlp/v1/{device_id}/rpt/progress
发布示例:
{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365220
},
"msg_type": "progress",
"payload": {
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "downloading",
"progress": 45,
"info": "Downloading courses/course01/chapter01/resources/001.mp3"
}
}
Topic: snlp/v1/{device_id}/rpt/log
发布示例:
{
"header": {
"device_id": "SN-88293021",
"timestamp": 1718365230
},
"msg_type": "log",
"payload": {
"level": "error",
"module": "audio",
"message": "Microphone init failed"
}
}
Topic: snlp/v1/{device_id}/cmd/ctl
Action 列表:
| Action | payload 示例 | 说明 |
|---|---|---|
| SET_VOLUME | {"level": 50} |
设置音量 0–100 |
| SET_POWER | {"state": "wake"} |
唤醒 / sleep 休眠 |
| SET_CLOCK | {"ts": 1718365200} |
同步 Unix 时间戳 |
| PLAY_MEDIA | {"path": "courses/course01/chapter01/resources/001.mp3", "volume": 50, "loop": false} |
播放本地媒体 |
| STOP_MEDIA | {} |
停止播放 |
| SET_ALARM | {"id": "alarm_01", "time": "07:00", "repeat": [1,2,3,4,5], "action": "add"} |
设置闹钟 |
| UNSET_ALARM | {"id": "alarm_01"} |
删除闹钟 |
| REBOOT | {"delay": 5} |
延时重启 |
SET_CLOCK 下发示例:
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "8f932149-719c-4464-99be-66dfcfa14f29",
"timestamp": 1718365200,
"ttl": 60
},
"action": "SET_CLOCK",
"payload": {
"ts": 1718365200
}
}
SET_VOLUME 下发示例:
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "34dc4157-9e52-4a99-bdad-b3daf665df11",
"timestamp": 1718365200,
"ttl": 60
},
"action": "SET_VOLUME",
"payload": {
"level": 50
}
}
SET_POWER 下发示例:
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": 1718365200,
"ttl": 60
},
"action": "SET_POWER",
"payload": {
"state": "wake"
}
}
Topic: snlp/v1/{device_id}/cmd/task
当前实现使用的 Action:
| Action | 说明 |
|---|---|
| SYNC_COURSE_TASK | 下发完整课程资源包(courseTask.json 格式),终端按 assets 批量下载 |
SYNC_COURSE_TASK 下发示例:
{
"header": {
"version": "1.0",
"device_id": "SN-88293021",
"req_id": "e1c1de2a-3067-417d-b533-67c9a9827a8e",
"timestamp": 1718365201,
"ttl": 7200
},
"action": "SYNC_COURSE_TASK",
"payload": {
"version": "1.0",
"course_id": "course01",
"course_name": "小智学习课程01",
"description": "课程01终端初始化任务:下载章节视频并更新本地资源清单",
"assets": [
{
"url": "http://your-server:2101/static/courses/course01/chapter01/resources/001.mp3",
"md5": "...",
"title": "第一章 课程001",
"target_path": "courses/course01/chapter01/resources/001.mp3",
"cover_url": "http://your-server:2101/static/courses/course01/chapter01/resources/001.png",
"cover_target_path": "courses/course01/chapter01/resources/001.png"
},
{
"url": "http://your-server:2101/static/courses/course01/chapter01/resources/002.mp3",
"md5": "...",
"title": "第一章 课程002",
"target_path": "courses/course01/chapter01/resources/002.mp3",
"cover_url": "http://your-server:2101/static/courses/course01/chapter01/resources/002.png",
"cover_target_path": "courses/course01/chapter01/resources/002.png"
}
]
}
}
assets 字段说明:
| 字段 | 说明 |
|---|---|
| url | 资源完整 HTTP 下载地址(服务端自动补全) |
| md5 | 文件校验值 |
| title | 资源标题 |
| target_path | 终端存储相对路径(与服务端目录结构一致) |
| cover_url | 封面完整 HTTP 下载地址 |
| cover_target_path | 封面终端存储相对路径 |
终端处理逻辑:
SYNC_COURSE_TASK 后解析 assets 列表url 下载文件,保存到存储卡 target_path 路径cover_url 下载封面,保存到 cover_target_pathrpt/progress 上报进度rpt/ack 回传 req_id 与执行结果PRD 预留 Action(可通过 HTTP /devices/{id}/task 手动下发):
| Action | payload 示例 | 说明 |
|---|---|---|
| DOWNLOAD | {"task_id":"uuid","url":"...","md5":"...","target_path":"..."} |
单文件下载 |
| UPDATE_MANIFEST | {"course_id":"...","assets":[...]} |
更新资源清单 |
| OTA_UPDATE | {"url":"...","version":"1.0.2"} |
固件升级 |
| DELETE_FILE | {"path":"..."} |
删除文件 |
设备首次上报 rpt/state 时,服务端自动执行:
1. cmd/ctl SET_CLOCK {"ts": <当前时间戳>}
2. cmd/ctl SET_VOLUME {"level": 50}
3. cmd/ctl SET_POWER {"state": "wake"}
4. cmd/task SYNC_COURSE_TASK {course01 完整 payload}
5. cmd/task SYNC_COURSE_TASK {course02 完整 payload}
... index.json 中每门基础课程各 1 条
手动 MQTT 发布示例(mosquitto_pub):
mosquitto_pub \
-h your-mqtt-broker -p 2100 \
-u your-username -P your-password \
-t "snlp/v1/SN-88293021/cmd/task" \
-q 1 \
-m '{"header":{"version":"1.0","device_id":"SN-88293021","req_id":"manual-uuid","timestamp":1718365200,"ttl":7200},"action":"SYNC_COURSE_TASK","payload":{"version":"1.0","course_id":"course01","course_name":"小智学习课程01","assets":[]}}'
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health |
健康检查 |
| GET | /static/{path} |
静态资源下载 |
| POST | /api/v1/scene/analyze |
场景识别 |
| GET | /api/v1/dialogue/stream |
SSE 对话流 |
| GET | /api/v1/courses |
课程索引 |
| GET | /api/v1/courses/base-manifest |
全部基础课程同步包预览 |
| GET | /api/v1/courses/{course_id} |
课程详情 |
| GET | /api/v1/courses/{course_id}/manifest |
单课程同步包预览 |
| GET | /api/v1/courses/{course_id}/tasks |
原始 courseTask.json |
| GET | /api/v1/tasklist |
设备初始化任务清单 |
| POST | /api/v1/devices/init |
手动设备初始化 |
| POST | /api/v1/devices/course-init |
手动单课程同步 |
| GET | /api/v1/devices |
在线设备列表 |
| GET | /api/v1/devices/initialized |
已初始化设备 |
| DELETE | /api/v1/devices/initialized/{device_id} |
清除初始化记录 |
| GET | /api/v1/devices/{device_id} |
设备状态 |
| GET | /api/v1/devices/{device_id}/init-status |
初始化状态 |
| GET | /api/v1/devices/{device_id}/acks |
指令回执历史 |
| GET | /api/v1/devices/{device_id}/events |
事件/进度历史 |
| POST | /api/v1/devices/{device_id}/cmd |
手动下发 ctl 指令 |
| POST | /api/v1/devices/{device_id}/task |
手动下发 task 指令 |
| 方向 | Topic | 关键 Action / 用途 |
|---|---|---|
| 终端 → 云 | snlp/v1/{id}/rpt/state |
心跳,触发自动初始化 |
| 终端 → 云 | snlp/v1/{id}/rpt/event |
ASR 结果、唤醒/休眠事件 |
| 终端 → 云 | snlp/v1/{id}/rpt/ack |
指令执行回执 |
| 终端 → 云 | snlp/v1/{id}/rpt/progress |
下载/OTA 进度 |
| 终端 → 云 | snlp/v1/{id}/rpt/log |
远程排障日志 |
| 云 → 终端 | snlp/v1/{id}/cmd/ctl |
SET_CLOCK / SET_VOLUME / SET_POWER / PLAY_MEDIA 等 |
| 云 → 终端 | snlp/v1/{id}/cmd/task |
SYNC_COURSE_TASK(课程资源包同步) |
文档版本:1.0 | 对应服务端版本:1.0.0