From 40c001bdc2f3f71d71a5d1294f4a7440cf0adfe5 Mon Sep 17 00:00:00 2001 From: Gustavo Ambrozio Date: Wed, 1 Nov 2023 15:09:12 -1000 Subject: [PATCH] Fix nextion waveform sending for multiple waveforms (#4408) --- esphome/components/nextion/nextion.cpp | 107 +++++++----------- esphome/components/nextion/nextion.h | 3 + .../nextion/nextion_component_base.h | 7 ++ 3 files changed, 54 insertions(+), 63 deletions(-) diff --git a/esphome/components/nextion/nextion.cpp b/esphome/components/nextion/nextion.cpp index 6133ad1d7e..78c07be890 100644 --- a/esphome/components/nextion/nextion.cpp +++ b/esphome/components/nextion/nextion.cpp @@ -116,6 +116,7 @@ void Nextion::reset_(bool reset_nextion) { this->read_byte(&d); }; this->nextion_queue_.clear(); + this->waveform_queue_.clear(); } void Nextion::dump_config() { @@ -364,37 +365,21 @@ void Nextion::process_nextion_commands_() { ESP_LOGW(TAG, "Nextion reported baud rate invalid!"); break; case 0x12: // invalid Waveform ID or Channel # was used + if (this->waveform_queue_.empty()) { + ESP_LOGW(TAG, + "Nextion reported invalid Waveform ID or Channel # was used but no waveform sensor in queue found!"); + } else { + auto &nb = this->waveform_queue_.front(); + NextionComponentBase *component = nb->component; - if (!this->nextion_queue_.empty()) { - int index = 0; - int found = -1; - for (auto &nb : this->nextion_queue_) { - NextionComponentBase *component = nb->component; + ESP_LOGW(TAG, "Nextion reported invalid Waveform ID %d or Channel # %d was used!", + component->get_component_id(), component->get_wave_channel_id()); - if (component->get_queue_type() == NextionQueueType::WAVEFORM_SENSOR) { - ESP_LOGW(TAG, "Nextion reported invalid Waveform ID %d or Channel # %d was used!", - component->get_component_id(), component->get_wave_channel_id()); + ESP_LOGN(TAG, "Removing waveform from queue with component id %d and waveform id %d", + component->get_component_id(), component->get_wave_channel_id()); - ESP_LOGN(TAG, "Removing waveform from queue with component id %d and waveform id %d", - component->get_component_id(), component->get_wave_channel_id()); - - found = index; - - delete component; // NOLINT(cppcoreguidelines-owning-memory) - delete nb; // NOLINT(cppcoreguidelines-owning-memory) - - break; - } - ++index; - } - - if (found != -1) { - this->nextion_queue_.erase(this->nextion_queue_.begin() + found); - } else { - ESP_LOGW( - TAG, - "Nextion reported invalid Waveform ID or Channel # was used but no waveform sensor in queue found!"); - } + delete nb; // NOLINT(cppcoreguidelines-owning-memory) + this->waveform_queue_.pop_front(); } break; case 0x1A: // variable name invalid @@ -697,44 +682,29 @@ void Nextion::process_nextion_commands_() { } case 0xFD: { // data transparent transmit finished ESP_LOGVV(TAG, "Nextion reported data transmit finished!"); + this->check_pending_waveform_(); break; } case 0xFE: { // data transparent transmit ready ESP_LOGVV(TAG, "Nextion reported ready for transmit!"); - - int index = 0; - int found = -1; - for (auto &nb : this->nextion_queue_) { - auto *component = nb->component; - if (component->get_queue_type() == NextionQueueType::WAVEFORM_SENSOR) { - size_t buffer_to_send = component->get_wave_buffer().size() < 255 ? component->get_wave_buffer().size() - : 255; // ADDT command can only send 255 - - this->write_array(component->get_wave_buffer().data(), static_cast(buffer_to_send)); - - ESP_LOGN(TAG, "Nextion sending waveform data for component id %d and waveform id %d, size %zu", - component->get_component_id(), component->get_wave_channel_id(), buffer_to_send); - - if (component->get_wave_buffer().size() <= 255) { - component->get_wave_buffer().clear(); - } else { - component->get_wave_buffer().erase(component->get_wave_buffer().begin(), - component->get_wave_buffer().begin() + buffer_to_send); - } - found = index; - delete component; // NOLINT(cppcoreguidelines-owning-memory) - delete nb; // NOLINT(cppcoreguidelines-owning-memory) - break; - } - ++index; - } - - if (found == -1) { + if (this->waveform_queue_.empty()) { ESP_LOGE(TAG, "No waveforms in queue to send data!"); break; - } else { - this->nextion_queue_.erase(this->nextion_queue_.begin() + found); } + + auto &nb = this->waveform_queue_.front(); + auto *component = nb->component; + size_t buffer_to_send = component->get_wave_buffer_size() < 255 ? component->get_wave_buffer_size() + : 255; // ADDT command can only send 255 + + this->write_array(component->get_wave_buffer().data(), static_cast(buffer_to_send)); + + ESP_LOGN(TAG, "Nextion sending waveform data for component id %d and waveform id %d, size %zu", + component->get_component_id(), component->get_wave_channel_id(), buffer_to_send); + + component->clear_wave_buffer(buffer_to_send); + delete nb; // NOLINT(cppcoreguidelines-owning-memory) + this->waveform_queue_.pop_front(); break; } default: @@ -1093,17 +1063,28 @@ void Nextion::add_addt_command_to_queue(NextionComponentBase *component) { // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) nextion::NextionQueue *nextion_queue = new nextion::NextionQueue; - // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) - nextion_queue->component = new nextion::NextionComponentBase; + nextion_queue->component = component; nextion_queue->queue_time = millis(); + this->waveform_queue_.push_back(nextion_queue); + if (this->waveform_queue_.size() == 1) + this->check_pending_waveform_(); +} + +void Nextion::check_pending_waveform_() { + if (this->waveform_queue_.empty()) + return; + + auto *nb = this->waveform_queue_.front(); + auto *component = nb->component; size_t buffer_to_send = component->get_wave_buffer_size() < 255 ? component->get_wave_buffer_size() : 255; // ADDT command can only send 255 std::string command = "addt " + to_string(component->get_component_id()) + "," + to_string(component->get_wave_channel_id()) + "," + to_string(buffer_to_send); - if (this->send_command_(command)) { - this->nextion_queue_.push_back(nextion_queue); + if (!this->send_command_(command)) { + delete nb; // NOLINT(cppcoreguidelines-owning-memory) + this->waveform_queue_.pop_front(); } } diff --git a/esphome/components/nextion/nextion.h b/esphome/components/nextion/nextion.h index 7518d7f4cb..92ff3fe235 100644 --- a/esphome/components/nextion/nextion.h +++ b/esphome/components/nextion/nextion.h @@ -740,6 +740,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe protected: std::deque nextion_queue_; + std::deque waveform_queue_; uint16_t recv_ret_string_(std::string &response, uint32_t timeout, bool recv_flag); void all_components_send_state_(bool force_update = false); uint64_t comok_sent_ = 0; @@ -780,6 +781,8 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe const std::string &variable_name_to_send, const std::string &state_value, bool is_sleep_safe = false); + void check_pending_waveform_(); + #ifdef USE_NEXTION_TFT_UPLOAD #ifdef USE_ESP8266 WiFiClient *wifi_client_{nullptr}; diff --git a/esphome/components/nextion/nextion_component_base.h b/esphome/components/nextion/nextion_component_base.h index e0ef8f93bc..42e1b00998 100644 --- a/esphome/components/nextion/nextion_component_base.h +++ b/esphome/components/nextion/nextion_component_base.h @@ -69,6 +69,13 @@ class NextionComponentBase { std::vector get_wave_buffer() { return this->wave_buffer_; } size_t get_wave_buffer_size() { return this->wave_buffer_.size(); } + void clear_wave_buffer(size_t buffer_sent) { + if (this->wave_buffer_.size() <= buffer_sent) { + this->wave_buffer_.clear(); + } else { + this->wave_buffer_.erase(this->wave_buffer_.begin(), this->wave_buffer_.begin() + buffer_sent); + } + } std::string get_variable_name() { return this->variable_name_; } std::string get_variable_name_to_send() { return this->variable_name_to_send_; }