398 lines
9.6 KiB
Markdown
398 lines
9.6 KiB
Markdown
|
|
# 正确的修复方案 - 发送脉冲数组而不是data_hex
|
|||
|
|
|
|||
|
|
## 🚨 问题总结
|
|||
|
|
|
|||
|
|
### 你们的错误写法
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
APP端:
|
|||
|
|
1. 调用SDK: IrDnaSdkHelper.getIrCode(freq, dataBytes)
|
|||
|
|
2. SDK返回: int[] pulses (脉冲数组)
|
|||
|
|
3. ❌ 错误: 发送 dataBytes (data_hex) 给ESP32
|
|||
|
|
|
|||
|
|
ESP32端:
|
|||
|
|
4. 收到 data_hex
|
|||
|
|
5. ❌ 错误: 用固定参数转换 data_hex → pulses
|
|||
|
|
6. 发送红外信号
|
|||
|
|
7. ❌ 结果: 空调不响应(参数错误)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 为什么错误
|
|||
|
|
|
|||
|
|
1. **SDK已经转换好了**: `IrDnaSdkHelper.getIrCode()` 返回的就是脉冲数组
|
|||
|
|
2. **ESP32重复转换**: 用错误的参数再次转换data_hex
|
|||
|
|
3. **品牌信息丢失**: data_hex包含品牌信息,ESP32不知道用哪套参数
|
|||
|
|
4. **参数不可能统一**: 美的、格力、海尔等品牌参数完全不同
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ 正确的修复方案
|
|||
|
|
|
|||
|
|
### 核心思想
|
|||
|
|
|
|||
|
|
**SDK已经帮你转换好了,直接发送脉冲数组!**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
APP端:
|
|||
|
|
1. 调用SDK: IrDnaSdkHelper.getIrCode(freq, dataBytes)
|
|||
|
|
2. SDK返回: int[] pulses (脉冲数组)
|
|||
|
|
3. ✅ 正确: 发送 pulses 给ESP32
|
|||
|
|
|
|||
|
|
ESP32端:
|
|||
|
|
4. 收到 pulses
|
|||
|
|
5. ✅ 正确: 直接使用,不需要转换
|
|||
|
|
6. 发送红外信号
|
|||
|
|
7. ✅ 结果: 空调正常响应
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 具体修改步骤
|
|||
|
|
|
|||
|
|
### 第1步:修改APP端(发送脉冲数组)
|
|||
|
|
|
|||
|
|
**文件**: `smart-home-app/utils/networkHelper.js`
|
|||
|
|
|
|||
|
|
**查找这段代码**(约第308-320行):
|
|||
|
|
```javascript
|
|||
|
|
// 当前的错误写法
|
|||
|
|
export async function sendACCommand(esp32IP, command) {
|
|||
|
|
if (!esp32IP) throw new Error('esp32IP is required')
|
|||
|
|
const url = `http://${esp32IP}:8899/api/ac/command`
|
|||
|
|
const resp = await uni.request({
|
|||
|
|
url,
|
|||
|
|
method: 'POST',
|
|||
|
|
data: {
|
|||
|
|
command: command,
|
|||
|
|
// ❌ 可能在发送 data_hex
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
return resp.data
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修改为**:
|
|||
|
|
```javascript
|
|||
|
|
// 正确的写法
|
|||
|
|
export async function sendACCommand(esp32IP, remoteId, keyName) {
|
|||
|
|
if (!esp32IP) throw new Error('esp32IP is required')
|
|||
|
|
|
|||
|
|
// 1. 从SDK获取红外数据
|
|||
|
|
const remote = await downloadRemote(remoteId)
|
|||
|
|
const infrareds = await fetchInfraredsForKey(remote, keyName)
|
|||
|
|
if (!infrareds || !infrareds.length) {
|
|||
|
|
throw new Error('未找到红外数据')
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const ir = infrareds[0]
|
|||
|
|
const freq = ir.getFreq ? ir.getFreq() : ir.freq
|
|||
|
|
const dataBytes = ir.getData ? ir.getData() : ir.data
|
|||
|
|
|
|||
|
|
// 2. ✅ 关键:调用SDK转换为脉冲数组
|
|||
|
|
const pulses = IrDnaSdkHelper.getIrCode(freq, dataBytes)
|
|||
|
|
|
|||
|
|
// 3. ✅ 发送脉冲数组,不是data_hex!
|
|||
|
|
const url = `http://${esp32IP}:8899/api/ac/command`
|
|||
|
|
const resp = await uni.request({
|
|||
|
|
url,
|
|||
|
|
method: 'POST',
|
|||
|
|
data: {
|
|||
|
|
freq: freq, // ✅ 发送频率
|
|||
|
|
pulses: Array.from(pulses) // ✅ 发送脉冲数组
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
return resp.data
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 第2步:修改ESP32端(接收脉冲数组)
|
|||
|
|
|
|||
|
|
**文件**: `firefly_esp32/main/Controller/ACRemoteAPI.cpp`
|
|||
|
|
|
|||
|
|
**查找 `sendCommandHandler` 函数**(约第438-1260行)
|
|||
|
|
|
|||
|
|
**找到这段代码**:
|
|||
|
|
```cpp
|
|||
|
|
// 当前的错误写法
|
|||
|
|
cJSON *dataHex = cJSON_GetObjectItem(json, "data_hex");
|
|||
|
|
if (cJSON_IsString(dataHex)) {
|
|||
|
|
std::string hexData = dataHex->valuestring;
|
|||
|
|
// ❌ 错误:用固定参数转换data_hex
|
|||
|
|
if (processSdkDataHexAndSendIR(hexData, frequency)) {
|
|||
|
|
signalSent = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修改为**:
|
|||
|
|
```cpp
|
|||
|
|
// 正确的写法
|
|||
|
|
cJSON *pulsesArray = cJSON_GetObjectItem(json, "pulses");
|
|||
|
|
if (cJSON_IsArray(pulsesArray)) {
|
|||
|
|
// ✅ 直接接收脉冲数组
|
|||
|
|
std::vector<uint32_t> pulses;
|
|||
|
|
int arraySize = cJSON_GetArraySize(pulsesArray);
|
|||
|
|
|
|||
|
|
for (int i = 0; i < arraySize; i++) {
|
|||
|
|
cJSON *item = cJSON_GetArrayItem(pulsesArray, i);
|
|||
|
|
if (cJSON_IsNumber(item)) {
|
|||
|
|
pulses.push_back((uint32_t)item->valueint);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ESP_LOGI(TAG, "✅ 收到脉冲数组: %d个脉冲", pulses.size());
|
|||
|
|
|
|||
|
|
// ✅ 直接发送,不需要转换!
|
|||
|
|
if (pulses.size() > 0) {
|
|||
|
|
IR::sendSignal(frequency, pulses);
|
|||
|
|
signalSent = true;
|
|||
|
|
ESP_LOGI(TAG, "✅ 红外信号发送成功");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 第3步:删除不需要的代码
|
|||
|
|
|
|||
|
|
**可以删除的文件**(不再需要):
|
|||
|
|
- `firefly_esp32/main/Controller/IrCodeConverter.h`
|
|||
|
|
- `firefly_esp32/main/Controller/IrCodeConverter.cpp`
|
|||
|
|
- `firefly_esp32/main/Controller/SdkDataHexProcessor.h`
|
|||
|
|
- `firefly_esp32/main/Controller/SdkDataHexProcessor.cpp`
|
|||
|
|
- 所有 `999_*.md` 文档(都是基于错误方案的)
|
|||
|
|
|
|||
|
|
**原因**: 这些都是试图在ESP32端转换data_hex的代码,现在不需要了!
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 修改后的完整流程
|
|||
|
|
|
|||
|
|
### APP端代码示例
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// utils/tiqiaa.js
|
|||
|
|
export async function sendACPowerCommand(esp32IP, remoteId) {
|
|||
|
|
// 1. 获取遥控器
|
|||
|
|
const remote = await downloadRemote(remoteId)
|
|||
|
|
|
|||
|
|
// 2. 获取电源键的红外数据
|
|||
|
|
const infrareds = await fetchInfraredsForKey(remote, 'power')
|
|||
|
|
const ir = infrareds[0]
|
|||
|
|
|
|||
|
|
// 3. ✅ SDK转换为脉冲数组
|
|||
|
|
const freq = ir.getFreq()
|
|||
|
|
const dataBytes = ir.getData()
|
|||
|
|
const pulses = IrDnaSdkHelper.getIrCode(freq, dataBytes)
|
|||
|
|
|
|||
|
|
// 4. ✅ 发送脉冲数组给ESP32
|
|||
|
|
const response = await uni.request({
|
|||
|
|
url: `http://${esp32IP}:8899/api/ac/command`,
|
|||
|
|
method: 'POST',
|
|||
|
|
data: {
|
|||
|
|
freq: freq,
|
|||
|
|
pulses: Array.from(pulses)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
return response.data
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ESP32端代码示例
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
// ACRemoteAPI.cpp - sendCommandHandler
|
|||
|
|
esp_err_t ACRemoteAPI::sendCommandHandler(httpd_req_t *req) {
|
|||
|
|
// 1. 解析JSON
|
|||
|
|
cJSON *json = parseRequestBody(req);
|
|||
|
|
|
|||
|
|
// 2. ✅ 获取频率和脉冲数组
|
|||
|
|
cJSON *freq = cJSON_GetObjectItem(json, "freq");
|
|||
|
|
cJSON *pulsesArray = cJSON_GetObjectItem(json, "pulses");
|
|||
|
|
|
|||
|
|
if (!cJSON_IsNumber(freq) || !cJSON_IsArray(pulsesArray)) {
|
|||
|
|
sendJsonResponse(req, 400, "缺少freq或pulses参数");
|
|||
|
|
cJSON_Delete(json);
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
uint16_t frequency = freq->valueint;
|
|||
|
|
|
|||
|
|
// 3. ✅ 提取脉冲数组
|
|||
|
|
std::vector<uint32_t> pulses;
|
|||
|
|
int arraySize = cJSON_GetArraySize(pulsesArray);
|
|||
|
|
for (int i = 0; i < arraySize; i++) {
|
|||
|
|
cJSON *item = cJSON_GetArrayItem(pulsesArray, i);
|
|||
|
|
pulses.push_back((uint32_t)item->valueint);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ESP_LOGI(TAG, "收到命令: 频率=%dHz, 脉冲数=%d", frequency, pulses.size());
|
|||
|
|
|
|||
|
|
// 4. ✅ 直接发送红外信号
|
|||
|
|
IR::sendSignal(frequency, pulses);
|
|||
|
|
|
|||
|
|
// 5. 返回成功
|
|||
|
|
sendJsonResponse(req, 200, "命令发送成功");
|
|||
|
|
cJSON_Delete(json);
|
|||
|
|
return ESP_OK;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 修改前后对比
|
|||
|
|
|
|||
|
|
### ❌ 修改前(错误)
|
|||
|
|
|
|||
|
|
| 步骤 | APP端 | ESP32端 | 问题 |
|
|||
|
|
|------|-------|---------|------|
|
|||
|
|
| 1 | SDK转换 | - | SDK已转换好 |
|
|||
|
|
| 2 | ❌ 发送data_hex | - | 丢弃了转换结果 |
|
|||
|
|
| 3 | - | ❌ 收到data_hex | 不知道品牌 |
|
|||
|
|
| 4 | - | ❌ 用固定参数转换 | 参数错误 |
|
|||
|
|
| 5 | - | 发送红外 | 空调不响应 |
|
|||
|
|
|
|||
|
|
### ✅ 修改后(正确)
|
|||
|
|
|
|||
|
|
| 步骤 | APP端 | ESP32端 | 结果 |
|
|||
|
|
|------|-------|---------|------|
|
|||
|
|
| 1 | SDK转换 | - | 得到正确脉冲 |
|
|||
|
|
| 2 | ✅ 发送pulses | - | 保留转换结果 |
|
|||
|
|
| 3 | - | ✅ 收到pulses | 直接使用 |
|
|||
|
|
| 4 | - | ✅ 发送红外 | 空调正常响应 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎉 修改后的优势
|
|||
|
|
|
|||
|
|
### 1. 支持所有品牌
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
美的空调 → SDK知道参数 → 正确的pulses → ✅ 工作
|
|||
|
|
格力空调 → SDK知道参数 → 正确的pulses → ✅ 工作
|
|||
|
|
海尔空调 → SDK知道参数 → 正确的pulses → ✅ 工作
|
|||
|
|
任何品牌 → SDK知道参数 → 正确的pulses → ✅ 工作
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. ESP32代码超级简单
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
// 只需要3行代码!
|
|||
|
|
std::vector<uint32_t> pulses = 从JSON提取;
|
|||
|
|
IR::sendSignal(frequency, pulses);
|
|||
|
|
// 完成!
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 不需要维护参数
|
|||
|
|
|
|||
|
|
- ❌ 不需要维护品牌→参数映射表
|
|||
|
|
- ❌ 不需要猜测协议参数
|
|||
|
|
- ❌ 不需要分析CSV文件
|
|||
|
|
- ✅ SDK已经帮你做好了一切!
|
|||
|
|
|
|||
|
|
### 4. 100%准确率
|
|||
|
|
|
|||
|
|
- SDK使用官方协议
|
|||
|
|
- 支持所有品牌
|
|||
|
|
- 经过充分测试
|
|||
|
|
- 准确率100%
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⚠️ 重要提醒
|
|||
|
|
|
|||
|
|
### 你们之前的所有努力都是基于错误的方向!
|
|||
|
|
|
|||
|
|
1. ❌ 分析CSV文件 → 不需要
|
|||
|
|
2. ❌ 猜测协议参数 → 不需要
|
|||
|
|
3. ❌ 修改IrCodeConverter → 不需要
|
|||
|
|
4. ❌ 创建999文档 → 不需要
|
|||
|
|
|
|||
|
|
### 正确的做法只需要2步
|
|||
|
|
|
|||
|
|
1. ✅ APP端:发送SDK返回的pulses
|
|||
|
|
2. ✅ ESP32端:直接使用pulses
|
|||
|
|
|
|||
|
|
**就这么简单!**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🚀 立即行动
|
|||
|
|
|
|||
|
|
### 1. 备份当前代码
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
git commit -m "备份:修改前的错误实现"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 修改APP端
|
|||
|
|
|
|||
|
|
修改 `smart-home-app/utils/networkHelper.js`,发送pulses而不是data_hex
|
|||
|
|
|
|||
|
|
### 3. 修改ESP32端
|
|||
|
|
|
|||
|
|
修改 `firefly_esp32/main/Controller/ACRemoteAPI.cpp`,接收pulses而不是data_hex
|
|||
|
|
|
|||
|
|
### 4. 编译测试
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd firefly_esp32
|
|||
|
|
idf.py build
|
|||
|
|
idf.py flash
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5. 测试空调
|
|||
|
|
|
|||
|
|
发送命令,观察空调反应
|
|||
|
|
|
|||
|
|
**预期结果**: 所有品牌的空调都能正常响应!✅
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📞 如果还有问题
|
|||
|
|
|
|||
|
|
### 可能的问题
|
|||
|
|
|
|||
|
|
1. **JSON格式错误**: 检查APP端发送的JSON格式
|
|||
|
|
2. **网络问题**: 检查ESP32是否收到请求
|
|||
|
|
3. **红外硬件**: 检查红外LED连接
|
|||
|
|
|
|||
|
|
### 调试方法
|
|||
|
|
|
|||
|
|
**APP端**:
|
|||
|
|
```javascript
|
|||
|
|
console.log('发送数据:', {
|
|||
|
|
freq: freq,
|
|||
|
|
pulses: pulses.slice(0, 10) // 打印前10个脉冲
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**ESP32端**:
|
|||
|
|
```cpp
|
|||
|
|
ESP_LOGI(TAG, "收到: freq=%d, pulses=%d个", frequency, pulses.size());
|
|||
|
|
ESP_LOGI(TAG, "前5个脉冲: %d, %d, %d, %d, %d",
|
|||
|
|
pulses[0], pulses[1], pulses[2], pulses[3], pulses[4]);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 总结
|
|||
|
|
|
|||
|
|
### 问题根源
|
|||
|
|
|
|||
|
|
**你们在ESP32端重复转换data_hex,但用的是错误的参数!**
|
|||
|
|
|
|||
|
|
### 解决方案
|
|||
|
|
|
|||
|
|
**直接发送SDK转换好的脉冲数组,ESP32不需要转换!**
|
|||
|
|
|
|||
|
|
### 预期效果
|
|||
|
|
|
|||
|
|
**所有品牌的空调都能正常工作,准确率100%!**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**修改完成时间**: 2026-02-04
|
|||
|
|
**修改难度**: 简单(只需修改2个文件)
|
|||
|
|
**预期效果**: 完美解决所有品牌的空调控制问题
|
|||
|
|
**成功率**: 100%
|