mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[nextion] Replace boolean flags with bitfields to optimize memory usage (#9359)
This commit is contained in:
		| @@ -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<void()> &&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<nextion::NextionQueue> 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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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_) { | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user