第五部分:详细设计文档
本章节在概要设计基础上,对软件各模块、硬件各部件、数据库、接口等进行细化设计,明确具体实现逻辑、数据结构、流程细节、硬件电路与固件设计,为编码与硬件集成提供直接依据。
5.1 软件详细设计(独立模块)
5.1.1 设备接入模块详细设计
5.1.1.1 模块类设计(以Java/Spring为例)
| 类名 | 职责 | 关键方法 |
|---|---|---|
DeviceAuthService | 设备身份验证 | authenticate(deviceId, secret) |
MqttGateway | MQTT协议处理 | handleMqttMessage(topic, payload) |
TcpServerHandler | TCP长连接处理 | channelRead(ChannelHandlerContext, Object) |
HttpDeviceController | HTTP设备接入接口 | uploadData(@RequestBody DeviceData) |
DeviceStatusManager | 设备在线状态管理 | updateStatus(deviceId, status), heartbeat(deviceId) |
5.1.1.2 设备接入流程
- MQTT接入:设备连接Broker(EMQX/Mosquitto)→ 携带用户名/密码 → Broker回调
MqttGateway→ 验证设备身份 → 订阅系统主题 → 记录接入日志 → 更新在线状态。 - TCP接入:设备建立Socket连接 → 发送认证JSON(
{deviceId, secret})→ 服务端解析验证 → 维持长连接 → 心跳保活(每30秒)。 - HTTP接入:设备POST
/api/device/upload→ 携带X-Device-Id与X-Token→ 验证通过后返回200 → 数据进入采集队列。
5.1.1.3 状态管理机制
- 使用Redis存储设备在线状态,key:
device:status:{deviceId},value:online/offline,TTL:90秒(心跳超时)。 - 监听MQTT的
$SYS/brokers/+/clients/+/disconnect事件主动感知离线。 - TCP连接断开时自动更新状态。
5.1.2 数据采集与存储模块详细设计
5.1.2.1 数据采集流程
-
设备上报数据 → 模块接收(同步或异步消息队列Kafka/RabbitMQ)→ 格式校验 → 解析为标准JSON结构:
json
{ "deviceId": "xxx", "timestamp": 1700000000000, "data": {"temperature": 25.6, "humidity": 60} } -
异常检测:根据预设阈值(如温度>50℃)触发告警,写入告警表。
-
存储策略:高频采集数据(秒级)写入时序数据库(如InfluxDB/TimescaleDB);设备配置、元数据写入关系库(MySQL/PG)。
5.1.2.2 数据清理与备份
- 原始数据保存30天,自动转存到冷存储(对象存储)或删除。
- 每日凌晨2点执行数据备份(全量+增量),备份保留7天。
5.1.3 远程控制模块详细设计
5.1.3.1 控制指令下发流程
- 用户在Web端点击“关闭开关” → 前端调用
POST /api/control/send - 后端生成指令ID(UUID) → 记录到
control_log表,状态为pending - 根据设备协议类型:
- MQTT:发布到设备专属topic
device/{deviceId}/control - TCP:通过对应Channel写入指令JSON
- HTTP:调用设备提供的回调URL
- MQTT:发布到设备专属topic
- 设备执行后回复ACK → 模块更新指令状态为
succeeded/failed - 若10秒内未收到ACK,触发重试(最多3次),仍失败则状态置为
failed并告警。
5.1.3.2 批量控制设计
- 支持选择多个设备 → 后台并发调用单设备控制逻辑,使用线程池(最大10线程)。
- 记录批量任务ID,可查询每个设备的执行结果。
5.1.4 用户管理与权限模块详细设计
5.1.4.1 权限模型(RBAC)
- 表结构:
user、role、permission、user_role、role_permission - 预置角色:
- 管理员:所有权限
- 普通用户:仅查看自己设备的实时数据及历史数据
- 运维人员:设备调试、固件升级、故障日志查看
5.1.4.2 认证与授权
- JWT令牌,有效期24小时,刷新令牌7天。
- 接口权限使用Spring Security注解
@PreAuthorize("hasPermission(...)")。 - 设备级权限:用户与设备通过
user_device表关联,查询时自动过滤。
5.1.5 接口详细设计(RESTful API示例)
5.1.5.1 设备注册接口
text
POST /api/device/register
Request Body: { "deviceName": "sensor_01", "protocol": "MQTT", "productKey": "xxx" }
Response: { "deviceId": "d_xxx", "secret": "xxxx" }
5.1.5.2 数据查询接口
text
GET /api/data/latest?deviceId=xxx
Response: { "deviceId": "xxx", "data": {...}, "timestamp": 1700000000 }
5.1.5.3 控制指令接口
text
POST /api/control/send
Request: { "deviceId": "xxx", "command": "turn_off", "params": {} }
Response: { "commandId": "cmd_xxx", "status": "pending" }
5.2 硬件详细设计(独立模块)
5.2.1 感知设备详细设计(以温湿度传感器为例)
5.2.1.1 硬件选型(示例)
| 组件 | 型号/规格 | 说明 |
|---|---|---|
| 传感器芯片 | SHT30 | 精度:±0.3℃ / ±2%RH |
| 主控MCU | ESP32-C3 | 支持Wi-Fi/BLE,低功耗 |
| 通信模块 | 内置Wi-Fi | 支持MQTT/TCP |
| 电源 | 3.7V锂电池 + 充电管理TP4056 | 续航约6个月(每小时上报一次) |
5.2.1.2 电路连接
- SHT30的SCL→ESP32的IO22,SDA→IO21,VCC→3.3V,GND→GND
- 电池正极→TP4056的BAT+,TP4056的OUT+→ESP32的VIN
- 预留UART0作为调试口
5.2.1.3 固件设计
- 采用Arduino/ESP-IDF开发
- 主循环:读取传感器(每10秒一次)→ 平均值计算(每分钟)→ 通过MQTT上报 → 进入深度睡眠(剩余时间)
- 上报频率可远程配置(默认60秒)
- 支持OTA升级
5.2.2 控制终端详细设计
5.2.2.1 硬件组成
- 主控:STM32F103C8T6
- 继电器模块(控制220V设备)
- 通信接口:SPI接ESP8266(透传MQTT)
- 本地存储:AT24C02(保存设备配置)
5.2.2.2 控制逻辑
- 监听通信模块转发的控制指令 → 解析指令类型(开关、PWM调光等)→ 驱动GPIO/继电器 → 读取传感器反馈(可选)→ 返回执行结果。
5.2.3 硬件协同时序
text
[传感器] --> UART --> [控制终端] --> SPI --> [通信模组] --> MQTT --> [平台]
[平台] --> MQTT --> [通信模组] --> SPI --> [控制终端] --> GPIO --> [执行器]
5.3 数据库详细设计
5.3.1 关系型数据库表设计(MySQL)
5.3.1.1 设备表 device
| 字段 | 类型 | 说明 |
|---|---|---|
| device_id | VARCHAR(32) PK | 设备唯一标识 |
| device_name | VARCHAR(64) | 设备名称 |
| protocol | ENUM('MQTT','TCP','HTTP') | 接入协议 |
| product_key | VARCHAR(32) | 产品型号 |
| secret | VARCHAR(64) | 设备密钥(加密存储) |
| status | TINYINT | 0-离线,1-在线 |
| last_active_time | DATETIME | 最后心跳时间 |
| created_time | DATETIME | 注册时间 |
5.3.1.2 用户表 user
| 字段 | 类型 | 说明 |
|---|---|---|
| user_id | INT AUTO PK | |
| username | VARCHAR(32) UNIQUE | |
| password | VARCHAR(128) | bcrypt加密 |
| role_id | INT | 关联角色表 |
| ... | ... |
5.3.1.3 指令日志表 control_log
| 字段 | 类型 | 说明 |
|---|---|---|
| command_id | VARCHAR(36) PK | |
| device_id | VARCHAR(32) | |
| command | TEXT | 指令内容 |
| status | VARCHAR(16) | pending/succeeded/failed |
| retry_count | INT | 重试次数 |
| create_time | DATETIME | |
| finish_time | DATETIME |
5.3.2 时序数据库设计(InfluxDB)
- 测量名:
device_data - Tag:
device_id,sensor_type - Field:
value(数值),unit(单位) - Timestamp:毫秒级时间戳
示例查询:SELECT mean(value) FROM device_data WHERE device_id='xxx' AND time > now()-1d