diff --git a/esp8285/src/ir_drv_ctrl.cpp b/esp8285/src/ir_drv_ctrl.cpp index 910d845..7778d2a 100644 --- a/esp8285/src/ir_drv_ctrl.cpp +++ b/esp8285/src/ir_drv_ctrl.cpp @@ -37,17 +37,24 @@ #define IR_SERIES_MAX (1024) #define IR_END_CODE (10000) -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 -const uint16_t k_capture_buffer_size = IR_SERIES_MAX; + +// external variable declaratoins +extern iris_kit_status_t g_iris_kit_status; + + +// public variable definitions + + +// private variable definitions static IRsend * ir_send = nullptr; static IRrecv * ir_recv = nullptr; +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; -int g_study_key_id = -1; -String g_study_key_name = ""; -String g_study_remote_index = ""; +// public function definitions bool sendIR(String file_name) { String save_path = SAVE_PATH + file_name; if (LittleFS.exists(save_path)) { @@ -161,27 +168,19 @@ void sendStatus(String file, t_remote_ac_status status) { } } -void prepareRecvIR(int key_id, String key_name, String remote_index) { - g_study_key_id = key_id; - g_study_key_name = key_name; - g_study_remote_index = remote_index; +void prepareRecvIR() { removeReceived(); enableIRIn(); } void cancelRecvIR() { - g_study_remote_index = ""; - g_study_key_name = ""; - g_study_key_id = -1; disableIRIn(); } -void completedRecvIR(int key_id, String key_name) { +int completeRecvIR(String &ir_data) { // called unsolicited - g_study_remote_index = ""; - g_study_key_name = ""; - g_study_key_id = -1; disableIRIn(); + return loadReceived(ir_data); } void recvIR() { @@ -195,6 +194,11 @@ void recvIR() { ir_recv->resume(); INFOLN(raw_data.c_str()); saveReceived(results); + processStatusChange(IRIS_KIT_STATUS_STUDIED, + g_iris_kit_status.console_id, + g_iris_kit_status.key_id, + g_iris_kit_status.key_name, + g_iris_kit_status.remote_index); } } @@ -202,11 +206,11 @@ bool saveReceived(decode_results& results) { String save_path = SAVE_PATH; String file_name = ""; - if (g_study_remote_index.isEmpty()) { + if (g_iris_kit_status.remote_index.isEmpty()) { return false; } - file_name = "ir_" + g_study_remote_index + RECEIVED_SUFFIX; + file_name = "ir_" + g_iris_kit_status.remote_index + RECEIVED_SUFFIX; save_path += file_name; INFOF("Save received code to: %s\n", save_path.c_str()); File cache = LittleFS.open(save_path, "w"); @@ -225,10 +229,10 @@ bool removeReceived() { String save_path = SAVE_PATH; String file_name = ""; - if (g_study_remote_index.isEmpty()) { + if (g_iris_kit_status.remote_index.isEmpty()) { return false; } - file_name = "ir_" + g_study_remote_index + RECEIVED_SUFFIX; + file_name = "ir_" + g_iris_kit_status.remote_index + RECEIVED_SUFFIX; save_path += file_name; INFOF("Delete received code file: %s\n", save_path.c_str()); LittleFS.remove(save_path); @@ -236,6 +240,29 @@ bool removeReceived() { return true; } +int loadReceived(String &ir_data) { + String save_path = SAVE_PATH; + String file_name = ""; + + if (g_iris_kit_status.remote_index.isEmpty()) { + return -1; + } + + 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(); + + return ir_data.length(); +} + void initAC(String file) { ACStatus[file]["power"] = 0; ACStatus[file]["temperature"] = 8; diff --git a/esp8285/src/ir_drv_ctrl.h b/esp8285/src/ir_drv_ctrl.h index cd7b866..44fcdf5 100644 --- a/esp8285/src/ir_drv_ctrl.h +++ b/esp8285/src/ir_drv_ctrl.h @@ -46,18 +46,20 @@ bool sendCommand(String file_name, int key); void sendStatus(String file_name, t_remote_ac_status status); -void prepareRecvIR(int key_id, String key_name, String remote_index); +void prepareRecvIR(); void cancelRecvIR(); -void completedRecvIR(int key_id, String key_name); +int completeRecvIR(String &ir_data); void recvIR(); -bool saveReceived(decode_results& results); +bool saveReceived(decode_results &results); bool removeReceived(); +int loadReceived(String &ir_data); + void initAC(String); #endif // IR_DRV_CTRL_H \ No newline at end of file diff --git a/esp8285/src/iris_client.cpp b/esp8285/src/iris_client.cpp index f68ec34..c094e50 100644 --- a/esp8285/src/iris_client.cpp +++ b/esp8285/src/iris_client.cpp @@ -62,11 +62,17 @@ char iris_password[PASSWORD_MAX] = { 0 }; static int processEvent(String event_name, String product_key, String device_name, String content); static String buildConnect(); static String buildHeartBeat(); +static void buildGeneralResponse(String notify_name); +static void buildGeneralIndication(String notify_name); +static String buildTestResponse(); +static String buildRecvPreparedResponse(); +static String buildRecvCompletedIndication(String ir_data); +static String buildRecvErrorIndication(); +static String buildRecvCancelledResponse(); static int handleConnected(String product_key, String device_name, String content); static int handleHartBeat(String product_key, String device_name, String content); static int handleEmit(String product_key, String device_name, String content); static int handleNotifyStatus(String product_key, String device_name, String content); -static int processStatusChange(int status, int console_id, int key_id, String key_name, String remote_index); static int hb_count = 0; @@ -243,6 +249,79 @@ void handleIrisKitMessage(const char* data, int length) { } } +int processStatusChange(int status, int console_id, int key_id, String key_name, String remote_index) { + switch(status) { + case IRIS_KIT_STATUS_READY_TO_STUDY: + { + // enter into IR receive mode and send response + updateIrisKitStatus(IRIS_KIT_STATUS_READY_TO_STUDY, console_id, remote_index, key_id, key_name); + prepareRecvIR(); + String recvPreparedResponseData = buildRecvPreparedResponse(); + sendData(g_upstream_topic.c_str(), (uint8_t*) recvPreparedResponseData.c_str(), recvPreparedResponseData.length()); + break; + } + case IRIS_KIT_STATUS_STUDIED: + { + // after IR data are received, load saved IR data and send to IRIS server + updateIrisKitStatus(IRIS_KIT_STATUS_STUDIED, console_id, remote_index, key_id, key_name); + String ir_data = ""; + String recvCompletedIndicationData = ""; + if (completeRecvIR(ir_data) > 0) { + recvCompletedIndicationData = buildRecvCompletedIndication(ir_data); + } else { + recvCompletedIndicationData = buildRecvErrorIndication(); + } + sendData(g_upstream_topic.c_str(), (uint8_t*) recvCompletedIndicationData.c_str(), recvCompletedIndicationData.length()); + updateIrisKitStatus(IRIS_KIT_STATUS_UPLOADED, console_id, remote_index, key_id, key_name); + break; + } + case IRIS_KIT_STATUS_CANCEL_STUDY: + { + // cancel IR receiving and reset + cancelRecvIR(); + String studyCancelledResponseData = buildRecvCancelledResponse(); + sendData(g_upstream_topic.c_str(), (uint8_t*) studyCancelledResponseData.c_str(), studyCancelledResponseData.length()); + resetIrisKitStatus(); + break; + } + case IRIS_KIT_STATUS_TEST: + { + // send response for test notification + updateIrisKitStatus(IRIS_KIT_STATUS_TEST, console_id, remote_index, key_id, key_name); + String testResponseData = buildTestResponse(); + sendData(g_upstream_topic.c_str(), (uint8_t*) testResponseData.c_str(), testResponseData.length()); + resetIrisKitStatus(); + break; + } + default: + { + break; + } + } + + return 0; +} + +void updateIrisKitStatus(status_t status, + int console_id, + String remote_index, + int key_id, String + key_name) { + g_iris_kit_status.status = status; + g_iris_kit_status.console_id = console_id; + g_iris_kit_status.remote_index = remote_index; + g_iris_kit_status.key_id = key_id; + g_iris_kit_status.key_name = key_name; +} + +void resetIrisKitStatus() { + g_iris_kit_status.status = IRIS_KIT_STATUS_IDLE; + g_iris_kit_status.console_id = 0; + g_iris_kit_status.remote_index = ""; + g_iris_kit_status.key_id = 0; + g_iris_kit_status.key_name = ""; +} + // private function definitions static int processEvent(String event_name, String product_key, String device_name, String content) { @@ -281,30 +360,69 @@ static String buildHeartBeat() { return heartBeatMessage; } -static String buildGeneralResponse(int console_id, String notify_payload) { - String notification = ""; +static void buildGeneralResponse(String notify_name) { iris_msg_doc.clear(); iris_msg_doc["eventName"] = String(EVENT_NOTIFY_RESP); iris_msg_doc["productKey"] = g_product_key; iris_msg_doc["deviceName"] = g_device_name; iris_msg_doc["appId"] = g_app_id; - iris_msg_doc["consoleId"] = console_id; - iris_msg_doc["resp"] = String(notify_payload); - serializeJson(iris_msg_doc, notification); - - return notification; + iris_msg_doc["consoleId"] = g_iris_kit_status.console_id; + iris_msg_doc["resp"] = String(notify_name); } -static String buildTestResponse(int console_id) { - return buildGeneralResponse(console_id, NOTIFY_RESP_TEST); +static void buildGeneralIndication(String notify_name) { + iris_ind_doc.clear(); + iris_ind_doc["eventName"] = String(EVENT_NOTIFY_RESP); + iris_ind_doc["productKey"] = g_product_key; + iris_ind_doc["deviceName"] = g_device_name; + iris_ind_doc["appId"] = g_app_id; + iris_ind_doc["consoleId"] = g_iris_kit_status.console_id; + iris_ind_doc["remoteIndex"] = g_iris_kit_status.remote_index; + iris_ind_doc["keyId"] = g_iris_kit_status.key_id; + iris_ind_doc["keyName"] = g_iris_kit_status.key_name; + iris_ind_doc["resp"] = String(notify_name); } -static String buildRecvPreparedResponse(int console_id) { - return buildGeneralResponse(console_id, NOTIFY_RECV_PREPARED); +static String buildTestResponse() { + String testReponse = ""; + buildGeneralResponse(NOTIFY_RESP_TEST); + serializeJson(iris_msg_doc, testReponse); + + return testReponse; } -static String buildStudyCancelledResponse(int console_id) { - return buildGeneralResponse(console_id, NOTIFY_STUDY_CANCELLED); +static String buildRecvPreparedResponse() { + String recvPreparedResponse = ""; + buildGeneralResponse(NOTIFY_RECV_PREPARED); + serializeJson(iris_msg_doc, recvPreparedResponse); + + return recvPreparedResponse; +} + +static String buildRecvCompletedIndication(String ir_data) { + String recvCompletedIndication = ""; + buildGeneralIndication(NOTIFY_RECV_COMPLETED); + iris_ind_doc["payload"] = ir_data; + serializeJson(iris_ind_doc, recvCompletedIndication); + + return recvCompletedIndication; +} + +static String buildRecvErrorIndication() { + String recvErrorIndication = ""; + buildGeneralIndication(NOTIFY_RECV_COMPLETED); + iris_ind_doc["payload"] = "error"; + serializeJson(iris_ind_doc, recvErrorIndication); + + return recvErrorIndication; +} + +static String buildRecvCancelledResponse() { + String recvCancelledResponse = ""; + buildGeneralResponse(NOTIFY_RECV_CANCELLED); + serializeJson(iris_msg_doc, recvCancelledResponse); + + return recvCancelledResponse; } static int handleConnected(String product_key, String device_name, String content) { @@ -318,7 +436,7 @@ static int handleHartBeat(String product_key, String device_name, String content static int handleEmit(String product_key, String device_name, String content) { INFOF("Received emit code : %s, %s, %s\n", product_key.c_str(), device_name.c_str(), content.c_str()); - g_iris_kit_status = IRIS_KIT_STATUS_EMITTING; + updateIrisKitStatus(IRIS_KIT_STATUS_EMITTING, 0, "", 0, ""); emit_code_doc.clear(); if (DeserializationError::Ok == deserializeJson(emit_code_doc, content)) { int remote_id = emit_code_doc["remoteId"]; @@ -329,7 +447,7 @@ static int handleEmit(String product_key, String device_name, String content) { } else { INFOF("Deserialize failed\n"); } - g_iris_kit_status = IRIS_KIT_STATUS_IDLE; + resetIrisKitStatus(); return 0; } @@ -348,39 +466,5 @@ static int handleNotifyStatus(String product_key, String device_name, String con } else { INFOF("Deserialize failed\n"); } - return 0; -} - -static int processStatusChange(int status, int console_id, int key_id, String key_name, String remote_index) { - switch(status) { - case IRIS_KIT_STATUS_TEST: - { - // send response for test notification - String testResponseData = buildTestResponse(console_id); - sendData(g_upstream_topic.c_str(), (uint8_t*) testResponseData.c_str(), testResponseData.length()); - break; - } - case IRIS_KIT_STATUS_READY_TO_STUDY: - { - // enter into IR receive mode and send response - prepareRecvIR(key_id, key_name, remote_index); - String recvPreparedResponseData = buildRecvPreparedResponse(console_id); - sendData(g_upstream_topic.c_str(), (uint8_t*) recvPreparedResponseData.c_str(), recvPreparedResponseData.length()); - break; - } - case IRIS_KIT_STATUS_CANCEL_STUDY: - { - // cancel IR receiving and reset - cancelRecvIR(); - String studyCancelledResponseData = buildStudyCancelledResponse(console_id); - sendData(g_upstream_topic.c_str(), (uint8_t*) studyCancelledResponseData.c_str(), studyCancelledResponseData.length()); - break; - } - default: - { - break; - } - } - return 0; } \ No newline at end of file diff --git a/esp8285/src/iris_client.h b/esp8285/src/iris_client.h index 7919b8e..f51ee3b 100644 --- a/esp8285/src/iris_client.h +++ b/esp8285/src/iris_client.h @@ -39,6 +39,14 @@ typedef enum { IRIS_KIT_STATUS_NOT_CONNECTED = 62, IRIS_KIT_STATUS_MAX = 63, +} status_t; + +typedef struct { + int console_id; + String remote_index; + int key_id; + String key_name; + status_t status; } iris_kit_status_t; // web http call URL list @@ -59,7 +67,8 @@ typedef enum { #define NOTIFY_RESP_TEST "test_ok" #define NOTIFY_RECV_PREPARED "recv_prepared" -#define NOTIFY_STUDY_CANCELLED "study_cancelled" +#define NOTIFY_RECV_CANCELLED "recv_cancelled" +#define NOTIFY_RECV_COMPLETED "recv_completed" typedef int (*eventHandler)(String, String, String); typedef struct { @@ -85,4 +94,18 @@ void sendIrisKitHeartBeat(); void handleIrisKitMessage(const char* data, int length); +int processStatusChange(int status, + int console_id, + int key_id, + String key_name, + String remote_index); + +void updateIrisKitStatus(status_t status, + int console_id, + String remote_index, + int key_id, String + key_name); + +void resetIrisKitStatus(); + #endif // IRIS_KIT_IR_BABY_H \ No newline at end of file diff --git a/esp8285/src/iris_kit.cpp b/esp8285/src/iris_kit.cpp index 49a1101..342ca0e 100644 --- a/esp8285/src/iris_kit.cpp +++ b/esp8285/src/iris_kit.cpp @@ -61,7 +61,13 @@ int credential_init_retry = 0; int g_runtime_env = RUNTIME_RELEASE; iris_kit_settings_t iriskit_settings; bool iris_kit_settings_loaded = false; -iris_kit_status_t g_iris_kit_status = IRIS_KIT_STATUS_NOT_CONNECTED; +iris_kit_status_t g_iris_kit_status = { + console_id: 0, + remote_index: "", + key_id: 0, + key_name: "", + status: IRIS_KIT_STATUS_IDLE +}; // private variable definitions @@ -189,7 +195,7 @@ void setup() { iriskit_settings.password = String(iris_password); setIrisKitSettings(iriskit_settings); - g_iris_kit_status = IRIS_KIT_STATUS_IDLE; + resetIrisKitStatus(); saveSettings(); @@ -232,8 +238,11 @@ void setup() { } void loop() { - if (IRIS_KIT_STATUS_READY_TO_STUDY == g_iris_kit_status) { + // process unsolicited FSM state change + if (IRIS_KIT_STATUS_READY_TO_STUDY == g_iris_kit_status.status) { recvIR(); + } else if (IRIS_KIT_STATUS_UPLOADED == g_iris_kit_status.status) { + resetIrisKitStatus(); } keepAliveIot(); yield();