Fix polling error
This commit is contained in:
@@ -137,6 +137,7 @@ void IotDisBridge::poll_task_(void* param) {
|
||||
while (!bridge->stop_polling_) {
|
||||
ESP_LOGI(TAG, "Polling for status update...");
|
||||
bridge->poll_status_();
|
||||
ESP_LOGI(TAG, "poll_status_() returned");
|
||||
|
||||
// Yield to allow display updates to complete
|
||||
taskYIELD();
|
||||
@@ -150,6 +151,7 @@ void IotDisBridge::poll_task_(void* param) {
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Polling task stopped");
|
||||
bridge->poll_task_handle_ = nullptr;
|
||||
vTaskDelete(nullptr);
|
||||
}
|
||||
|
||||
@@ -176,38 +178,28 @@ void IotDisBridge::poll_status_() {
|
||||
event_data.state = StatusUpdateEventData::VoiceState::UNMUTED;
|
||||
}
|
||||
|
||||
// Reset failure counter on successful push update
|
||||
if (event_data.state != StatusUpdateEventData::VoiceState::UNKNOWN) {
|
||||
consecutive_failures_ = 0;
|
||||
}
|
||||
|
||||
if (on_status_update_callback_) {
|
||||
on_status_update_callback_(event_data, status_event_user_data_);
|
||||
}
|
||||
|
||||
// VoiceState new_state = VoiceState::UNKNOWN;
|
||||
// if (push_message == MUTED_RESPONSE) {
|
||||
// new_state = VoiceState::MUTED;
|
||||
// } else if (push_message == UNMUTED_RESPONSE) {
|
||||
// new_state = VoiceState::UNMUTED;
|
||||
// }
|
||||
|
||||
// if (new_state != VoiceState::UNKNOWN) {
|
||||
// consecutive_failures_ = 0;
|
||||
// if (main_ui_ && current_page_ == Page::MAIN) {
|
||||
// main_ui_->show_error_notification(false);
|
||||
// }
|
||||
|
||||
// if (state_mutex_ && xSemaphoreTake(state_mutex_, pdMS_TO_TICKS(100)) == pdTRUE) {
|
||||
// current_state_ = new_state;
|
||||
// xSemaphoreGive(state_mutex_);
|
||||
// }
|
||||
|
||||
// update_main_ui();
|
||||
// return; // Got push update, skip polling
|
||||
// }
|
||||
// Got push update, skip polling
|
||||
if (event_data.state != StatusUpdateEventData::VoiceState::UNKNOWN) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Send STATUS command for polling
|
||||
ESP_LOGI(TAG, "Sending STATUS command for polling");
|
||||
err = udp_client_.send_command(STATUS_COMMAND);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGW(TAG, "Failed to send STATUS command");
|
||||
consecutive_failures_++;
|
||||
ESP_LOGW(TAG, "Failed to send STATUS command for polling. Consecutive failures: %d",
|
||||
consecutive_failures_);
|
||||
|
||||
if (consecutive_failures_ >= MAX_FAILURES_BEFORE_ERROR) {
|
||||
if (on_status_update_callback_) {
|
||||
@@ -221,12 +213,15 @@ void IotDisBridge::poll_status_() {
|
||||
}
|
||||
|
||||
// Wait for response to STATUS command
|
||||
ESP_LOGI(TAG, "Waiting for response to STATUS command (timeout: %dms)", RESPONSE_TIMEOUT_MS);
|
||||
std::string response;
|
||||
err = udp_client_.receive_response(response, RESPONSE_TIMEOUT_MS);
|
||||
ESP_LOGI(TAG, "Received response from STATUS command: err=%d", err);
|
||||
|
||||
if (err == ESP_OK) {
|
||||
// Success - reset failure counter
|
||||
consecutive_failures_ = 0;
|
||||
ESP_LOGI(TAG, "STATUS response: %s", response.c_str());
|
||||
|
||||
StatusUpdateEventData event_data {
|
||||
.state = StatusUpdateEventData::VoiceState::UNKNOWN
|
||||
@@ -236,15 +231,19 @@ void IotDisBridge::poll_status_() {
|
||||
} else if (response == UNMUTED_RESPONSE) {
|
||||
event_data.state = StatusUpdateEventData::VoiceState::UNMUTED;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Invoking status update callback with state: %d", event_data.state);
|
||||
if (on_status_update_callback_) {
|
||||
on_status_update_callback_(event_data, status_event_user_data_);
|
||||
ESP_LOGI(TAG, "Status update callback returned");
|
||||
}
|
||||
} else {
|
||||
// Timeout or error
|
||||
consecutive_failures_++;
|
||||
ESP_LOGW(TAG, "No response to STATUS (failures: %d)", consecutive_failures_);
|
||||
ESP_LOGW(TAG, "No response to STATUS (failures: %d, error: %d)", consecutive_failures_, err);
|
||||
|
||||
if (consecutive_failures_ >= MAX_FAILURES_BEFORE_ERROR) {
|
||||
ESP_LOGW(TAG, "Max failures reached, sending ERROR state");
|
||||
if (on_status_update_callback_) {
|
||||
on_status_update_callback_(
|
||||
StatusUpdateEventData { .state = StatusUpdateEventData::VoiceState::ERROR },
|
||||
@@ -253,4 +252,6 @@ void IotDisBridge::poll_status_() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "poll_status_ complete");
|
||||
}
|
||||
@@ -45,8 +45,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr int POLL_INTERVAL_MS = 2000;
|
||||
static constexpr int ERROR_POLL_INTERVAL_MS = 5000;
|
||||
static constexpr int POLL_INTERVAL_MS = 10000;
|
||||
static constexpr int ERROR_POLL_INTERVAL_MS = 20000;
|
||||
static constexpr int RESPONSE_TIMEOUT_MS = 1000;
|
||||
static constexpr int MAX_FAILURES_BEFORE_ERROR = 3;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "ui/apps/iotdis/app.h"
|
||||
#include "ui/interaction_handler.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_lvgl_port.h"
|
||||
|
||||
static const char* TAG = "MainUI";
|
||||
|
||||
@@ -28,6 +29,15 @@ esp_err_t MainUI::deinit(void) {
|
||||
}
|
||||
|
||||
void MainUI::create_ui_(lv_obj_t* parent) {
|
||||
if (!parent) {
|
||||
ESP_LOGE(TAG, "Parent LVGL object is null");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lvgl_port_lock(pdMS_TO_TICKS(100))) {
|
||||
ESP_LOGE(TAG, "Failed to acquire LVGL lock for UI creation");
|
||||
return;
|
||||
}
|
||||
// Set up main page with flex column layout
|
||||
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(parent, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
@@ -101,6 +111,7 @@ void MainUI::create_ui_(lv_obj_t* parent) {
|
||||
lv_obj_center(settings_icon);
|
||||
|
||||
ESP_LOGI(TAG, "Main UI created");
|
||||
lvgl_port_unlock();
|
||||
}
|
||||
|
||||
esp_err_t MainUI::register_on_settings_button_clicked(lv_event_cb_t cb, void* user_data) {
|
||||
@@ -124,6 +135,11 @@ void MainUI::update_status(VoiceState state) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lvgl_port_lock(pdMS_TO_TICKS(100))) {
|
||||
ESP_LOGW(TAG, "Failed to acquire LVGL lock for status update");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case VoiceState::MUTED:
|
||||
lv_label_set_text(status_icon_label_, LV_SYMBOL_MUTE);
|
||||
@@ -150,24 +166,40 @@ void MainUI::update_status(VoiceState state) {
|
||||
lv_obj_set_style_text_color(status_icon_label_, lv_color_black(), 0);
|
||||
break;
|
||||
}
|
||||
lvgl_port_unlock();
|
||||
}
|
||||
|
||||
void MainUI::show_error_notification(bool show) {
|
||||
if (error_notification_) {
|
||||
if (show) {
|
||||
lv_obj_clear_flag(error_notification_, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_add_flag(error_notification_, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
if (!error_notification_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lvgl_port_lock(pdMS_TO_TICKS(100))) {
|
||||
ESP_LOGW(TAG, "Failed to acquire LVGL lock for error notification update");
|
||||
return;
|
||||
}
|
||||
if (show) {
|
||||
lv_obj_clear_flag(error_notification_, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_add_flag(error_notification_, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
lvgl_port_unlock();
|
||||
}
|
||||
|
||||
void MainUI::update_config_prompt(bool configured) {
|
||||
if (config_prompt_) {
|
||||
if (configured) {
|
||||
lv_obj_add_flag(config_prompt_, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_clear_flag(config_prompt_, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
if (!config_prompt_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!lvgl_port_lock(pdMS_TO_TICKS(100))) {
|
||||
ESP_LOGW(TAG, "Failed to acquire LVGL lock for config prompt update");
|
||||
return;
|
||||
}
|
||||
if (configured) {
|
||||
lv_obj_add_flag(config_prompt_, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_clear_flag(config_prompt_, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
lvgl_port_unlock();
|
||||
|
||||
}
|
||||
|
||||
@@ -106,17 +106,24 @@ void MainUIHandler::send_mute_command_() {
|
||||
}
|
||||
|
||||
void MainUIHandler::on_status_update_(StatusUpdateEventData data) {
|
||||
ESP_LOGI(TAG, "on_status_update_ called with state: %d", data.state);
|
||||
|
||||
// Update state in thread-safe manner
|
||||
if (state_mutex_ && xSemaphoreTake(state_mutex_, pdMS_TO_TICKS(100)) == pdTRUE) {
|
||||
current_state_ = data.state;
|
||||
xSemaphoreGive(state_mutex_);
|
||||
ESP_LOGI(TAG, "State updated in mutex");
|
||||
}
|
||||
|
||||
// Update UI
|
||||
ESP_LOGI(TAG, "Calling update_ui_()");
|
||||
update_ui_();
|
||||
ESP_LOGI(TAG, "on_status_update_ complete");
|
||||
}
|
||||
|
||||
void MainUIHandler::update_ui_() {
|
||||
ESP_LOGI(TAG, "update_ui_ called");
|
||||
|
||||
if (main_ui_) {
|
||||
StatusUpdateEventData::VoiceState state;
|
||||
if (state_mutex_ && xSemaphoreTake(state_mutex_, pdMS_TO_TICKS(100)) == pdTRUE) {
|
||||
@@ -126,6 +133,8 @@ void MainUIHandler::update_ui_() {
|
||||
state = StatusUpdateEventData::VoiceState::UNKNOWN;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Converting state: %d", state);
|
||||
|
||||
// Convert to MainUI VoiceState
|
||||
VoiceState ui_state;
|
||||
switch (state) {
|
||||
@@ -143,8 +152,14 @@ void MainUIHandler::update_ui_() {
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Calling main_ui_->update_status() with ui_state: %d", ui_state);
|
||||
|
||||
// Lock LVGL before calling UI functions from another task
|
||||
main_ui_->update_status(ui_state);
|
||||
ESP_LOGI(TAG, "main_ui_->update_status() returned");
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "update_ui_ complete");
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user