云端设备API文档1.0

1.基本概念

  • SecretId: 应用身份 ID,用于接口鉴权。
  • SecretKey: 应用密钥,用于签名计算与数据加解密,严禁在客户端暴露
  • IMEI: 设备唯一标识符,通常为 15 位数字。
  • AES-256-CBC: 本平台统一使用的数据加密算法。

2. 安全与鉴权机制

所有接口请求均需进行安全校验,确保数据来源可靠且未被篡改。

2.1 签名算法 (Signature)

所有请求必须在 HTTP Header 中包含 Authorization 字段。

计算方法:

  1. 拼接字符串: StringToSign = SecretId + Timestamp + EncryptedData
  2. 生成签名: 使用 SecretKeyStringToSign 进行 HMAC-SHA256 计算,结果转为小写 16 进制字符串。

2.2 数据加密 (Encryption)

请求体中的 data 字段为 AES 加密后的密文。

  • 算法: AES-256-CBC
  • 密钥 (Key): 您的 SecretKey
  • 偏移量 (IV): 随机生成 16 字节
  • 填充模式: PKCS7
  • 密文格式: Base64(IV + CipherText) (16字节IV拼在密文前)

2.3 示例代码

PHP 示例

class ApiSecurity
{
    /**
     * 加密数据
     */
    public static function encrypt($data, $secretKey)
    {
        // 1. 生成 16 字节随机 IV
        $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
        // 2. AES 加密 (使用原始数据模式,无需手动填充)
        $encrypted = openssl_encrypt($data, 'aes-256-cbc', $secretKey, OPENSSL_RAW_DATA, $iv);
        // 3. 拼接 IV 和密文,并进行 Base64 编码
        return base64_encode($iv . $encrypted);
    }

    /**
     * 解密数据
     */
    public static function decrypt($encryptedData, $secretKey)
    {
        // 1. Base64 解码
        $raw = base64_decode($encryptedData);
        // 2. 提取前 16 字节 IV
        $iv = substr($raw, 0, 16);
        // 3. 提取剩余密文
        $cipherText = substr($raw, 16);
        // 4. AES 解密
        return openssl_decrypt($cipherText, 'aes-256-cbc', $secretKey, OPENSSL_RAW_DATA, $iv);
    }

    /**
     * 生成签名
     */
    public static function sign($secretId, $secretKey, $timestamp, $data)
    {
        $stringToSign = $secretId . $timestamp . $data;
        return hash_hmac('sha256', $stringToSign, $secretKey);
    }
}

Java 示例

import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

public class ApiSecurity {

    public static String encrypt(String data, String secretKey) throws Exception {
        byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8); // 假设Key为32字节,如果不足需补全
        // 1. 生成IV
        byte[] iv = new byte[16];
        new SecureRandom().nextBytes(iv);

        // 2. AES加密
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(iv));
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));

        // 3. 拼接 IV + 密文
        byte[] combined = new byte[iv.length + encrypted.length];
        System.arraycopy(iv, 0, combined, 0, iv.length);
        System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);

        // 4. Base64编码
        return Base64.getEncoder().encodeToString(combined);
    }

    public static String decrypt(String encryptedData, String secretKey) throws Exception {
        byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
        byte[] decoded = Base64.getDecoder().decode(encryptedData);

        // 1. 提取IV
        byte[] iv = new byte[16];
        System.arraycopy(decoded, 0, iv, 0, 16);

        // 2. 提取密文
        byte[] cipherText = new byte[decoded.length - 16];
        System.arraycopy(decoded, 16, cipherText, 0, cipherText.length);

        // 3. 解密
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), new IvParameterSpec(iv));
        return new String(cipher.doFinal(cipherText), StandardCharsets.UTF_8);
    }

    public static String sign(String secretId, String secretKey, long timestamp, String data) throws Exception {
        String stringToSign = secretId + timestamp + data;
        Mac hmacSha256 = Mac.getInstance("HmacSHA256");
        hmacSha256.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] hash = hmacSha256.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));

        // 转小写16进制
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }
}

