单片机互通调试(未完成)

This commit is contained in:
2025-05-26 22:52:17 +08:00
parent 17cbec048e
commit 22e1109d81
5 changed files with 249 additions and 187 deletions

111
README.md
View File

@@ -131,81 +131,76 @@
### 4.2. MQTT 主题 (Topics) 约定
#### 4.2.1. 状态上报 (单片机 -> 后端)
* **主题格式**: `charging/spot/{spotUid}/status`
* `{spotUid}`: 充电桩/车位的唯一标识符 (必须与后端数据库中 `parking_spot` 表记录的 `uid` 一致)。
* **消息格式 (Payload)**: JSON
根据后端服务的实际MQTT通信实现主题约定如下
#### 4.2.1. 上行消息 (单片机 -> 后端)
所有类型的上行消息,包括设备状态更新、心跳以及对后端指令的执行回执 (ACK),都统一发送到以下主题:
* **统一上行主题格式**: `yupi_mqtt_power_project/robot/status/{spotUid}`
* `{spotUid}`: 充电桩/车位的唯一标识符 (例如 `ESP32_SPOT_001`必须与后端系统中注册的设备ID一致)。
* **消息格式 (Payload)**: JSON。
消息体结构应与后端 `com.yupi.project.model.dto.mqtt.RobotStatusMessage` 类对应。通过消息体内的字段来区分具体的消息含义。
**示例 - 常规状态更新或心跳包 (Heartbeat):**
```json
{
"spotUid": "SPOT001",
"timestamp": "2024-05-19T12:30:00Z", // ISO 8601 UTC
"status": "IDLE",
"robotUid": "ESP32_SPOT_001",
"actualRobotStatus": "IDLE", // 当前设备状态,如 IDLE, CHARGING, COMPLETED, FAULTED
// 以下为可选的详细状态,根据实际需求和后端处理逻辑添加
"voltage": 220.5,
"current": 0.0,
"power": 0.0,
"energyConsumed": 0.0, // 本次充电已用电量 (kWh)
"errorCode": 0,
"errorMessage": "",
"sessionId": null // 可选,充电中则为当前会话ID
"energyConsumed": 1.23, // kWh, 本次或累计,根据业务定义
"errorCode": 0, // 设备故障码0为正常
"message": "Device operational", // 可选的文本消息
"activeTaskId": null // 如果当前正在执行某个任务可上报任务ID或会话ID
}
```
* **状态定义 (`status`)**: (根据实际项目枚举调整)
* `IDLE`: 空闲
* `PLUGGED_IN`: 已插枪 (待启动)
* `AWAITING_START_COMMAND`: (可选) 已扫码,等待后端确认启动
* `CHARGING`: 充电中
* `STOPPING`: 停止中
* `COMPLETED`: 充电完成
* `FAULTED`: 故障
* **心跳频率**: 建议每 30-60 秒发送一次心跳(可以是一个简化的状态更新消息)。
#### 4.2.2. 指令下发 (后端 -> 单片机)
单片机需订阅以下主题以接收指令
* **启动充电指令**:
* **主题格式**: `charging/spot/{spotUid}/command/start`
* **消息格式 (Payload)**: JSON
```json
{
"commandId": "cmd_uuid_123",
"sessionId": 789,
"userId": 123
}
```
* **停止充电指令**:
* **主题格式**: `charging/spot/{spotUid}/command/stop`
* **消息格式 (Payload)**: JSON
```json
{
"commandId": "cmd_uuid_678",
"sessionId": 789,
"reason": "USER_REQUEST"
}
```
#### 4.2.3. 指令执行回执 (单片机 -> 后端, 推荐)
* **主题格式**: `charging/spot/{spotUid}/command/ack`
* **消息格式 (Payload)**: JSON
**示例 - 指令执行回执 (ACK):**
当单片机执行完后端下发的指令后,应向此统一上行主题发送一个回执消息
```json
{
"commandId": "cmd_uuid_123",
"spotUid": "SPOT001",
"status": "SUCCESS",
"message": "Charging started"
"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" // 可选,如果与特定会话相关
}
```
#### 4.2.4. 心跳 (单片机 -> 后端)
* **主题格式**: `charging/spot/{spotUid}/heartbeat`
* **消息格式 (Payload)**: JSON
#### 4.2.2. 下行指令 (后端 -> 单片机)
后端服务向特定单片机下发指令时,使用以下主题格式。单片机应订阅其自身的这个专属指令主题。
* **统一下行指令主题格式**: `yupi_mqtt_power_project/robot/command/{spotUid}`
* `{spotUid}`: 目标充电桩的唯一标识符。
* **消息格式 (Payload)**: JSON。
JSON消息体内部包含了具体的指令类型和所需参数。
**示例 - 启动充电指令:**
```json
{
"spotUid": "SPOT001",
"timestamp": "2024-05-19T12:35:00Z",
"status": "IDLE"
"commandType": "START_CHARGE", // 指令类型
"taskId": "backend_task_id_for_ack_789", // 供单片机ACK时使用的任务ID
"sessionId": "session_abc_123" // 关联的充电会话ID
// ...其他可能的参数...
}
```
* **频率**: 例如每 30-60 秒。
**示例 - 停止充电指令:**
```json
{
"commandType": "STOP_CHARGE",
"taskId": "backend_task_id_for_ack_000"
// ...其他可能的参数...
}
```
* **单片机处理逻辑**: 单片机收到消息后需解析JSON负载识别 `commandType`,提取 `taskId` (用于后续ACK),并获取其他指令参数来执行相应操作。
### 4.3. 单片机开发关键逻辑
1. **MQTT 初始化与重连机制**。