智能随访系统 — BLE SDK 数据采集全景

系统定位

基于 Veepoo BLE SDK 的微信小程序医疗级智能穿戴设备数据采集平台。通过蓝牙低功耗(BLE)协议连接可穿戴设备,自动采集生理体征数据,经结构化处理后上传至六元空间 MySQL 数据库。

生产环境已部署https://dc.ncrc.org.cn/api2


支持的设备

设备 型号 佩戴方式 连接方式 采集能力
AMOLED 智能手表 VP-W680 腕戴 BLE 5.0 血压、体温、血糖、血液成分、身体成分、血氧、心率、步数、睡眠
R04 蓝牙智能戒指 R04 指戴 BLE 4.2+ 心率、血氧、HRV、压力、睡眠

Veepoo SDK 是设备无关的通用协议层,连接后通过功能汇总包自动识别该设备支持的采集能力。


采集的 11 类数据

序号 数据类型 英文标识 采集字段 单位 上传 JSON 键名
1 心率 heartRate heartRate, heartState bpm 心率值, 心率状态
2 血氧 bloodOxygen bloodOxygen, [heartRate] % 血氧饱和度, 心率
3 血压 bloodPressure systolic, diastolic, [heartRate] mmHg 高压, 低压, 脉搏, 风险等级
4 体温 temperature temperature, [skinTemperature] °C 体温, 皮肤温度
5 血糖 bloodGlucose bloodGlucose, mealState mmol/L 血糖值_mmol_L, 餐态
6 血液成分 bloodLiquid uricAcid, cholesterol, triglyceride mg/dL 尿酸, 胆固醇, 甘油三酯
7 身体成分 bodyComposition weight, BMI, bodyFat%, muscle kg/% 体重, BMI, 体脂率, 肌肉量
8 ECG ecg heartRate, ecgWaveform[], diseaseResult[] bpm/mV 心率, 诊断, 波形采样点数
9 步数 step step, calorie, distance 步/cal/m 步数, 卡路里, 距离_米
10 睡眠 sleep fallAsleepTime, wakeUpTime, deepSleepMinutes min 入睡时间, 醒来时间, 深睡_分钟, 浅睡_分钟
11 日综合 daily 以上各项的日汇总 混合 类型: daily

生产数据流水线

┌──────────────────────────────────────────────────────┐
│  Layer 1: 硬件设备                                     │
│  AMOLED 手表 / R04 戒指                                │
│  通过 BLE 私有协议 + 加密 发送二进制数据帧               │
└──────────────────────┬───────────────────────────────┘
                       ↓
┌──────────────────────────────────────────────────────┐
│  Layer 2: 微信小程序(采集层)                          │
│  wx.onBLECharacteristicValueChange() 接收原始数据       │
│  Veepoo SDK (378KB JS) 解析协议帧 → TypeScript 结构体    │
│  57 个功能页面触发各类采集                               │
└──────────────────────┬───────────────────────────────┘
                       ↓
┌──────────────────────────────────────────────────────┐
│  Layer 3: 本地存储(离线优先)                          │
│  dataStorage.saveData('heartRate', {heartRate: 75})    │
│  写入: {wx.env.USER_DATA_PATH}/health_data/YYYY-MM-DD/ │
│  每种数据类型一个 JSON 文件,按日期分目录                 │
│  断网时数据不丢失                                      │
└──────────────────────┬───────────────────────────────┘
                       ↓ 异步 HTTPS POST
┌──────────────────────────────────────────────────────┐
│  Layer 4: 六元外网代理                                  │
│  POST https://dc.ncrc.org.cn/api2/api/health-data      │
│  六元技术负责人配置的反向代理                            │
│  将外网请求转发到内网 192.168.4.104:3000                │
└──────────────────────┬───────────────────────────────┘
                       ↓
┌──────────────────────────────────────────────────────┐
│  Layer 5: 公司服务器 192.168.4.104                      │
│  Python HTTP 服务 (/opt/suifang/health_server.py:3000) │
│  接收 JSON → to_chinese_record() 转中文字段 + 加时间戳  │
│  UPSERT 逻辑(核心):                                   │
│    1. SELECT 该 deviceId 现有行                        │
│    2. 解析 data 列大 JSON(首次为空)                   │
│    3. push 新测量到对应类型数组                         │
│    4. UPDATE 写回(首次则 INSERT 新行)                 │
└──────────────────────┬───────────────────────────────┘
                       ↓