3. 基础接入规范

  • 请求域名: https://api.cloud.sz90.cn/index.php/apply/v1/
  • 数据格式: JSON
  • 公共请求体:
{
  "secretId": "AKIDz8krbsJ5yKBZQpn74WFkm...",
  "timestamp": 1707641000,
  "data": "v7F9G...加密密文..."
}
  • 公共响应体:
{
  "status": 1,
  "msg": "成功",
  "data": { ... },
  "langKey": "common.success"
}

注:status 为 1 表示业务成功,0 表示失败。


4. 设备管理接口

本节接口用于管理设备库存、绑定状态及型号同步。所有请求均需使用上述加密方式传输 data 字段。

4.1 获取设备库存 (get_device_inventory)

查询当前应用的设备授权额度及使用情况。

  • URL: get_device_inventory
  • Method: POST
  • 请求参数: {} (空对象)
  • 响应参数 (data字段):
  • 字段 类型 说明
    purchaseNum Integer 总采购授权数量
    storeNum Integer 已入库(已添加)设备数量
    pendingStorageNum Integer 剩余可添加设备数量

4.2 添加设备 (add_device)

将新设备录入平台并绑定到指定型号。

  • URL: add_device
  • Method: POST
  • 请求参数 (解密后):
  • 字段 类型 必填 说明
    mId Integer 设备型号 ID (需先调用同步型号接口获取)
    imei Array 设备 IMEI 列表,单次建议不超过 50 个

4.3 同步型号信息 (sync_device_model)

获取平台支持的设备型号列表及其配置参数。

  • URL: sync_device_model
  • Method: POST
  • 请求参数 (解密后):
  • 字段 类型 必填 说明
    type Integer 同步类型:
    0: 指定同步 (需传 modelIds)
    1: 同步新增 (排除 modelIds)
    2: 全部同步
    modelIds Array 型号 ID 列表 (type=0/1 时使用)

4.4 解绑设备 (unbind_device)

解除设备与当前应用的绑定关系,通常会触发设备恢复出厂设置。

  • URL: unbind_device
  • Method: POST
  • 请求参数 (解密后)
  • 字段 类型 必填 说明
    devId String 设备 IMEI

4.5 删除设备 (del_apply_device)

从应用的设备列表中彻底删除设备。

  • URL: del_apply_device
  • Method: POST
  • 请求参数 (解密后):
  • 字段 类型 必填 说明
    imeiArr Array 需要删除的设备 IMEI 数组

5. 设备指令配置接口

本章节详细说明各个配置指令的参数结构。所有接口 URL 统一为 set_device_config/:command,其中 :command 为具体指令名称。

公共请求参数 (解密后 data):

字段 类型 必填 说明
devId String 设备 IMEI
config Object/Array 具体配置内容 (见下文各指令说明)

5.1 闹钟设置 (setAlarm)

  • command: setAlarm
  • config 类型: Array<Object> (最多支持 3 组)
  • config 字段说明:|
  • 字段 类型 说明
    time String 闹钟时间,格式 "HH:MM" (如 "07:30")
    status Integer 开关状态 (0:关, 1:开)
    frequency Integer 频率类型 (1:每天, 2:一次, 3:按周)
    week String 星期设置 (仅 frequency=3 时有效)。
    格式为 7 位 0/1 字符串,从周一到周日。
    例如 "1000001" 代表周一和周日开启。

5.2 SOS号码设置 (setSos)

  • command: setSos
  • config 类型: Array<String>
  • config 说明: 包含 SOS 电话号码的字符串数组,最多支持 3 个号码。
  • 示例: ["13800138000", "13900139000"]

5.3 亲情联系人/白名单 (setPhl)

  • command: setPhl
  • config 类型: Array<Object>
  • config 字段说明:
  • 字段 类型 说明
    name String 联系人姓名
    phone String 电话号码

5.4 频率设置 (setFrq)

设置设备各项传感器数据的自动上报频率。

  • command: setFrq
  • config 类型: Object
  • config 字段说明:
  • 字段 类型 说明
    type Integer 频率类型:
    0: 定位
    1: 心率
    2: 体温
    3: 血氧
    4: 血压
    5: HRV
    switch Integer 开关 (0:关, 1:开)
    frequency Integer 间隔时间 (分钟)。
    部分设备定位频率最小 5 分钟,体温最小 60 分钟。

