跳转至

设备通信协议

概述

设备通过 WebSocket 连接与 Cloud API 通信。设备端在连接时通过 X-Device-ID 头部标识自身身份,所有数据帧使用 JSON 格式。

连接

设备连接到 WebSocket 端点,并携带设备 ID:

ws://<host>:8765
Headers:
  X-Device-ID: <device_id>

协议流程

sequenceDiagram
    participant Device as 设备
    participant Cloud as Cloud API

    Device->>Cloud: WebSocket 连接 (X-Device-ID)
    Device->>Cloud: register {token, hostname, ip, version}
    Cloud->>Device: register_ack {success: true}

    loop 每 30 秒
        Device->>Cloud: heartbeat
        Cloud->>Device: heartbeat_ack
    end

    Note over Device,Cloud: 设备状态上报(可选)
    Device->>Cloud: status_report { ... }

    Note over Device,Cloud: 云端请求代理
    Cloud->>Device: request {id, method, path, params, body}
    Device->>Cloud: response {id, data}

帧类型

注册 (register)

设备连接后立即发送,必须在接收任何代理请求之前完成注册。

设备 → 云端:

{
  "type": "register",
  "data": {
    "token": "设备共享令牌",
    "hostname": "janpnp-host",
    "ip": "192.168.1.10",
    "version": "1.0.0"
  }
}

云端 → 设备:

{
  "type": "register_ack",
  "id": "uuid",
  "timestamp": 1721788800000,
  "data": {
    "success": true
  }
}

若 Token 验证失败:

{
  "type": "register_ack",
  "id": "uuid",
  "timestamp": 1721788800000,
  "data": {
    "success": false,
    "error": "token 验证失败"
  }
}

心跳 (heartbeat)

设备每 30 秒发送一次心跳以维持连接。

设备 → 云端:

{
  "type": "heartbeat",
  "id": "uuid",
  "timestamp": 1721788800000,
  "data": {}
}

云端 → 设备:

{
  "type": "heartbeat_ack",
  "id": "uuid",
  "timestamp": 1721788800000,
  "data": {}
}

请求 (request)

云端向设备发送代理请求。

云端 → 设备:

{
  "type": "request",
  "id": "uuid",
  "timestamp": 1721788800000,
  "method": "GET",
  "path": "/system/status",
  "params": {},
  "body": null
}
字段 类型 说明
id string 请求唯一标识,用于匹配响应
method string HTTP 方法 (GET/POST/PUT/DELETE)
path string 设备端 API 路径
params object 查询参数
body any 请求体(可选)

响应 (response)

设备处理完请求后回复。

设备 → 云端:

{
  "type": "response",
  "id": "uuid",
  "data": {
    "success": true,
    "status": 200,
    "data": {}
  }
}
字段 类型 说明
id string 对应请求的 ID
data.success boolean 是否成功
data.status int HTTP 状态码
data.data any 响应数据
data.error string 错误描述(失败时)

状态上报 (status_report)

设备主动上报当前状态(可选)。

设备 → 云端:

{
  "type": "status_report",
  "id": "uuid",
  "timestamp": 1721788800000,
  "data": {
    "temperature": 35.2,
    "humidity": 45.0,
    "status": "idle",
    "errors": []
  }
}

文件上传

订单文件等二进制数据使用 Base64 编码传输:

{
  "filename": "order.csv",
  "encoding": "base64",
  "data": "base64编码的文件内容"
}

错误码

状态码 含义
200 成功
400 请求参数错误
404 资源不存在
500 设备内部错误
502 设备未注册或未认证
504 处理超时

参考实现

项目中的 tools/mock_device.py 是一个可执行的模拟设备客户端,可作为协议参考实现。

安全注意事项

  • 设备 WebSocket 连接建议使用 WSS(WebSocket over TLS)
  • 设备 Token 应使用密码学安全的随机字符串
  • 设备 ID 不影响安全性,设备认证依赖 Token 校验