Files

HomeControl 页面功能说明

概述

HomeControl 页面是用于控制 ESP32 设备的核心页面,支持 MQTT 消息通信、设备状态监控和控制指令发送等功能。

核心功能

1. MQTT 消息通信

  • 自动连接 MQTT 服务器
  • 订阅设备主题,接收设备消息
  • 处理设备上报的传感器数据
  • 发送控制指令到设备

2. 设备数据管理

  • 存储和解析 ESP32 设备数据
  • 实时更新设备状态
  • 提取特定设备信息(如温度、湿度、空气质量等)

3. 控制指令发送

支持发送控制指令到 ESP32 设备,并接收设备响应。

基本用法

// 最简单的用法 - 只控制灯光
this.sendControlCommand({
  light: "on",
});

// 控制多个设备
this.sendControlCommand({
  light: "on",
  fan: "off",
  curtain: "open",
});

高级用法 - 带配置参数

// 控制灯光并设置亮度
this.sendControlCommand({ light: "on" }, { brightness: 80 });

高级用法 - 带回调函数

// 发送控制并处理响应
this.sendControlCommand({ light: "on" }, null, (response) => {
  console.log("控制结果:", response);
  if (response.success) {
    console.log("控制成功");
  } else {
    console.log("控制失败:", response.message);
  }
});

完整用法 - 所有参数

this.sendControlCommand(
  { light: "on", fan: "off" }, // 控制参数
  { brightness: 80 }, // 配置参数
  (response) => {
    // 回调函数
    console.log("响应:", response);
  }
);

4. 请求-响应匹配机制

系统实现了完整的请求追踪和响应匹配功能:

工作原理

  1. 每个控制指令都会生成唯一的request_id
  2. 发送指令时自动保存请求信息到pendingRequests
  3. 接收到 ESP32 响应后,通过request_id匹配原始请求
  4. 根据响应状态自动显示提示信息
  5. 如果有回调函数,自动调用并传递响应数据
  6. 5 秒后自动清理已完成的请求

请求格式

{
  "type": "control_command",
  "device_id": "esp32_bedroom_001",
  "device_type": "bedroom_controller",
  "timestamp": 1768495346335,
  "message_type": "control_request",
  "request_id": "req_1768495346336_n3bhf90pu",
  "data": {
    "controls": {
      "light": "on"
    }
  }
}

响应格式

{
  "type": "control_response",
  "device_id": "esp32_bedroom_001",
  "device_type": "bedroom_controller",
  "timestamp": 1768495550428,
  "message_type": "control_result",
  "request_id": "req_1768495550428_d47w3fu8j",
  "data": {
    "result": {
      "status": "success",
      "message": "Control executed successfully"
    }
  }
}

响应状态说明

  • success: 控制指令执行成功
  • error: 控制指令执行出错
  • failed: 控制指令执行失败

数据结构

页面数据

data: {
  receivedMessages: [],      // 存储接收到的消息
  esp32Device: null,         // 存储ESP32设备数据
  deviceOnline: false,       // 设备在线状态
  lastUpdateTime: null,      // 最后更新时间
  pendingRequests: {}        // 存储待处理的控制请求
}

ESP32 设备数据结构

{
  type: "device_message",
  deviceId: "esp32_bedroom_001",
  deviceType: "bedroom_controller",
  timestamp: 1768495346335,
  messageType: "telemetry_update",
  requestId: null,
  statusCode: null,
  statusMessage: null,
  state: {
    online: true,
    // 其他状态信息
  },
  telemetry: {
    temperature: 25.5,
    humidity: 60,
    air_quality: 85,
    // 其他遥测数据
  },
  controlResult: null,
  rawData: {...}
}

API 说明

sendControlCommand(controls, config, callback)

发送控制指令到 ESP32 设备

参数:

  • controls (Object): 控制参数对象,例如 { light: "on" }
  • config (Object, 可选): 配置参数对象,例如 { brightness: 80 }
  • callback (Function, 可选): 响应回调函数

返回值:

  • 成功: 返回 request_id (字符串)
  • 失败: 返回 null

示例:

const requestId = this.sendControlCommand({ light: "on" }, null, (response) => {
  if (response.success) {
    console.log("控制成功");
  }
});

handleControlResponse(response)

处理 ESP32 设备的控制响应

参数:

  • response (Object): 响应消息对象

功能:

  • 通过 request_id 匹配原始请求
  • 解析响应状态
  • 显示提示信息
  • 调用回调函数(如果有)
  • 自动清理已完成的请求

parseESP32Data(message)

解析 ESP32 设备上传的数据

参数:

  • message (Object|string): 接收到的消息内容

返回值:

  • 成功: 返回解析后的数据对象
  • 失败: 返回 null

extractESP32Info(path)

从解析后的 ESP32 数据中提取特定信息

参数:

  • path (string): 数据路径,使用点号分隔,例如 "telemetry.air_quality"

返回值:

  • 成功: 返回提取的值
  • 失败: 返回 null

示例:

// 提取空气质量
const airQuality = this.extractESP32Info("telemetry.air_quality");

// 提取温度
const temperature = this.extractESP32Info("telemetry.temperature");

// 获取所有数据
const allData = this.extractESP32Info();

注意事项

  1. 回调函数是可选的

    • 不使用回调时,系统会自动显示 Toast 提示
    • 使用回调时,可以自定义处理响应逻辑
  2. 请求自动清理

    • 已完成的请求会在 5 秒后自动清理
    • 发送失败的请求会立即移除
  3. 错误处理

    • 所有函数都包含错误处理
    • 错误信息会输出到控制台
    • 关键错误会显示 Toast 提示
  4. MQTT 连接

    • 使用前确保 MQTT 已连接
    • 未连接时会显示提示信息
    • 需要正确配置 MQTT 主题

ESP32 端实现参考

接收控制指令

void handleControlCommand(String payload) {
  DynamicJsonDocument doc(1024);
  deserializeJson(doc, payload);

  String requestId = doc["request_id"];
  String lightControl = doc["data"]["controls"]["light"];

  // 执行控制操作
  if (lightControl == "on") {
    digitalWrite(LED_PIN, HIGH);
  } else if (lightControl == "off") {
    digitalWrite(LED_PIN, LOW);
  }

  // 发送响应
  sendControlResponse(requestId, "success", "Control executed successfully");
}

发送控制响应

void sendControlResponse(String requestId, String status, String message) {
  DynamicJsonDocument doc(1024);

  doc["type"] = "control_response";
  doc["device_id"] = deviceId;
  doc["device_type"] = "bedroom_controller";
  doc["timestamp"] = millis();
  doc["message_type"] = "control_result";
  doc["request_id"] = requestId;
  doc["data"]["result"]["status"] = status;
  doc["data"]["result"]["message"] = message;

  String response;
  serializeJson(doc, response);
  client.publish(responseTopic, response.c_str());
}

更新日志