5.5 功能开关 (setSwitch)

控制设备的各项功能开关。注意:具体支持的开关类型取决于设备型号。

  • command: setSwitch
  • config 类型: Object
  • config 字段说明:
  • 字段 类型 说明
    type Integer 开关类型:
    0: 跌倒检测
    1: SOS短信
    2: 防打扰/白名单
    3: 拨号盘
    4: 计步
    5: 低电报警
    6: 摘除报警
    9: 体温检测
    10: 语音播报
    11: 睡眠检测
    12: 窄床模式
    switch Integer 状态 (0:关, 1:开)
    value Integer (可选) 附加值,例如 type=0 (跌倒) 时代表灵敏度 (1-3)。

5.6 立即指令 (instantCmd)

下发立即执行的指令,不带参数配置。

  • command: instantCmd
  • 请求参数: 注意参数名为 type 而非 config
  • 字段 类型 说明
    type Integer 指令类型:
    0: 立即定位
    1: 测量心率
    2: 测量体温
    3: 测量血氧
    4: 测量血压
    5: 恢复出厂设置
    6: 查找设备 (响铃)
    7: 远程关机
    8: 测量HRV

5.7 发送微聊 (sendMicroChat)

向设备发送语音或文本消息。

  • command: sendMicroChat
  • 请求参数:
  • 字段 类型 说明
    type Integer 消息类型 (0:语音, 1:文本)
    content String 消息内容:
    type=0: Base64 编码的 AMR 格式语音数据
    type=1: 文本字符串

5.8 提醒类设置 (吃药/用餐/喝水/喝茶)

统一的时间段提醒设置接口。

  • command:
    • setMedicineAlarm (吃药)
    • setDiningAlarm (用餐)
    • setWaterAlarm (喝水)
    • setTeaAlarm (喝茶)
  • config 类型: Array<Object>
  • config 字段说明 (吃药/用餐):
  • 字段 类型 说明
    time String 提醒时间 (HH:MM)
    status Integer 开关 (0:关, 1:开)
    frequency Integer 频率 (1:每天, 2:一次, 3:按周)
    week String 星期设置 (同 setAlarm)
  • config 字段说明 (喝水/喝茶)
  • 字段 类型 说明
    startTime String 开始时间 (HH:MM)
    endTime String 结束时间 (HH:MM)
    frequency Integer 间隔时间 (分钟, 范围 5-120)
    status Integer 开关 (0:关, 1:开)

5.9 运动提醒 (setExerciseAlarm)

  • command: setExerciseAlarm
  • config 类型: Object
  • config 字段说明:
  • 字段 类型 说明
    frequency Integer 检测频率 (分钟)
    sosSwitch Integer SOS 开关
    data Array
    < Object >
    时段列表,每项包含:{startTime: "HH:MM", endTime: "HH:MM", status: 1}

5.10 滴滴报警设置 (setDiDi)

  • command: setDiDi
  • config 类型: Object
  • config 字段说明:
  • 字段 类型 说明
    type Integer 操作类型 (0:发送报警, 1:更新状态)
    alarmId Integer 报警 ID
    status Integer (仅type=1) 状态值
    groupName String (仅type=0) 组名
    devName String (仅type=0) 设备名

5.11 其他设置 (setOther)

  • command: setOther
  • config 类型: Object
  • config 字段说明:
  • 字段 类型 说明
    type Integer 设置类型:
    1: 跌倒灵敏度 (value: 1-3)
    2: 跌倒报警电话 (value: 电话号码)
    value Integer/String 设置值

6. 数据转发规范 (Forwarding)

当设备上报数据(如 SOS 报警、定位更新、心跳等)时,云端将通过 HTTP POST 异步转发至您的服务器。

6.1 转发机制

  • URL: 您在平台配置的回调地址。
  • Header: Authorization: {Signature} (同 API 鉴权)。
  • Body: 加密后的 JSON 字符串 { "data": "...", "timestamp": ... }

6.2 转发数据结构 (解密后)

所有转发数据解密后均包含以下公共字段:

字段 类型 说明
devId String 设备 IMEI
pushType Integer 推送类型 (见下文)
data Object 具体的业务数据对象

