diff --git a/esphome/components/nextion/nextion.cpp b/esphome/components/nextion/nextion.cpp index bcb1aced9a..d95238bbb4 100644 --- a/esphome/components/nextion/nextion.cpp +++ b/esphome/components/nextion/nextion.cpp @@ -11,7 +11,7 @@ static const char *const TAG = "nextion"; void Nextion::setup() { this->is_setup_ = false; - this->ignore_is_setup_ = true; + this->connection_state_.ignore_is_setup_ = true; // Wake up the nextion this->send_command_("bkcmd=0"); @@ -23,16 +23,16 @@ void Nextion::setup() { // Reboot it this->send_command_("rest"); - this->ignore_is_setup_ = false; + this->connection_state_.ignore_is_setup_ = false; } bool Nextion::send_command_(const std::string &command) { - if (!this->ignore_is_setup_ && !this->is_setup()) { + if (!this->connection_state_.ignore_is_setup_ && !this->is_setup()) { return false; } #ifdef USE_NEXTION_COMMAND_SPACING - if (!this->ignore_is_setup_ && !this->command_pacer_.can_send()) { + if (!this->connection_state_.ignore_is_setup_ && !this->command_pacer_.can_send()) { ESP_LOGN(TAG, "Command spacing: delaying command '%s'", command.c_str()); return false; } @@ -48,7 +48,7 @@ bool Nextion::send_command_(const std::string &command) { } bool Nextion::check_connect_() { - if (this->is_connected_) + if (this->connection_state_.is_connected_) return true; // Check if the handshake should be skipped for the Nextion connection @@ -56,7 +56,7 @@ bool Nextion::check_connect_() { // Log the connection status without handshake ESP_LOGW(TAG, "Connected (no handshake)"); // Set the connection status to true - this->is_connected_ = true; + this->connection_state_.is_connected_ = true; // Return true indicating the connection is set return true; } @@ -64,7 +64,7 @@ bool Nextion::check_connect_() { if (this->comok_sent_ == 0) { this->reset_(false); - this->ignore_is_setup_ = true; + this->connection_state_.ignore_is_setup_ = true; this->send_command_("boguscommand=0"); // bogus command. needed sometimes after updating if (this->exit_reparse_on_start_) { this->send_command_("DRAKJHSUYDGBNCJHGJKSHBDN"); @@ -72,7 +72,7 @@ bool Nextion::check_connect_() { this->send_command_("connect"); this->comok_sent_ = App.get_loop_component_start_time(); - this->ignore_is_setup_ = false; + this->connection_state_.ignore_is_setup_ = false; return false; } @@ -101,9 +101,9 @@ bool Nextion::check_connect_() { return false; } - this->ignore_is_setup_ = true; + this->connection_state_.ignore_is_setup_ = true; ESP_LOGI(TAG, "Connected"); - this->is_connected_ = true; + this->connection_state_.is_connected_ = true; ESP_LOGN(TAG, "connect: %s", response.c_str()); @@ -127,7 +127,7 @@ bool Nextion::check_connect_() { ESP_LOGE(TAG, "Bad connect value: '%s'", response.c_str()); } - this->ignore_is_setup_ = false; + this->connection_state_.ignore_is_setup_ = false; this->dump_config(); return true; } @@ -158,7 +158,7 @@ void Nextion::dump_config() { ESP_LOGCONFIG(TAG, " Wake On Touch: %s\n" " Exit reparse: %s", - YESNO(this->auto_wake_on_touch_), YESNO(this->exit_reparse_on_start_)); + YESNO(this->connection_state_.auto_wake_on_touch_), YESNO(this->exit_reparse_on_start_)); #ifdef USE_NEXTION_MAX_COMMANDS_PER_LOOP ESP_LOGCONFIG(TAG, " Max commands per loop: %u", this->max_commands_per_loop_); #endif // USE_NEXTION_MAX_COMMANDS_PER_LOOP @@ -221,7 +221,7 @@ void Nextion::add_buffer_overflow_event_callback(std::function &&callbac } void Nextion::update_all_components() { - if ((!this->is_setup() && !this->ignore_is_setup_) || this->is_sleeping()) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || this->is_sleeping()) return; for (auto *binarysensortype : this->binarysensortype_) { @@ -239,7 +239,7 @@ void Nextion::update_all_components() { } bool Nextion::send_command(const char *command) { - if ((!this->is_setup() && !this->ignore_is_setup_) || this->is_sleeping()) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || this->is_sleeping()) return false; if (this->send_command_(command)) { @@ -250,7 +250,7 @@ bool Nextion::send_command(const char *command) { } bool Nextion::send_command_printf(const char *format, ...) { - if ((!this->is_setup() && !this->ignore_is_setup_) || this->is_sleeping()) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || this->is_sleeping()) return false; char buffer[256]; @@ -291,12 +291,12 @@ void Nextion::print_queue_members_() { #endif void Nextion::loop() { - if (!this->check_connect_() || this->is_updating_) + if (!this->check_connect_() || this->connection_state_.is_updating_) return; - if (this->nextion_reports_is_setup_ && !this->sent_setup_commands_) { - this->ignore_is_setup_ = true; - this->sent_setup_commands_ = true; + if (this->connection_state_.nextion_reports_is_setup_ && !this->connection_state_.sent_setup_commands_) { + this->connection_state_.ignore_is_setup_ = true; + this->connection_state_.sent_setup_commands_ = true; this->send_command_("bkcmd=3"); // Always, returns 0x00 to 0x23 result of serial command. if (this->brightness_.has_value()) { @@ -314,19 +314,19 @@ void Nextion::loop() { this->set_wake_up_page(this->wake_up_page_); } - this->ignore_is_setup_ = false; + this->connection_state_.ignore_is_setup_ = false; } this->process_serial_(); // Receive serial data this->process_nextion_commands_(); // Process nextion return commands - if (!this->nextion_reports_is_setup_) { + if (!this->connection_state_.nextion_reports_is_setup_) { if (this->started_ms_ == 0) this->started_ms_ = App.get_loop_component_start_time(); if (this->started_ms_ + this->startup_override_ms_ < App.get_loop_component_start_time()) { ESP_LOGD(TAG, "Manual ready set"); - this->nextion_reports_is_setup_ = true; + this->connection_state_.nextion_reports_is_setup_ = true; } } @@ -669,7 +669,7 @@ void Nextion::process_nextion_commands_() { case 0x88: // system successful start up { ESP_LOGD(TAG, "System start: %zu", to_process_length); - this->nextion_reports_is_setup_ = true; + this->connection_state_.nextion_reports_is_setup_ = true; break; } case 0x89: { // start SD card upgrade @@ -1052,7 +1052,7 @@ void Nextion::add_no_result_to_queue_(const std::string &variable_name) { * @param command */ void Nextion::add_no_result_to_queue_with_command_(const std::string &variable_name, const std::string &command) { - if ((!this->is_setup() && !this->ignore_is_setup_) || command.empty()) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || command.empty()) return; if (this->send_command_(command)) { @@ -1095,7 +1095,7 @@ void Nextion::add_no_result_to_queue_with_pending_command_(const std::string &va bool Nextion::add_no_result_to_queue_with_ignore_sleep_printf_(const std::string &variable_name, const char *format, ...) { - if ((!this->is_setup() && !this->ignore_is_setup_)) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_)) return false; char buffer[256]; @@ -1120,7 +1120,7 @@ bool Nextion::add_no_result_to_queue_with_ignore_sleep_printf_(const std::string * @param ... The format arguments */ bool Nextion::add_no_result_to_queue_with_printf_(const std::string &variable_name, const char *format, ...) { - if ((!this->is_setup() && !this->ignore_is_setup_) || this->is_sleeping()) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || this->is_sleeping()) return false; char buffer[256]; @@ -1159,7 +1159,7 @@ void Nextion::add_no_result_to_queue_with_set(const std::string &variable_name, void Nextion::add_no_result_to_queue_with_set_internal_(const std::string &variable_name, const std::string &variable_name_to_send, int32_t state_value, bool is_sleep_safe) { - if ((!this->is_setup() && !this->ignore_is_setup_) || (!is_sleep_safe && this->is_sleeping())) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || (!is_sleep_safe && this->is_sleeping())) return; this->add_no_result_to_queue_with_ignore_sleep_printf_(variable_name, "%s=%" PRId32, variable_name_to_send.c_str(), @@ -1187,7 +1187,7 @@ void Nextion::add_no_result_to_queue_with_set(const std::string &variable_name, void Nextion::add_no_result_to_queue_with_set_internal_(const std::string &variable_name, const std::string &variable_name_to_send, const std::string &state_value, bool is_sleep_safe) { - if ((!this->is_setup() && !this->ignore_is_setup_) || (!is_sleep_safe && this->is_sleeping())) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || (!is_sleep_safe && this->is_sleeping())) return; this->add_no_result_to_queue_with_printf_(variable_name, "%s=\"%s\"", variable_name_to_send.c_str(), @@ -1204,7 +1204,7 @@ void Nextion::add_no_result_to_queue_with_set_internal_(const std::string &varia * @param component Pointer to the Nextion component that will handle the response. */ void Nextion::add_to_get_queue(NextionComponentBase *component) { - if ((!this->is_setup() && !this->ignore_is_setup_)) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_)) return; #ifdef USE_NEXTION_MAX_QUEUE_SIZE @@ -1244,7 +1244,7 @@ void Nextion::add_to_get_queue(NextionComponentBase *component) { * @param buffer_size The buffer data */ void Nextion::add_addt_command_to_queue(NextionComponentBase *component) { - if ((!this->is_setup() && !this->ignore_is_setup_) || this->is_sleeping()) + if ((!this->is_setup() && !this->connection_state_.ignore_is_setup_) || this->is_sleeping()) return; RAMAllocator allocator; @@ -1285,7 +1285,7 @@ void Nextion::set_writer(const nextion_writer_t &writer) { this->writer_ = write ESPDEPRECATED("set_wait_for_ack(bool) deprecated, no effect", "v1.20") void Nextion::set_wait_for_ack(bool wait_for_ack) { ESP_LOGE(TAG, "Deprecated"); } -bool Nextion::is_updating() { return this->is_updating_; } +bool Nextion::is_updating() { return this->connection_state_.is_updating_; } } // namespace nextion } // namespace esphome diff --git a/esphome/components/nextion/nextion.h b/esphome/components/nextion/nextion.h index f5fa26b98c..0ce9429594 100644 --- a/esphome/components/nextion/nextion.h +++ b/esphome/components/nextion/nextion.h @@ -1302,7 +1302,7 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe * @return true if the Nextion display is connected and ready to receive commands * @return false if the display is not yet connected or connection was lost */ - bool is_connected() { return this->is_connected_; } + bool is_connected() { return this->connection_state_.is_connected_; } protected: #ifdef USE_NEXTION_MAX_COMMANDS_PER_LOOP @@ -1336,21 +1336,28 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe bool remove_from_q_(bool report_empty = true); /** - * @brief - * Sends commands ignoring of the Nextion has been setup. + * @brief Status flags for Nextion display state management + * + * Uses bitfields to pack multiple boolean states into a single byte, + * saving 5 bytes of RAM compared to individual bool variables. */ - bool ignore_is_setup_ = false; + struct { + uint8_t is_connected_ : 1; ///< Connection established with Nextion display + uint8_t sent_setup_commands_ : 1; ///< Initial setup commands have been sent + uint8_t ignore_is_setup_ : 1; ///< Temporarily ignore setup state for special operations + uint8_t nextion_reports_is_setup_ : 1; ///< Nextion has reported successful initialization + uint8_t is_updating_ : 1; ///< TFT firmware update is currently in progress + uint8_t auto_wake_on_touch_ : 1; ///< Display should wake automatically on touch (default: true) + uint8_t reserved_ : 2; ///< Reserved bits for future flag additions + } connection_state_{}; ///< Zero-initialized status flags (all start as false) - bool nextion_reports_is_setup_ = false; void process_nextion_commands_(); void process_serial_(); - bool is_updating_ = false; uint16_t touch_sleep_timeout_ = 0; uint8_t wake_up_page_ = 255; #ifdef USE_NEXTION_CONF_START_UP_PAGE uint8_t start_up_page_ = 255; #endif // USE_NEXTION_CONF_START_UP_PAGE - bool auto_wake_on_touch_ = true; bool exit_reparse_on_start_ = false; bool skip_connection_handshake_ = false; @@ -1472,11 +1479,9 @@ class Nextion : public NextionBase, public PollingComponent, public uart::UARTDe void reset_(bool reset_nextion = true); std::string command_data_; - bool is_connected_ = false; const uint16_t startup_override_ms_ = 8000; const uint16_t max_q_age_ms_ = 8000; uint32_t started_ms_ = 0; - bool sent_setup_commands_ = false; }; } // namespace nextion diff --git a/esphome/components/nextion/nextion_commands.cpp b/esphome/components/nextion/nextion_commands.cpp index f8307c6c4b..018f8fe732 100644 --- a/esphome/components/nextion/nextion_commands.cpp +++ b/esphome/components/nextion/nextion_commands.cpp @@ -38,7 +38,7 @@ void Nextion::sleep(bool sleep) { // Protocol reparse mode bool Nextion::set_protocol_reparse_mode(bool active_mode) { ESP_LOGV(TAG, "Reparse mode: %s", YESNO(active_mode)); - this->ignore_is_setup_ = true; // if not in reparse mode setup will fail, so it should be ignored + this->connection_state_.ignore_is_setup_ = true; // if not in reparse mode setup will fail, so it should be ignored bool all_commands_sent = true; if (active_mode) { // Sets active protocol reparse mode all_commands_sent &= this->send_command_("recmod=1"); @@ -48,10 +48,10 @@ bool Nextion::set_protocol_reparse_mode(bool active_mode) { all_commands_sent &= this->send_command_("recmod=0"); // Sending recmode=0 twice is recommended all_commands_sent &= this->send_command_("recmod=0"); } - if (!this->nextion_reports_is_setup_) { // No need to connect if is already setup + if (!this->connection_state_.nextion_reports_is_setup_) { // No need to connect if is already setup all_commands_sent &= this->send_command_("connect"); } - this->ignore_is_setup_ = false; + this->connection_state_.ignore_is_setup_ = false; return all_commands_sent; } @@ -191,7 +191,7 @@ void Nextion::set_backlight_brightness(float brightness) { } void Nextion::set_auto_wake_on_touch(bool auto_wake_on_touch) { - this->auto_wake_on_touch_ = auto_wake_on_touch; + this->connection_state_.auto_wake_on_touch_ = auto_wake_on_touch; this->add_no_result_to_queue_with_set("auto_wake_on_touch", "thup", auto_wake_on_touch ? 1 : 0); } diff --git a/esphome/components/nextion/nextion_upload.cpp b/esphome/components/nextion/nextion_upload.cpp index 6a54abfed4..c47b393f99 100644 --- a/esphome/components/nextion/nextion_upload.cpp +++ b/esphome/components/nextion/nextion_upload.cpp @@ -16,8 +16,8 @@ bool Nextion::upload_end_(bool successful) { } else { ESP_LOGE(TAG, "Upload failed"); - this->is_updating_ = false; - this->ignore_is_setup_ = false; + this->connection_state_.is_updating_ = false; + this->connection_state_.ignore_is_setup_ = false; uint32_t baud_rate = this->parent_->get_baud_rate(); if (baud_rate != this->original_baud_rate_) { diff --git a/esphome/components/nextion/nextion_upload_arduino.cpp b/esphome/components/nextion/nextion_upload_arduino.cpp index 6cd03118d2..b0e5d121dd 100644 --- a/esphome/components/nextion/nextion_upload_arduino.cpp +++ b/esphome/components/nextion/nextion_upload_arduino.cpp @@ -152,7 +152,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { ESP_LOGD(TAG, "Exit reparse: %s", YESNO(exit_reparse)); ESP_LOGD(TAG, "URL: %s", this->tft_url_.c_str()); - if (this->is_updating_) { + if (this->connection_state_.is_updating_) { ESP_LOGW(TAG, "Upload in progress"); return false; } @@ -162,7 +162,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { return false; } - this->is_updating_ = true; + this->connection_state_.is_updating_ = true; if (exit_reparse) { ESP_LOGD(TAG, "Exit reparse mode"); @@ -203,7 +203,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { begin_status = http_client.begin(*this->get_wifi_client_(), this->tft_url_.c_str()); #endif // USE_ESP8266 if (!begin_status) { - this->is_updating_ = false; + this->connection_state_.is_updating_ = false; ESP_LOGD(TAG, "Connection failed"); return false; } else { @@ -254,7 +254,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { // The Nextion will ignore the upload command if it is sleeping ESP_LOGV(TAG, "Wake-up"); - this->ignore_is_setup_ = true; + this->connection_state_.ignore_is_setup_ = true; this->send_command_("sleep=0"); this->send_command_("dim=100"); delay(250); // NOLINT diff --git a/esphome/components/nextion/nextion_upload_idf.cpp b/esphome/components/nextion/nextion_upload_idf.cpp index 14ce46d0a0..78a47f9e2c 100644 --- a/esphome/components/nextion/nextion_upload_idf.cpp +++ b/esphome/components/nextion/nextion_upload_idf.cpp @@ -155,7 +155,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { ESP_LOGD(TAG, "Exit reparse: %s", YESNO(exit_reparse)); ESP_LOGD(TAG, "URL: %s", this->tft_url_.c_str()); - if (this->is_updating_) { + if (this->connection_state_.is_updating_) { ESP_LOGW(TAG, "Upload in progress"); return false; } @@ -165,7 +165,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { return false; } - this->is_updating_ = true; + this->connection_state_.is_updating_ = true; if (exit_reparse) { ESP_LOGD(TAG, "Exit reparse mode"); @@ -246,7 +246,7 @@ bool Nextion::upload_tft(uint32_t baud_rate, bool exit_reparse) { // The Nextion will ignore the upload command if it is sleeping ESP_LOGV(TAG, "Wake-up"); - this->ignore_is_setup_ = true; + this->connection_state_.ignore_is_setup_ = true; this->send_command_("sleep=0"); this->send_command_("dim=100"); vTaskDelay(pdMS_TO_TICKS(250)); // NOLINT