单片机互通调试初步完成

This commit is contained in:
2025-05-27 16:44:45 +08:00
parent 22e1109d81
commit 6aaae06bac
22 changed files with 1678 additions and 129 deletions

View File

@@ -142,34 +142,30 @@
* **消息格式 (Payload)**: JSON。
消息体结构应与后端 `com.yupi.project.model.dto.mqtt.RobotStatusMessage` 类对应。通过消息体内的字段来区分具体的消息含义。
**示例 - 常规状态更新或心跳包 (Heartbeat):**
**示例 - 常规状态更新 (如移动中、充电中、空闲等) 或心跳包 (Heartbeat):**
```json
{
"robotUid": "ESP32_SPOT_001",
"actualRobotStatus": "IDLE", // 当前设备状态,如 IDLE, CHARGING, COMPLETED, FAULTED
"actualRobotStatus": "CHARGING", // 设备当前状态, 如 IDLE, MOVING, CHARGING, COMPLETED, FAULTED
// 以下为可选的详细状态,根据实际需求和后端处理逻辑添加
"voltage": 220.5,
"current": 0.0,
"power": 0.0,
"energyConsumed": 1.23, // kWh, 本次或累计,根据业务定义
"errorCode": 0, // 设备故障码0为正常
"message": "Device operational", // 可选的文本消息
"activeTaskId": null // 如果当前正在执行某个任务可上报任务ID或会话ID
"voltage": 220.5, // 充电时相关
"current": 5.1, // 充电时相关
"power": 1.12, // kW, 充电时相关
"energyConsumed": 0.5, // kWh, 本次充电已消耗电量
"errorCode": 0, // 0表示无错误其他值表示特定错误类型
"activeTaskId": "session_xyz123" // 如果设备当前正在执行某个任务或会话上报其ID
}
```
* **心跳频率**: 建议每 30-60 秒发送一次心跳(可以是一个简化的状态更新消息)。
**示例 - 指令执行回执 (ACK):**
当单片机执行完后端下发的指令后,应向此统一上行主题发送一个回执消息。
**示例 - 对后端指令的ACK (成功):**
```json
{
"robotUid": "ESP32_SPOT_001",
"taskId": "backend_provided_task_id_123", // 后端下发指令时提供的taskId
"status": "SUCCESS", //"FAILURE"
"message": "Charging started successfully", // 对指令执行结果的描述
"errorCode": "0", // 如果失败,提供错误码
"actualRobotStatus": "CHARGING" // 执行指令后设备的当前状态
// "activeTaskId": "session_xyz" // 可选,如果与特定会话相关
"taskId": "backend_task_789", // 对应后端指令中的taskId
"status": "SUCCESS", // 指令执行结果: SUCCESS 或 FAILURE
"message": "Command executed successfully",
"actualRobotStatus": "IDLE", // ACK发生时设备的当前核心状态
"activeTaskId": "session_abc456" // 可选如果ACK与特定会话相关
}
```
@@ -182,44 +178,58 @@
* **消息格式 (Payload)**: JSON。
JSON消息体内部包含了具体的指令类型和所需参数。
**示例 - 启动充电指令:**
**示例 - 移动到车位指令 (MOVE_TO_SPOT):**
此指令指示机器人移动到指定车位。机器人到达后将自动进入充电状态。
```json
{
"commandType": "START_CHARGE", // 指令类型
"commandType": "MOVE_TO_SPOT",
"taskId": "backend_task_id_for_ack_789", // 供单片机ACK时使用的任务ID
"sessionId": "session_abc_123" // 关联的充电会话ID
// ...其他可能的参数...
"target_spot_uid": "SPOT_UID_001" // 目标车位ID (单片机仅用于确认,主要由 spotUid 主题参数决定目标)
// "sessionId": "session_abc_123" // 可选如果需要在payload中也传递会话ID
}
```
**示例 - 停止充电指令:**
**示例 - 停止充电指令 (STOP_CHARGE):**
```json
{
"commandType": "STOP_CHARGE",
"taskId": "backend_task_id_for_ack_000"
// ...其他可能的参数...
"taskId": "backend_task_id_for_ack_000",
"sessionId": "session_abc_123" // 关联的充电会话ID
}
```
* **单片机处理逻辑**: 单片机收到消息后需解析JSON负载识别 `commandType`,提取 `taskId` (用于后续ACK),并获取其他指令参数来执行相应操作。
* **单片机处理逻辑**: 单片机收到消息后需解析JSON负载识别 `commandType`,提取 `taskId` (用于后续ACK),并获取其他指令参数来执行相应操作。 对于 `MOVE_TO_SPOT`,到达后自动转换为 `CHARGING` 状态。
### 4.3. 单片机开发关键逻辑
1. **MQTT 初始化与重连机制**。
2. **订阅指令主题**。
3. **JSON 指令消息解析**。
4. **充电启停控制** (继电器等硬件操作)。
5. **状态监测与实时上报**
6. **心跳包定时发送**
7. **故障检测与上报**
8. **安全性**: 确保 `spotUid` 唯一性;推荐 MQTT 通信使用 TLS/SSL 加密
4. **移动控制** (如果机器人需要物理移动)。
5. **充电启停控制** (继电器等硬件操作,停止充电时需要)
6. **状态监测与实时上报**:
* 收到 `MOVE_TO_SPOT` 后,状态变为 `MOVING` 并上报
* 到达目标车位后,状态变为 `CHARGING` 并上报,同时对 `MOVE_TO_SPOT` 指令进行ACK
* 收到 `STOP_CHARGE` 后,停止充电,状态变为 `COMPLETED` (或 `IDLE`) 并上报,同时对 `STOP_CHARGE` 指令进行ACK。
7. **心跳包定时发送**。
8. **故障检测与上报**。
9. **安全性**: 确保 `spotUid` 唯一性;推荐 MQTT 通信使用 TLS/SSL 加密。
### 4.4. 示例流程:用户启动充电
1. 用户在前端 App 请求启动充电桩 `SPOT001`。
2. 后端服务验证,创建充电会话 `sessionId=789`。
3. 后端向 MQTT 主题 `charging/spot/SPOT001/command/start` 发布启动指令
4. 单片机 `SPOT001` 接收指令,启动充电
5. 单片机 `charging/spot/SPOT001/status` 上报状态 `CHARGING`,包含 `sessionId`。
6. (可选) 单片机向 `charging/spot/SPOT001/command/ack` 发布成功回执
7. 后端更新会话状态,前端界面同步更新
### 4.4. 示例流程:用户启动充电 (更新后)
1. 用户在前端 App 请求在车位 `SPOT001` 进行充电
2. 后端服务验证,创建充电会话 `sessionId=789`,状态为 `REQUESTED`
3. 后端分配机器人,创建 `MOVE_TO_SPOT` 任务 (例如 `taskId=task_move_123`)并将机器人DB状态更新为 `MOVING`,会话状态更新为 `ROBOT_ASSIGNED`
4. 后端向 MQTT 主题 `yupi_mqtt_power_project/robot/command/SPOT001` 发布 `MOVE_TO_SPOT` 指令payload 包含 `taskId=task_move_123`
5. 单片机 `SPOT001` 接收指令:
a. 将其内部状态更新为 `MOVING`
b. 向上行主题 `yupi_mqtt_power_project/robot/status/SPOT001` 上报状态 `MOVING`
c. (模拟)执行移动。
d. 移动到达后,将其内部状态更新为 `CHARGING`。
e. 向上行主题发送 ACK 消息,确认 `taskId=task_move_123` 完成,消息中 `actualRobotStatus` 为 `CHARGING`。
f. (可选或由ACK消息覆盖) 再次向上行主题上报状态 `CHARGING`,包含 `sessionId`。
6. 后端接收到 `MOVE_TO_SPOT` 任务 ( `taskId=task_move_123`) 的 ACK (其中机器人状态为 `CHARGING`):
a. 将 `RobotTask` ( `taskId=task_move_123`) 标记为 `COMPLETED`。
b. 将机器人 `SPOT001` 在数据库中的状态更新为 `CHARGING`。
c. 将充电会话 `sessionId=789` 的状态更新为 `CHARGING_STARTED`,并记录充电开始时间。
7. 前端界面同步更新,显示充电已开始。
## 5. 项目结构 (简要)