6.2.1 心跳/步数数据 (pushType: 0)

设备定期上报的基本状态数据。

  • 字段说明:
  • 字段 类型 说明
    electricAmount Integer 剩余电量百分比 (0-100)
    stepNumber Integer 今日累计步数
  • 示例 JSON:
{
  "devId": "863916050806960",
  "pushType": 0,
  "data": {
    "electricAmount": 85,
    "stepNumber": 5600
  }
}

6.2.2 定位数据 (pushType: 1)

设备的位置更新信息。

  • 字段说明:
  • 字段 类型 说明
    longitude Float 经度 (GCJ-02坐标系)
    latitude Float 纬度 (GCJ-02坐标系)
    address String 逆地理编码后的详细地址
    locationType Integer 定位方式 (0:GPS, 1:WIFI, 2:LBS)
  • 示例 JSON:
{
  "devId": "863916050806960",
  "pushType": 1,
  "data": {
    "longitude": 113.123456,
    "latitude": 22.123456,
    "address": "广东省深圳市南山区...",
    "locationType": 0
  }
}

6.2.3 报警数据 (pushType: 2)

设备触发的紧急报警信息。

  • 字段说明:
  • 字段 类型 说明
    alarmType Integer 报警类型码 (详见附录 7.1)
    alarmText String 报警描述文本
    longitude Float 报警时的经度
    latitude Float 报警时的纬度
    address String 报警时的地址
    locationType Integer 定位方式(0:GPS 1:WIFI 2:LBS)
  • 示例 JSON:
{
  "devId": "863916050806960",
  "pushType": 2,
  "data": {
    "alarmType": 2,
    "alarmText": "SOS报警",
    "longitude": 113.123456,
    "latitude": 22.123456,
    "address": "广东省深圳市南山区...",
    "locationType": 0
  }
}

6.2.4 健康数据 (pushType: 3)

设备测量的健康体征数据。

  • 字段说明:
  • 字段 类型 说明
    heart Integer 心率 (bpm)
    temperature Float 体温 (℃)
    ox Integer 血氧饱和度 (%)
    systolic Integer 收缩压 (mmHg)
    diastolic Integer 舒张压 (mmHg)
    hrv Integer 心率变异性 (ms)
  • 示例 JSON:
{
  "devId": "863916050806960",
  "pushType": 3,
  "data": {
    "heart": 75,
    "temperature": 36.5,
    "ox": 98,
    "systolic": 120,
    "diastolic": 80,
    "hrv": 50
  }
}

6.2.5 微聊消息 (pushType: 4)

设备发来的语音消息。

  • 字段说明:
  • 字段 类型 说明
    voice String Base64 编码的 AMR 格式语音数据
  • 示例 JSON:
{
  "devId": "863916050806960",
  "pushType": 4,
  "data": {
    "voice": "f08P7...Base64..."
  }
}

6.2.6 滴滴报警回调 (pushType: 6)

滴滴报警处理结果的异步通知。

  • 字段说明:
  • 字段 类型 说明
    actionType String 固定为 "accept_record"
    alarmId Integer 关联的报警 ID
  • 示例 JSON:
{
  "devId": "863916050806960",
  "pushType": 6,
  "data": {
    "actionType": "accept_record",
    "alarmId": 12345
  }
}

7. 附录

7.1 报警类型对照表 (alarmType)

Code 说明 Code 说明
1 心率超标 18 设备已离线
2 SOS报警 23 电子围栏报警
3 电量过低 25 体温超标
4 跌倒报警 38 手表已佩戴
6 血压超标 103 房间里有人
8 久坐提醒 104 房间里无人
10 血糖超标 120 离床
12 血氧超标 201 房颤预警
13 手表已摘除 300 呼吸异常
14 主动关机 302 烟感报警
15 自动关机 306 检测到火灾
16 离家提醒 312 门磁打开
17 到家提醒 317 燃气报警

7.2 常见错误码

  • status: 0, msg: "签名错误": 请检查签名计算过程及 SecretKey。
  • status: 0, msg: "请求已超时": 请确保请求时间戳与服务器时间偏差在 5 分钟内。
  • status: 0, msg: "设备不存在": 请检查 imei 是否已添加或 mId 是否正确。