Files
mqtt_power/LogBook.md

109 lines
9.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 项目变更日志 - 第二阶段MQTT 集成
## 2023-12-02: 第二阶段启动 - MQTT 集成
- **状态**: 第一阶段开发已完成,相关日志已存档至 `LogBook_Phase1.md`
- **当前任务**: 开始第二阶段开发,重点是 MQTT 的集成。
- **依据文档**: `springboot-init-main/doc/development_stages/stage_2_mqtt_integration.md`
- **已完成**:
1. **数据库初始化**: 在 `mqtt_power` 数据库中成功创建了 `robot_task` 表。
2. **MQTT Broker 确定与配置**:
- 确认使用公共 MQTT Broker: `broker.emqx.io:1883`
- 更新 `springboot-init-main/src/main/resources/application.yml` 添加了 Broker 连接信息,并为 `client-id-prefix``command-topic-base``status-topic-base` 添加了项目唯一前缀 (如 `yupi_mqtt_power_project/`) 以确保在公共环境中的唯一性。
- 创建了 `springboot-init-main/src/main/java/com/yupi/project/config/properties/MqttProperties.java` 来映射 MQTT 配置。
3. **更新开发文档**:
- 修改了 `springboot-init-main/doc/development_stages/stage_2_mqtt_integration.md`,反映了公共 Broker 的使用、Topic 唯一性策略以及应用层鉴权的重要性。
4. **实现 MQTT 客户端核心配置 (`MqttConfig.java`, `MqttCallbackHandler.java`, `MqttConnectionManager.java`)**:
- 创建了 `com.yupi.project.mqtt.MqttCallbackHandler` 类,实现 `MqttCallbackExtended`接口,用于处理连接事件和初步的消息接收(日志记录)。在 `connectComplete` 中实现订阅状态主题 `yupi_mqtt_power_project/robot/status/+` 的逻辑。
- 创建了 `com.yupi.project.config.MqttConfig` 配置类,定义 `MqttConnectOptions``MqttClient` Beans。
- 创建了 `com.yupi.project.mqtt.MqttConnectionManager` 类,实现 `ApplicationListener<ContextRefreshedEvent>``DisposableBean`,在应用启动完成后连接 MQTT并在应用关闭前断开连接。解决了 MqttClient 初始化和连接时序问题。
5. **创建 `RobotTask` 管理基础结构**:
-`com.yupi.project.model.enums` 包下创建了 `CommandTypeEnum.java``TaskStatusEnum.java`
-`com.yupi.project.model.entity` 包下创建了 `RobotTask.java` 实体类,包含 MyBatis-Plus 注解。
-`com.yupi.project.mapper` 包下创建了 `RobotTaskMapper.java` 接口。
-`com.yupi.project.service` 包下创建了 `RobotTaskService.java` 接口,定义了任务管理的核心方法。
-`com.yupi.project.service.impl` 包下创建了 `RobotTaskServiceImpl.java` 类,并为接口方法提供了最小化占位实现。
6. **详细实现 `RobotTaskServiceImpl` 中的核心业务方法**:
- `createTask(String robotId, CommandTypeEnum commandType, String payloadJson, Long sessionId)`: 创建新的机器人任务,初始状态为 PENDING。
- `hasPendingOrSentTask(String robotId)`: 检查机器人是否有 PENDING 或 SENT 状态的任务。
- `markTaskAsSent(Long taskId, Date sentTime)`: 将任务状态从 PENDING 更新为 SENT并记录发送时间。
- `findLatestSentTaskByRobotId(String robotId)`: 查找指定机器人最近一个 SENT 状态的任务。
- `markTaskAsAcknowledged(Long taskId, boolean success, String errorMessage, Date ackTime)`: 根据机器人响应更新任务状态为 ACKNOWLEDGED_SUCCESS 或 ACKNOWLEDGED_FAILURE并记录确认时间和错误信息。
- `findAndMarkTimedOutTasks(int timeoutSeconds)`: 查找并标记已发送但超时的任务为 TIMED_OUT。
- **下一步计划 (依据 `stage_2_mqtt_integration.md`)**:
1. **实现消息发布 (`MqttService`)**:
- 创建 `MqttService` 接口和 `MqttServiceImpl` 实现类。
- 实现 `sendCommand(...)` 方法,该方法会调用 `RobotTaskService.hasPendingOrSentTask` 进行检查,调用 `RobotTaskService.createTask` 创建任务,然后通过 `MqttClient` 发布指令,最后调用 `RobotTaskService.markTaskAsSent` 更新任务状态。
2. **实现消息处理 (`MqttMessageHandler`)**:
- 创建 `MqttMessageHandler` 接口和 `MqttMessageHandlerImpl` 实现类 (之前 `MqttCallbackHandler` 中有占位,现在需要具体实现)。
- 实现 `handleStatusUpdate(String topic, String payload)` 方法,解析机器人状态,查找关联的 `RobotTask`,并调用 `RobotTaskService.markTaskAsAcknowledged` 更新任务。
- 根据机器人状态执行后续业务逻辑 (此阶段可留空或简单日志记录)。
3. **实现任务超时处理 (`TaskTimeoutHandler`)**:
- 创建 `TaskTimeoutHandler` 类,使用 `@Scheduled` 定时调用 `RobotTaskService.findAndMarkTimedOutTasks`
- (可选)根据超时任务更新关联的业务实体状态 (如 `ChargingRobot`, `ChargingSession`)。
- 更正了 `springboot-init-main/src/main/java/com/yupi/project/service/impl/MqttServiceImpl.java` 的实现,确保 `sendCommand` 方法的逻辑完整和正确。
- 实现 `TaskTimeoutHandler.java`,使用 `@Scheduled` 定时调用 `RobotTaskService.findAndMarkTimedOutTasks` 处理任务超时。
-`MyApplication.java` 中添加 `@EnableScheduling` 以启用定时任务。
-`application.yml` 中添加了 `mqtt.task.timeoutSeconds``mqtt.task.timeoutCheckRateMs` 配置项。
---
**第二阶段 (MQTT 集成) 已于 YYYY-MM-DD 完成。**
所有核心功能点包括MQTT连接、消息发布/订阅、RobotTask状态跟踪和基础超时处理已实现。
依赖于 ChargingSession 的超时后联动处理已明确推至第三阶段。
---
## YYYY-MM-DD (请替换为当前日期) - 第三阶段后端开发
- **核心业务实体与服务实现**:
- 创建了枚举类: `RobotStatusEnum`, `ParkingSpotStatusEnum`, `ChargingSessionStatusEnum`, `PaymentStatusEnum`.
- 创建了数据库实体: `ChargingRobot`, `ParkingSpot`, `ChargingSession`.
- 创建了对应的Mapper接口: `ChargingRobotMapper`, `ParkingSpotMapper`, `ChargingSessionMapper`.
- 创建了Service接口: `ChargingRobotService`, `ParkingSpotService`, `ChargingSessionService`.
- 创建了Service实现类: `ChargingRobotServiceImpl`, `ParkingSpotServiceImpl`, `ChargingSessionServiceImpl`.
- `ChargingSessionServiceImpl` 中实现了充电请求、机器人分配、状态流转 (到达、开始/结束充电)、费用计算、支付、取消、超时处理等核心逻辑。
- **API 控制器实现**:
- 创建了 `ChargingRobotAdminController` 用于管理员管理充电机器人 (CRUD, 列表查询, 状态类型)。
- 创建了 `ParkingSpotAdminController` 用于管理员管理车位 (CRUD, 列表查询, 状态类型)。
- 创建了 `ChargingSessionController` 用于用户发起充电请求、查询历史会话、支付、取消会话。
- 创建了相关的DTOs (如 `ChargingRobotAddRequest`, `ParkingSpotQueryRequest`, `ChargingRequest`, `PaymentRequest`) 和 VO (`ChargingSessionVO`).
- **MQTT与任务处理联动**:
- 更新了 `MqttMessageHandlerImpl`使其在收到机器人状态ACK后能调用 `ChargingSessionService` 更新相关充电会话的状态。
- 更新了 `TaskTimeoutHandler`,使其在检测到与会话关联的任务超时后,能调用 `ChargingSessionService` 处理会话超时逻辑。
-`ChargingSessionService` 中补充了 `getQueryWrapper` 方法用于支持分页和条件查询。
- **主要实现功能点**:
- 管理员可以增删改查充电机器人和车位。
- 用户可以请求在特定车位充电。
- 系统能够尝试分配空闲机器人,并向其发送移动指令 (通过MQTT并记录RobotTask)。
- 系统能够根据机器人通过MQTT反馈的状态到达、开始充电、结束充电更新充电会话的生命周期。
- 充电结束后,系统能计算费用,并允许用户支付。
- 用户可以在特定阶段取消充电会话。
- 机器人任务超时会影响关联的充电会话状态。
- **补充后端功能 (根据阶段计划调整)**:
-`ChargingSessionAdminController.java` 中添加了管理员分页查询所有充电会话的接口 (`POST /admin/session/list/page`)。
-`ChargingSessionController.java` 中添加了用户"优雅停止充电"的接口 (`POST /session/stop`)。
- 此接口会向机器人发送 `STOP_CHARGE` 指令,并通过 `ChargingSessionServiceImpl.stopChargingByUser` 方法创建相应的 `RobotTask`
- 会话的最终完成和计费依赖 `MqttMessageHandlerImpl` 收到机器人对 `STOP_CHARGE` 指令的成功ACK后调用 `chargingSessionService.handleChargingEnd` 处理。
- **下一步**:
- 进行详细的单元测试和集成测试。
- 完善错误处理、日志记录和边界条件。
- 更新API文档。
- **开始第三阶段前端开发**。
- 根据 `stage_3_core_charging_logic.md` 检查业务流程覆盖情况。
## 后端开发 - 第三阶段核心充电逻辑完成
* **状态**: 后端核心业务逻辑、服务实现、MQTT集成及主要API Controller已完成开发并通过多轮编译错误修复。
* 充电全流程 (请求、分配、移动、到达、开始、结束、计费、支付、取消、超时) 已实现。
* 机器人和车位的状态管理服务已实现并集成到主流程。
* 用户余额扣减实现原子性操作。
* MQTT消息处理机制已建立可处理任务ACK和常规状态上报。
* **决策**: 经过讨论,充电过程中的实时时长更新 (`currentChargingDurationSeconds`) 功能在本阶段不实现,最终计费依赖充电结束时上报的 `totalDurationSeconds`
* **后续**: 后端已为前端开发提供基础。建议在前端大规模开发前后端进行核心API的冒烟测试并完善API文档如使用Swagger