Files
iris-kit/esp8285/src/ir_drv_ctrl.cpp

322 lines
9.7 KiB
C++
Raw Normal View History

2022-01-12 17:24:18 +08:00
/**
*
2024-02-11 12:42:50 +08:00
* Copyright (c) 2020-2024 IRbaby-IRext
2022-01-12 17:24:18 +08:00
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <LittleFS.h>
#include "defines.h"
2024-02-11 12:42:50 +08:00
#include "global.h"
#include "serials.h"
#include "user_settings.h"
#include "iris_client.h"
2024-02-11 12:42:50 +08:00
#include "http_client.h"
#include "utils.h"
2024-10-23 17:48:02 +08:00
#include "ir_drv_ctrl.h"
2022-01-12 17:24:18 +08:00
2022-10-11 20:08:44 +08:00
#define IR_SERIES_MAX (1024)
#define IR_END_CODE (10000)
2024-10-29 17:10:39 +08:00
// external variable declaratoins
extern iris_kit_status_t g_iris_kit_status;
// public variable definitions
2024-11-11 18:34:03 +08:00
decode_results g_recv_results;
String g_recv_ir_code_str = "";
2024-10-29 17:10:39 +08:00
// private variable definitions
2022-01-12 17:24:18 +08:00
static IRsend * ir_send = nullptr;
static IRrecv * ir_recv = nullptr;
2024-10-29 17:10:39 +08:00
static const uint8_t k_timeout = 50;
// as this program is a special purpose capture/decoder, let us use a larger
// than normal buffer so we can handle Air Conditioner remote codes
static const uint16_t k_capture_buffer_size = IR_SERIES_MAX;
2022-01-12 17:24:18 +08:00
2024-10-23 17:48:02 +08:00
2024-10-29 17:10:39 +08:00
// public function definitions
2022-01-12 17:24:18 +08:00
bool sendIR(String file_name) {
String save_path = SAVE_PATH + file_name;
if (LittleFS.exists(save_path)) {
File cache = LittleFS.open(save_path, "r");
if (!cache) {
2024-10-25 17:33:38 +08:00
ERRORF("Failed to open %s\n", save_path.c_str());
2022-01-12 17:24:18 +08:00
return false;
}
Serial.println();
2022-10-11 20:08:44 +08:00
uint16_t *data_buffer = (uint16_t *)malloc(sizeof(uint16_t) * IR_SERIES_MAX);
2022-01-12 17:24:18 +08:00
uint16_t length = cache.size() / 2;
2022-10-11 20:08:44 +08:00
memset(data_buffer, 0x0, IR_SERIES_MAX);
2022-01-12 17:24:18 +08:00
cache.readBytes((char *)data_buffer, cache.size());
ir_recv->disableIRIn();
ir_send->sendRaw(data_buffer, length, 38);
free(data_buffer);
cache.close();
return true;
}
return false;
}
2022-10-11 20:08:44 +08:00
bool emitIR(String timing) {
char* parts[IR_SERIES_MAX];
uint16_t series[IR_SERIES_MAX + 1] = { 0 };
int parts_num = 0;
int i = 0;
parts_num = split_string(timing, parts, ",");
if (parts_num > 0) {
for (i = 0; i < parts_num; i++) {
series[i] = (uint16_t) atoi(parts[i]);
}
series[i] = (uint16_t) IR_END_CODE;
ir_recv->disableIRIn();
2022-11-07 13:45:58 +08:00
INFOF("IR send raw : %d\n", parts_num);
2022-10-11 20:08:44 +08:00
ir_send->sendRaw(series, parts_num + 1, 38);
}
return true;
}
bool sendCommand(String file_name, int key) {
String save_path = SAVE_PATH;
save_path += file_name;
if (LittleFS.exists(save_path)) {
File cache = LittleFS.open(save_path, "r");
if (cache) {
UINT16 content_size = cache.size();
2024-10-25 17:33:38 +08:00
INFOF("Send command, content size = %d\n", content_size);
2022-10-11 20:08:44 +08:00
if (content_size != 0) {
UINT8 *content = (UINT8 *)malloc(content_size * sizeof(UINT8));
cache.seek(0L, fs::SeekSet);
cache.readBytes((char *)content, content_size);
ir_binary_open(2, 1, content, content_size);
UINT16 *user_data = (UINT16 *)malloc(IR_SERIES_MAX * sizeof(UINT16));
UINT16 data_length = ir_decode(0, user_data, NULL, FALSE);
2024-10-25 17:33:38 +08:00
INFOF("Send command, data_length = %d\n", data_length);
2022-10-11 20:08:44 +08:00
if (LOG_DEBUG) {
for (int i = 0; i < data_length; i++)
Serial.printf("%d ", *(user_data + i));
Serial.println();
}
ir_recv->disableIRIn();
ir_send->sendRaw(user_data, data_length, 38);
ir_close();
free(user_data);
free(content);
} else
ERRORF("Open %s is empty\n", save_path.c_str());
}
cache.close();
}
return true;
}
2022-01-12 17:24:18 +08:00
void sendStatus(String file, t_remote_ac_status status) {
String save_path = SAVE_PATH + file;
2022-03-13 17:49:22 +08:00
String url = String(DOWNLOAD_PREFIX) + file + String(DOWNLOAD_SUFFIX);
2022-01-12 17:24:18 +08:00
if (!LittleFS.exists(save_path)) {
2022-03-13 17:49:22 +08:00
downLoadFile(url, file, SAVE_PATH);
2022-01-12 17:24:18 +08:00
}
if (LittleFS.exists(save_path)) {
File cache = LittleFS.open(save_path, "r");
if (cache) {
UINT16 content_size = cache.size();
2024-10-25 17:33:38 +08:00
INFOF("Send status, content size = %d\n", content_size);
2022-01-12 17:24:18 +08:00
if (content_size != 0) {
UINT8 *content = (UINT8 *)malloc(content_size * sizeof(UINT8));
cache.seek(0L, fs::SeekSet);
cache.readBytes((char *)content, content_size);
ir_binary_open(REMOTE_CATEGORY_AC, 1, content, content_size);
2022-10-11 20:08:44 +08:00
UINT16 *user_data = (UINT16 *)malloc(IR_SERIES_MAX * sizeof(UINT16));
2022-01-12 17:24:18 +08:00
UINT16 data_length = ir_decode(0, user_data, &status, FALSE);
2024-10-25 17:33:38 +08:00
INFOF("Send status, data_length = %d\n", data_length);
2022-01-12 17:24:18 +08:00
ir_recv->disableIRIn();
ir_send->sendRaw(user_data, data_length, 38);
ir_close();
free(user_data);
free(content);
saveACStatus(file, status);
} else
ERRORF("Open %s is empty\n", save_path.c_str());
}
cache.close();
}
}
void prepareStudyIR() {
2024-10-25 17:33:38 +08:00
removeReceived();
enableIRIn();
2024-10-23 17:48:02 +08:00
}
void cancelStudyIR() {
2024-10-23 17:48:02 +08:00
disableIRIn();
}
int completeStudyIR(String &ir_data) {
2024-10-23 17:48:02 +08:00
// called unsolicited
disableIRIn();
2024-10-29 17:10:39 +08:00
return loadReceived(ir_data);
2024-10-23 17:48:02 +08:00
}
2022-01-12 17:24:18 +08:00
void recvIR() {
2024-11-11 18:34:03 +08:00
if (ir_recv->decode(&g_recv_results)) {
INFOF("Recv IR, raw length = %d\n", g_recv_results.rawlen - 1);
2022-01-12 17:24:18 +08:00
String raw_data;
2024-11-11 18:34:03 +08:00
for (int i = 1; i < g_recv_results.rawlen; i++) {
raw_data += String(*(g_recv_results.rawbuf + i) * kRawTick) + ",";
2022-01-12 17:24:18 +08:00
}
ir_recv->resume();
2024-10-25 17:33:38 +08:00
INFOLN(raw_data.c_str());
2024-11-11 18:34:03 +08:00
saveReceived(g_recv_results);
2024-10-29 17:10:39 +08:00
processStatusChange(IRIS_KIT_STATUS_STUDIED,
g_iris_kit_status.console_id,
g_iris_kit_status.remote_index,
2024-10-29 17:10:39 +08:00
g_iris_kit_status.key_id,
g_iris_kit_status.key_name);
2022-01-12 17:24:18 +08:00
}
}
2024-10-25 17:33:38 +08:00
bool saveReceived(decode_results& results) {
2022-01-12 17:24:18 +08:00
String save_path = SAVE_PATH;
2024-10-25 17:33:38 +08:00
String file_name = "";
2024-11-11 18:34:03 +08:00
uint16_t max_time_slice = 0;
char time_slice[16] = { 0 };
2022-01-12 17:24:18 +08:00
2024-10-29 17:10:39 +08:00
if (g_iris_kit_status.remote_index.isEmpty()) {
2024-10-25 17:33:38 +08:00
return false;
}
2024-11-11 18:34:03 +08:00
#if defined STORE_RECEIVED_TO_TMP_FILE
2024-10-29 17:10:39 +08:00
file_name = "ir_" + g_iris_kit_status.remote_index + RECEIVED_SUFFIX;
2024-10-25 17:33:38 +08:00
save_path += file_name;
INFOF("Save received code to: %s\n", save_path.c_str());
2022-01-12 17:24:18 +08:00
File cache = LittleFS.open(save_path, "w");
if (!cache) {
2024-10-25 17:33:38 +08:00
ERRORF("Failed to create file\n");
2022-01-12 17:24:18 +08:00
return false;
}
2024-11-11 18:34:03 +08:00
#endif
for (size_t i = 0; i < results.rawlen; i++) {
memset(time_slice, 0, sizeof(time_slice));
if (*(results.rawbuf + i) > max_time_slice) {
max_time_slice = *(results.rawbuf + i);
}
snprintf(time_slice, 15, "%d", *(results.rawbuf + i));
g_recv_ir_code_str += String(time_slice) + ",";
}
// append tail code
max_time_slice = 2 * max_time_slice;
snprintf(time_slice, 15, "%d", max_time_slice);
g_recv_ir_code_str += String(time_slice);
#if defined STORE_RECEIVED_TO_TMP_FILE
cache.write(g_recv_ir_code_str.c_str(), g_recv_ir_code_str.length());
2022-01-12 17:24:18 +08:00
cache.close();
2024-11-11 18:34:03 +08:00
#endif
2022-01-12 17:24:18 +08:00
return true;
}
2024-10-25 17:33:38 +08:00
bool removeReceived() {
String save_path = SAVE_PATH;
String file_name = "";
2024-10-29 17:10:39 +08:00
if (g_iris_kit_status.remote_index.isEmpty()) {
2024-10-25 17:33:38 +08:00
return false;
}
2024-11-11 18:34:03 +08:00
#if defined STORE_RECEIVED_TO_TMP_FILE
2024-10-29 17:10:39 +08:00
file_name = "ir_" + g_iris_kit_status.remote_index + RECEIVED_SUFFIX;
2024-10-25 17:33:38 +08:00
save_path += file_name;
INFOF("Delete received code file: %s\n", save_path.c_str());
LittleFS.remove(save_path);
2024-11-11 18:34:03 +08:00
#endif
2024-10-25 17:33:38 +08:00
return true;
}
2024-10-29 17:10:39 +08:00
int loadReceived(String &ir_data) {
String save_path = SAVE_PATH;
String file_name = "";
if (g_iris_kit_status.remote_index.isEmpty()) {
return -1;
}
2024-11-11 18:34:03 +08:00
#if defined STORE_RECEIVED_TO_TMP_FILE
2024-10-29 17:10:39 +08:00
file_name = "ir_" + g_iris_kit_status.remote_index + RECEIVED_SUFFIX;
save_path += file_name;
INFOF("Load received code from: %s\n", save_path.c_str());
File cache = LittleFS.open(save_path, "r");
if (!cache) {
ERRORF("Failed to open file\n");
return false;
}
ir_data = cache.readString();
cache.close();
2024-11-11 18:34:03 +08:00
#else
ir_data = g_recv_ir_code_str;
#endif
2024-10-29 17:10:39 +08:00
return ir_data.length();
}
2022-01-12 17:24:18 +08:00
void initAC(String file) {
ACStatus[file]["power"] = 0;
ACStatus[file]["temperature"] = 8;
ACStatus[file]["mode"] = 2;
ACStatus[file]["swing"] = 0;
ACStatus[file]["speed"] = 0;
}
void loadIRPin(uint8_t send_pin, uint8_t recv_pin) {
if (ir_send != nullptr) {
delete ir_send;
}
if (ir_recv != nullptr) {
delete ir_recv;
}
ir_send = new IRsend(send_pin);
2024-10-25 17:33:38 +08:00
INFOF("Load IR send pin at %d\n", send_pin);
2022-01-12 17:24:18 +08:00
ir_send->begin();
2022-10-11 20:08:44 +08:00
ir_recv = new IRrecv(recv_pin, k_capture_buffer_size, k_timeout, true);
2024-10-23 17:48:02 +08:00
disableIRIn();
2022-01-12 17:24:18 +08:00
}
2024-10-23 17:48:02 +08:00
void disableIRIn() {
2022-01-12 17:24:18 +08:00
ir_recv->disableIRIn();
}
2024-10-23 17:48:02 +08:00
void enableIRIn() {
2022-01-12 17:24:18 +08:00
ir_recv->enableIRIn();
}