修复充电请求流程

This commit is contained in:
2025-06-07 16:28:02 +08:00
parent f132b557df
commit fb27dc6f29
8 changed files with 243 additions and 137 deletions

View File

@@ -130,7 +130,7 @@ void callback(char *topic, byte *payload, unsigned int length) {
if (cmdType == nullptr || taskId == nullptr) {
Serial.println("指令JSON缺少 commandType/command 或 taskId 字段。");
publish_ack_message(0, "指令解析失败", false, "Command JSON invalid (missing commandType/command or taskId)");
publish_ack_message(taskId, false, "Command JSON invalid (missing commandType/command or taskId)", nullptr);
return;
}
@@ -170,7 +170,7 @@ void callback(char *topic, byte *payload, unsigned int length) {
chargeStartTimeMillis = millis();
Serial.println("状态更新: CHARGING (已到达目标车位 " + currentSpotId + ",视为开始充电)");
publish_ack_message(taskId, "移动到指定点", true, "Robot arrived at spot and started charging (simulated)");
publish_ack_message(taskId, true, "Robot arrived at spot and started charging (simulated)", currentSpotId.c_str());
publish_status_update(false, nullptr, nullptr, nullptr, nullptr, nullptr);
@@ -196,7 +196,7 @@ void callback(char *topic, byte *payload, unsigned int length) {
currentSessionId = "";
}
Serial.println("模拟: 充电已启动。会话ID: " + currentSessionId + ", 车位: " + currentSpotId);
publish_ack_message(taskId, "开始充电", true, "Charging started successfully");
publish_ack_message(taskId, true, "Charging started successfully", currentSessionId.c_str());
publish_status_update(false, nullptr, nullptr, nullptr, nullptr, nullptr);
} else if (strcmp(cmdType, "STOP_CHARGE") == 0) {
@@ -214,7 +214,7 @@ void callback(char *topic, byte *payload, unsigned int length) {
currentSessionId = "";
// 在ACK中上报准确的充电时长如果需要的话可以通过修改 publish_ack_message 或在 message 字段中添加
// For now, the generic ACK is sent.
publish_ack_message(taskId, "停止充电", true, ("Charging stopped. Duration: " + String(chargeDuration) + "s").c_str(), currentEnergyConsumed, chargeDuration);
publish_ack_message(taskId, true, ("Charging stopped. Duration: " + String(chargeDuration) + "s").c_str(), previousSessionId.c_str());
publish_status_update(false, nullptr, nullptr, nullptr, nullptr, nullptr);
}
// Add other commandType handling here if needed, e.g., "QUERY_STATUS"
@@ -225,7 +225,7 @@ void callback(char *topic, byte *payload, unsigned int length) {
// }
else {
Serial.println("未知指令 commandType: " + String(cmdType));
publish_ack_message(taskId, "未知指令", false, ("Unknown commandType: " + String(cmdType)).c_str());
publish_ack_message(taskId, false, ("Unknown commandType: " + String(cmdType)).c_str(), nullptr);
}
Serial.println("-----------------------");
}
@@ -254,7 +254,13 @@ void publish_status_update(bool isAckOrTaskUpdate, const char* ackTaskId, const
doc["robotUid"] = spotUid;
if (isAckOrTaskUpdate) {
if (ackTaskId) doc["taskId"] = ackTaskId;
if (ackTaskId) {
// 关键修复:同时提供 taskId 和 activeTaskId 字段
// taskId 用于 robot_task 表的状态更新
// activeTaskId 用于 charging_session 的业务流程推进
doc["taskId"] = ackTaskId;
doc["activeTaskId"] = ackTaskId;
}
if (ackStatus) doc["status"] = ackStatus;
if (ackMessage) doc["message"] = ackMessage;
// 根据用户要求ACK中不发送errorCode
@@ -323,30 +329,18 @@ void publish_heartbeat() {
lastHeartbeatTime = millis();
}
// 新增ACK消息发布函数以符合后端期望的格式
void publish_ack_message(long taskId, const char* commandAckStr, bool success, const char* message, float energyKwh = -1.0f, int durationSeconds = -1) {
StaticJsonDocument<256> doc; // 调整大小以适应所有字段
doc["robotUid"] = spotUid;
doc["command_ack"] = commandAckStr; // 指令的中文描述
doc["task_id"] = taskId; // 任务ID (数字类型)
doc["success"] = success; // 成功状态 (布尔类型)
if (message && strlen(message) > 0) {
doc["message"] = message;
// Simplified ACK message function
void publish_ack_message(const char* taskId, bool success, const char* message, const char* contextInfo) {
if (!taskId || strlen(taskId) == 0) {
Serial.println("无法发送ACK: taskId 为空");
return;
}
// 针对 STOP_CHARGE 指令的额外字段
if (strcmp(commandAckStr, "停止充电") == 0) {
if (energyKwh >= 0) {
doc["energy_kwh"] = energyKwh;
}
if (durationSeconds >= 0) {
doc["duration_s"] = durationSeconds;
}
}
publish_message(topic_uplink_to_backend, doc, "ACK");
// Use the main publish_status_update function formatted as an ACK
// For contextInfo, we can pass spotId if relevant, or sessionId if that's what backend expects for ACKs.
// The 'true' indicates it's an ACK.
// The ackErrorCode field in publish_status_update will be set to "SUCCESS_ACK" or "FAILURE_ACK"
// 根据用户要求ACK中的errorCode也暂时简化或移除。如果保留确保含义清晰。
publish_status_update(true, taskId, success ? "COMPLETED" : "FAILED", message, nullptr, contextInfo);
}
void setup() {