智能手表接入指南
概述
MBE 为智能手表/手环设备提供轻量级 HTTP REST API,支持:
- 语音问答(超简洁回复,适合小屏幕)
- 健康数据上报(心率、步数、睡眠、血氧)
- 快捷操作(定时器、闹钟、运动追踪)
- 通知推送
API 端点
| 端点 | 方法 | 描述 |
|---|---|---|
/api/watch/query |
POST | 语音问答 |
/api/watch/health |
POST | 健康数据上报 |
/api/watch/quick |
POST | 快捷操作 |
/api/watch/ping |
GET | 健康检查 |
/api/watch/debug |
GET | 调试页面 |
服务地址
生产环境: https://mbe.hi-maker.com
调试页面: https://mbe.hi-maker.com/api/watch/debug
1. 语音问答接口
请求
POST /api/watch/query
Content-Type: application/json
{
"q": "今天天气怎么样",
"wid": "watch_001",
"uid": "user_123",
"hr": 72,
"steps": 5234,
"battery": 80
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| q | string | 是 | 语音指令/问题 |
| wid | string | 是 | 手表ID |
| uid | string | 否 | 用户ID |
| hr | int | 否 | 当前心率 |
| steps | int | 否 | 今日步数 |
| battery | int | 否 | 电池电量 % |
响应
{
"ok": true,
"a": "今天多云,气温18-25度,适合户外运动",
"display": "多云 18-25度",
"tts": "今天多云,气温18到25度",
"action": null
}
| 字段 | 说明 |
|---|---|
| ok | 是否成功 |
| a | 完整回答(最多100字符) |
| display | 显示文字(最多40字符,适合小屏幕) |
| tts | 语音播报文本(最多60字符) |
| action | 快捷操作(null表示纯问答) |
快捷操作响应
识别为快捷操作时返回动作指令:
{
"ok": true,
"a": "已设定5分钟",
"display": "已设定5分钟",
"tts": "好的,5分钟后提醒您",
"action": "timer",
"params": {"seconds": 300}
}
支持的快捷操作:
| 语音指令 | action | params | 说明 |
|---|---|---|---|
| 定时5分钟 | timer | {seconds: 300} | 定时器 |
| 设闹钟7点30 | alarm | {hour: 7, minute: 30} | 闹钟 |
| 测心率 | measure_hr | {} | 测量心率 |
| 测血氧 | measure_spo2 | {} | 测量血氧 |
| 开始跑步 | start_workout | {type: "running"} | 开始运动 |
| 结束运动 | stop_workout | {} | 结束运动 |
| 找手机 | find_phone | {} | 呼叫手机 |
| 开启勿扰 | dnd_on | {} | 勿扰模式 |
| 关闭勿扰 | dnd_off | {} | 关闭勿扰 |
| 屏幕常亮 | screen_on | {} | 保持亮屏 |
2. 健康数据上报
请求
POST /api/watch/health
Content-Type: application/json
{
"wid": "watch_001",
"uid": "user_123",
"ts": 1706198400000,
"hr": 72,
"hr_min": 55,
"hr_max": 120,
"hr_resting": 62,
"steps": 8234,
"distance": 5200,
"calories": 320,
"floors": 5,
"active_minutes": 45,
"sleep_duration": 420,
"sleep_deep": 90,
"sleep_light": 240,
"sleep_rem": 90,
"sleep_score": 85,
"spo2": 98,
"stress": 35,
"battery": 80
}
| 字段 | 类型 | 说明 |
|---|---|---|
| wid | string | 手表ID |
| ts | int | 时间戳 (毫秒) |
| hr | int | 当前心率 (次/分) |
| hr_resting | int | 静息心率 |
| steps | int | 今日步数 |
| distance | float | 距离 (米) |
| calories | int | 消耗卡路里 |
| sleep_duration | int | 睡眠时长 (分钟) |
| sleep_score | int | 睡眠评分 (0-100) |
| spo2 | int | 血氧饱和度 % |
| stress | int | 压力指数 (0-100) |
| battery | int | 电池电量 % |
响应
{
"ok": true,
"goals": {
"steps": {
"current": 8234,
"target": 8000,
"progress": 100
}
},
"tips": "太棒了!今日步数目标已达成"
}
可能的告警响应:
{
"ok": true,
"alert": {
"type": "high_hr",
"message": "心率偏高(110),请注意休息"
}
}
3. 快捷操作接口
请求
POST /api/watch/quick
Content-Type: application/json
{
"wid": "watch_001",
"action": "timer",
"params": {"seconds": 300}
}
支持的操作:
| action | params | 说明 |
|---|---|---|
| timer | {seconds} | 定时器 |
| alarm | {hour, minute} | 闹钟 |
| find_phone | {} | 找手机 |
| dnd_on | {} | 开启勿扰 |
| dnd_off | {} | 关闭勿扰 |
| start_workout | {type} | 开始运动 |
| stop_workout | {} | 结束运动 |
| measure_hr | {} | 测心率 |
| measure_spo2 | {} | 测血氧 |
| screen_on | {} | 屏幕常亮 |
响应
{
"ok": true,
"action": "timer",
"display": "定时器已设置",
"tts": "定时器已设置",
"params": {"seconds": 300}
}
集成代码示例
Android Wear (Kotlin)
import okhttp3.*
import org.json.JSONObject
class MBEWatchClient(private val baseUrl: String = "https://mbe.hi-maker.com") {
private val client = OkHttpClient.Builder()
.connectTimeout(3, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(3, java.util.concurrent.TimeUnit.SECONDS)
.build()
fun query(
question: String,
watchId: String,
heartRate: Int? = null,
steps: Int? = null,
callback: (Result<WatchResponse>) -> Unit
) {
val json = JSONObject().apply {
put("q", question)
put("wid", watchId)
heartRate?.let { put("hr", it) }
steps?.let { put("steps", it) }
}
val request = Request.Builder()
.url("$baseUrl/api/watch/query")
.post(RequestBody.create(
MediaType.parse("application/json"),
json.toString()
))
.build()
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
val body = response.body()?.string() ?: ""
val result = JSONObject(body)
callback(Result.success(WatchResponse(
ok = result.getBoolean("ok"),
display = result.optString("display", ""),
tts = result.optString("tts", ""),
action = result.optString("action", null)
)))
}
override fun onFailure(call: Call, e: IOException) {
callback(Result.failure(e))
}
})
}
fun reportHealth(watchId: String, hr: Int?, steps: Int?, spo2: Int?) {
val json = JSONObject().apply {
put("wid", watchId)
put("ts", System.currentTimeMillis())
hr?.let { put("hr", it) }
steps?.let { put("steps", it) }
spo2?.let { put("spo2", it) }
}
val request = Request.Builder()
.url("$baseUrl/api/watch/health")
.post(RequestBody.create(
MediaType.parse("application/json"),
json.toString()
))
.build()
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {}
override fun onFailure(call: Call, e: IOException) {}
})
}
}
data class WatchResponse(
val ok: Boolean,
val display: String,
val tts: String,
val action: String?
)
WatchOS (Swift)
import Foundation
class MBEWatchClient {
let baseURL: String
init(baseURL: String = "https://mbe.hi-maker.com") {
self.baseURL = baseURL
}
func query(
question: String,
watchId: String,
heartRate: Int? = nil,
steps: Int? = nil,
completion: @escaping (Result<WatchResponse, Error>) -> Void
) {
guard let url = URL(string: "\(baseURL)/api/watch/query") else {
completion(.failure(URLError(.badURL)))
return
}
var body: [String: Any] = [
"q": question,
"wid": watchId
]
if let hr = heartRate { body["hr"] = hr }
if let s = steps { body["steps"] = s }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
request.timeoutInterval = 3
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
completion(.failure(error))
return
}
guard let data = data,
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
completion(.failure(URLError(.badServerResponse)))
return
}
let response = WatchResponse(
ok: json["ok"] as? Bool ?? false,
display: json["display"] as? String ?? "",
tts: json["tts"] as? String ?? "",
action: json["action"] as? String
)
completion(.success(response))
}.resume()
}
}
struct WatchResponse {
let ok: Bool
let display: String
let tts: String
let action: String?
}
// 使用示例
let client = MBEWatchClient()
client.query(question: "定时5分钟", watchId: "my_watch") { result in
switch result {
case .success(let response):
print("Display: \(response.display)")
if let action = response.action {
// 执行本地操作
handleAction(action)
}
case .failure(let error):
print("Error: \(error)")
}
}
Python (测试)
import requests
class MBEWatchClient:
def __init__(self, base_url="https://mbe.hi-maker.com"):
self.base_url = base_url
def query(self, question, watch_id, hr=None, steps=None):
"""语音问答"""
payload = {"q": question, "wid": watch_id}
if hr: payload["hr"] = hr
if steps: payload["steps"] = steps
resp = requests.post(
f"{self.base_url}/api/watch/query",
json=payload,
timeout=3
)
return resp.json()
def report_health(self, watch_id, **data):
"""上报健康数据"""
payload = {"wid": watch_id, **data}
resp = requests.post(
f"{self.base_url}/api/watch/health",
json=payload,
timeout=3
)
return resp.json()
def quick_action(self, watch_id, action, params=None):
"""快捷操作"""
resp = requests.post(
f"{self.base_url}/api/watch/quick",
json={"wid": watch_id, "action": action, "params": params or {}},
timeout=3
)
return resp.json()
# 使用示例
client = MBEWatchClient()
# 语音问答
result = client.query("今天天气怎么样", "my_watch", hr=72, steps=5000)
print(f"显示: {result['display']}")
print(f"TTS: {result['tts']}")
# 上报健康数据
client.report_health("my_watch", hr=75, steps=6000, spo2=98)
# 快捷操作
client.quick_action("my_watch", "timer", {"seconds": 300})
设计要点
1. 屏幕适配
智能手表屏幕小(通常 390x390 或更小),MBE 返回三种文本:
| 字段 | 长度 | 用途 |
|---|---|---|
| display | 40字符 | 屏幕显示 |
| tts | 60字符 | 语音播报 |
| a | 100字符 | 完整内容 |
2. 响应时间
| 场景 | 超时设置 | 典型响应 |
|---|---|---|
| 语音问答 | 2秒 | 0.2-0.5秒 |
| 快捷操作 | - | <0.05秒 |
| 健康上报 | 3秒 | 0.02秒 |
3. 电量优化
- 使用短连接而非长连接
- 批量上报健康数据(每5-10分钟一次)
- 本地缓存常用回复
4. 离线处理
快捷操作(定时器、闹钟、运动等)应在手表本地实现,MBE 只负责语义理解。
架构说明
┌───────────┐ ┌─────────────┐
│ 智能手表 │ ──── HTTP ────→ │ MBE API │
│ WearOS/ │ │ │
│ WatchOS │ ←─── JSON ───── │ /api/watch │
└───────────┘ └─────────────┘
│ │
│ 蓝牙 ▼
▼ ┌─────────────┐
┌───────────┐ │ 专家系统 │
│ 手机 │ │ 知识库 │
│ APP │ └─────────────┘
└───────────┘
数据流:
- 手表通过蓝牙连接手机网络
- HTTP请求发送到MBE
- MBE返回简洁回复 + 操作指令
- 操作指令由手表本地执行
常见问题
1. 如何处理网络延迟?
- 设置严格的超时(2秒)
- 快捷操作本地优先处理
- 超时时返回友好提示
2. 如何节省电量?
- 不使用WebSocket长连接
- 批量上报数据
- 本地缓存常用回复
3. 如何适配不同手表?
API 统一,客户端根据屏幕大小选择使用 display(小屏)或 a(大屏)字段。