┌──────────────────────────────────────────────────────┐
│  Layer 6: 六元 MySQL (192.168.4.174)                    │
│  数据库: h6dp_suifang                                   │
│                                                        │
│  wearable_device      ── 设备列表(六元维护)           │
│  wearable_device_data ── 体征数据(一台设备一行)        │
│    id        : 自增主键                                 │
│    deviceId  : 关联 wearable_device.id(每台设备一行)  │
│    data      : 大 JSON(11 类数据分组数组)             │
│    createTime: 最后更新时间                             │
└──────────────────────────────────────────────────────┘

大 JSON 结构示例

每台设备 1 行,data 列汇总该设备的所有历史测量:

{
  "心率": [
    {"心率值": 72, "心率状态": "静息", "采集时间": "2026-04-07T08:05:34.000Z"},
    {"心率值": 75, "心率状态": "静息", "采集时间": "2026-04-07T08:08:45.000Z"}
  ],
  "血压": [
    {"高压": 128, "低压": 82, "脉搏": 72, "风险等级": "高血压1级", "采集时间": "..."}
  ],
  "血氧": [...],
  "体温": [...],
  "血糖": [...],
  "血液成分": [...],
  "身体成分": [...],
  "心电": [...],
  "步数": [...],
  "睡眠": [...],
  "日综合": [...]
}

11 类数据 → 11 个键,每个键的值都是该类型所有历史测量的数组。客户读取时只需 1 次查询即可获取该设备的全部数据。


数据结构示例

血压数据(含自动风险分级)

{
  "类型": "血压",
  "高压": 128,
  "低压": 82,
  "脉搏": 72,
  "风险等级": "正常"
}

心率数据

{
  "类型": "心率",
  "心率值": 72,
  "心率状态": "静息"
}

睡眠数据

{
  "类型": "睡眠",
  "入睡时间": "23:15",
  "醒来时间": "07:30",
  "深睡_分钟": 120,
  "浅睡_分钟": 280
}

REST API

生产基地址https://dc.ncrc.org.cn/api2

方法 端点 说明
POST /api/health-data 写入一条体征记录
GET /api/data 查询所有已写入数据
GET /api/status 服务器健康检查

验证示例

# 检查服务器状态
curl https://dc.ncrc.org.cn/api2/api/status

# 查看所有数据
curl https://dc.ncrc.org.cn/api2/api/data

# 写入测试数据
curl -X POST https://dc.ncrc.org.cn/api2/api/health-data \
  -H "Content-Type: application/json" \
  -d '{"dataType":"bloodPressure","data":{"systolic":120,"diastolic":80,"heartRate":72}}'

关键技术点

  1. 一台设备一行:UPSERT 模式,每台设备在 MySQL 中只占 1 行;新数据通过 SELECT-merge-UPDATE 合并到大 JSON
  2. 大 JSON 汇总:11 类数据按中文键分组,每类是数组结构,保留历史测量
  3. 离线优先架构:本地 JSON 文件先存,HTTPS 上传后发,断网不丢数据
  4. 设备无关协议:Veepoo SDK 通过功能汇总包自动适配不同设备的采集能力
  5. 中文 JSON 映射:SDK 采集的英文字段自动转为中文键名存入六元数据库
  6. 自动风险分级:血压数据写入时自动按 AHA 标准分级(正常/偏高/高血压1级/高血压2级/危急)
  7. 外网可达:通过六元配置的反向代理,手机无需连接公司 WiFi 即可上传数据

当前状态

维度 状态
生产数据服务 ✅ 已部署(dc.ncrc.org.cn/api2)
数据格式 ✅ 一台设备一行 + 大 JSON 汇总(11 类)
六元 MySQL 写入 ✅ 已验证(设备 1 含 10 类数据)
真机 BLE 采集 ❌ 待测试(需连接手表走完整流程)