mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/dev' into integration
This commit is contained in:
		
							
								
								
									
										39
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -214,17 +214,51 @@ jobs: | |||||||
|         if: matrix.os == 'windows-latest' |         if: matrix.os == 'windows-latest' | ||||||
|         run: | |         run: | | ||||||
|           ./venv/Scripts/activate |           ./venv/Scripts/activate | ||||||
|           pytest -vv --cov-report=xml --tb=native -n auto tests |           pytest -vv --cov-report=xml --tb=native -n auto tests --ignore=tests/integration/ | ||||||
|       - name: Run pytest |       - name: Run pytest | ||||||
|         if: matrix.os == 'ubuntu-latest' || matrix.os == 'macOS-latest' |         if: matrix.os == 'ubuntu-latest' || matrix.os == 'macOS-latest' | ||||||
|         run: | |         run: | | ||||||
|           . venv/bin/activate |           . venv/bin/activate | ||||||
|           pytest -vv --cov-report=xml --tb=native -n auto tests |           pytest -vv --cov-report=xml --tb=native -n auto tests --ignore=tests/integration/ | ||||||
|       - name: Upload coverage to Codecov |       - name: Upload coverage to Codecov | ||||||
|         uses: codecov/codecov-action@v5.4.3 |         uses: codecov/codecov-action@v5.4.3 | ||||||
|         with: |         with: | ||||||
|           token: ${{ secrets.CODECOV_TOKEN }} |           token: ${{ secrets.CODECOV_TOKEN }} | ||||||
|  |  | ||||||
|  |   integration-tests: | ||||||
|  |     name: Run integration tests | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     needs: | ||||||
|  |       - common | ||||||
|  |     steps: | ||||||
|  |       - name: Check out code from GitHub | ||||||
|  |         uses: actions/checkout@v4.2.2 | ||||||
|  |       - name: Set up Python 3.13 | ||||||
|  |         id: python | ||||||
|  |         uses: actions/setup-python@v5.6.0 | ||||||
|  |         with: | ||||||
|  |           python-version: "3.13" | ||||||
|  |       - name: Restore Python virtual environment | ||||||
|  |         id: cache-venv | ||||||
|  |         uses: actions/cache@v4.2.3 | ||||||
|  |         with: | ||||||
|  |           path: venv | ||||||
|  |           key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{ needs.common.outputs.cache-key }} | ||||||
|  |       - name: Create Python virtual environment | ||||||
|  |         if: steps.cache-venv.outputs.cache-hit != 'true' | ||||||
|  |         run: | | ||||||
|  |           python -m venv venv | ||||||
|  |           . venv/bin/activate | ||||||
|  |           python --version | ||||||
|  |           pip install -r requirements.txt -r requirements_test.txt | ||||||
|  |           pip install -e . | ||||||
|  |       - name: Register matcher | ||||||
|  |         run: echo "::add-matcher::.github/workflows/matchers/pytest.json" | ||||||
|  |       - name: Run integration tests | ||||||
|  |         run: | | ||||||
|  |           . venv/bin/activate | ||||||
|  |           pytest -vv --no-cov --tb=native -n auto tests/integration/ | ||||||
|  |  | ||||||
|   clang-format: |   clang-format: | ||||||
|     name: Check clang-format |     name: Check clang-format | ||||||
|     runs-on: ubuntu-24.04 |     runs-on: ubuntu-24.04 | ||||||
| @@ -494,6 +528,7 @@ jobs: | |||||||
|       - flake8 |       - flake8 | ||||||
|       - pylint |       - pylint | ||||||
|       - pytest |       - pytest | ||||||
|  |       - integration-tests | ||||||
|       - pyupgrade |       - pyupgrade | ||||||
|       - clang-tidy |       - clang-tidy | ||||||
|       - list-components |       - list-components | ||||||
|   | |||||||
| @@ -44,7 +44,7 @@ void NextionBinarySensor::set_state(bool state, bool publish, bool send_to_nexti | |||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   if (send_to_nextion) { |   if (send_to_nextion) { | ||||||
|     if (this->nextion_->is_sleeping() || !this->visible_) { |     if (this->nextion_->is_sleeping() || !this->component_flags_.visible) { | ||||||
|       this->needs_to_send_update_ = true; |       this->needs_to_send_update_ = true; | ||||||
|     } else { |     } else { | ||||||
|       this->needs_to_send_update_ = false; |       this->needs_to_send_update_ = false; | ||||||
|   | |||||||
| @@ -8,8 +8,8 @@ void NextionComponent::set_background_color(Color bco) { | |||||||
|     return;  // This is a variable. no need to set color |     return;  // This is a variable. no need to set color | ||||||
|   } |   } | ||||||
|   this->bco_ = bco; |   this->bco_ = bco; | ||||||
|   this->bco_needs_update_ = true; |   this->component_flags_.bco_needs_update = true; | ||||||
|   this->bco_is_set_ = true; |   this->component_flags_.bco_is_set = true; | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -19,8 +19,8 @@ void NextionComponent::set_background_pressed_color(Color bco2) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   this->bco2_ = bco2; |   this->bco2_ = bco2; | ||||||
|   this->bco2_needs_update_ = true; |   this->component_flags_.bco2_needs_update = true; | ||||||
|   this->bco2_is_set_ = true; |   this->component_flags_.bco2_is_set = true; | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -29,8 +29,8 @@ void NextionComponent::set_foreground_color(Color pco) { | |||||||
|     return;  // This is a variable. no need to set color |     return;  // This is a variable. no need to set color | ||||||
|   } |   } | ||||||
|   this->pco_ = pco; |   this->pco_ = pco; | ||||||
|   this->pco_needs_update_ = true; |   this->component_flags_.pco_needs_update = true; | ||||||
|   this->pco_is_set_ = true; |   this->component_flags_.pco_is_set = true; | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -39,8 +39,8 @@ void NextionComponent::set_foreground_pressed_color(Color pco2) { | |||||||
|     return;  // This is a variable. no need to set color |     return;  // This is a variable. no need to set color | ||||||
|   } |   } | ||||||
|   this->pco2_ = pco2; |   this->pco2_ = pco2; | ||||||
|   this->pco2_needs_update_ = true; |   this->component_flags_.pco2_needs_update = true; | ||||||
|   this->pco2_is_set_ = true; |   this->component_flags_.pco2_is_set = true; | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -49,8 +49,8 @@ void NextionComponent::set_font_id(uint8_t font_id) { | |||||||
|     return;  // This is a variable. no need to set color |     return;  // This is a variable. no need to set color | ||||||
|   } |   } | ||||||
|   this->font_id_ = font_id; |   this->font_id_ = font_id; | ||||||
|   this->font_id_needs_update_ = true; |   this->component_flags_.font_id_needs_update = true; | ||||||
|   this->font_id_is_set_ = true; |   this->component_flags_.font_id_is_set = true; | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -58,20 +58,20 @@ void NextionComponent::set_visible(bool visible) { | |||||||
|   if (this->variable_name_ == this->variable_name_to_send_) { |   if (this->variable_name_ == this->variable_name_to_send_) { | ||||||
|     return;  // This is a variable. no need to set color |     return;  // This is a variable. no need to set color | ||||||
|   } |   } | ||||||
|   this->visible_ = visible; |   this->component_flags_.visible = visible; | ||||||
|   this->visible_needs_update_ = true; |   this->component_flags_.visible_needs_update = true; | ||||||
|   this->visible_is_set_ = true; |   this->component_flags_.visible_is_set = true; | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void NextionComponent::update_component_settings(bool force_update) { | void NextionComponent::update_component_settings(bool force_update) { | ||||||
|   if (this->nextion_->is_sleeping() || !this->nextion_->is_setup() || !this->visible_is_set_ || |   if (this->nextion_->is_sleeping() || !this->nextion_->is_setup() || !this->component_flags_.visible_is_set || | ||||||
|       (!this->visible_needs_update_ && !this->visible_)) { |       (!this->component_flags_.visible_needs_update && !this->component_flags_.visible)) { | ||||||
|     this->needs_to_send_update_ = true; |     this->needs_to_send_update_ = true; | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (this->visible_needs_update_ || (force_update && this->visible_is_set_)) { |   if (this->component_flags_.visible_needs_update || (force_update && this->component_flags_.visible_is_set)) { | ||||||
|     std::string name_to_send = this->variable_name_; |     std::string name_to_send = this->variable_name_; | ||||||
|  |  | ||||||
|     size_t pos = name_to_send.find_last_of('.'); |     size_t pos = name_to_send.find_last_of('.'); | ||||||
| @@ -79,9 +79,9 @@ void NextionComponent::update_component_settings(bool force_update) { | |||||||
|       name_to_send = name_to_send.substr(pos + 1); |       name_to_send = name_to_send.substr(pos + 1); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     this->visible_needs_update_ = false; |     this->component_flags_.visible_needs_update = false; | ||||||
|  |  | ||||||
|     if (this->visible_) { |     if (this->component_flags_.visible) { | ||||||
|       this->nextion_->show_component(name_to_send.c_str()); |       this->nextion_->show_component(name_to_send.c_str()); | ||||||
|       this->send_state_to_nextion(); |       this->send_state_to_nextion(); | ||||||
|     } else { |     } else { | ||||||
| @@ -90,26 +90,26 @@ void NextionComponent::update_component_settings(bool force_update) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (this->bco_needs_update_ || (force_update && this->bco2_is_set_)) { |   if (this->component_flags_.bco_needs_update || (force_update && this->component_flags_.bco2_is_set)) { | ||||||
|     this->nextion_->set_component_background_color(this->variable_name_.c_str(), this->bco_); |     this->nextion_->set_component_background_color(this->variable_name_.c_str(), this->bco_); | ||||||
|     this->bco_needs_update_ = false; |     this->component_flags_.bco_needs_update = false; | ||||||
|   } |   } | ||||||
|   if (this->bco2_needs_update_ || (force_update && this->bco2_is_set_)) { |   if (this->component_flags_.bco2_needs_update || (force_update && this->component_flags_.bco2_is_set)) { | ||||||
|     this->nextion_->set_component_pressed_background_color(this->variable_name_.c_str(), this->bco2_); |     this->nextion_->set_component_pressed_background_color(this->variable_name_.c_str(), this->bco2_); | ||||||
|     this->bco2_needs_update_ = false; |     this->component_flags_.bco2_needs_update = false; | ||||||
|   } |   } | ||||||
|   if (this->pco_needs_update_ || (force_update && this->pco_is_set_)) { |   if (this->component_flags_.pco_needs_update || (force_update && this->component_flags_.pco_is_set)) { | ||||||
|     this->nextion_->set_component_foreground_color(this->variable_name_.c_str(), this->pco_); |     this->nextion_->set_component_foreground_color(this->variable_name_.c_str(), this->pco_); | ||||||
|     this->pco_needs_update_ = false; |     this->component_flags_.pco_needs_update = false; | ||||||
|   } |   } | ||||||
|   if (this->pco2_needs_update_ || (force_update && this->pco2_is_set_)) { |   if (this->component_flags_.pco2_needs_update || (force_update && this->component_flags_.pco2_is_set)) { | ||||||
|     this->nextion_->set_component_pressed_foreground_color(this->variable_name_.c_str(), this->pco2_); |     this->nextion_->set_component_pressed_foreground_color(this->variable_name_.c_str(), this->pco2_); | ||||||
|     this->pco2_needs_update_ = false; |     this->component_flags_.pco2_needs_update = false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   if (this->font_id_needs_update_ || (force_update && this->font_id_is_set_)) { |   if (this->component_flags_.font_id_needs_update || (force_update && this->component_flags_.font_id_is_set)) { | ||||||
|     this->nextion_->set_component_font(this->variable_name_.c_str(), this->font_id_); |     this->nextion_->set_component_font(this->variable_name_.c_str(), this->font_id_); | ||||||
|     this->font_id_needs_update_ = false; |     this->component_flags_.font_id_needs_update = false; | ||||||
|   } |   } | ||||||
| } | } | ||||||
| }  // namespace nextion | }  // namespace nextion | ||||||
|   | |||||||
| @@ -21,29 +21,64 @@ class NextionComponent : public NextionComponentBase { | |||||||
|   void set_visible(bool visible); |   void set_visible(bool visible); | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|  |   /** | ||||||
|  |    * @brief Constructor initializes component state with visible=true (default state) | ||||||
|  |    */ | ||||||
|  |   NextionComponent() { | ||||||
|  |     component_flags_ = {};         // Zero-initialize all state | ||||||
|  |     component_flags_.visible = 1;  // Set default visibility to true | ||||||
|  |   } | ||||||
|  |  | ||||||
|   NextionBase *nextion_; |   NextionBase *nextion_; | ||||||
|  |  | ||||||
|   bool bco_needs_update_ = false; |   // Color and styling properties | ||||||
|   bool bco_is_set_ = false; |   Color bco_;   // Background color | ||||||
|   Color bco_; |   Color bco2_;  // Pressed background color | ||||||
|   bool bco2_needs_update_ = false; |   Color pco_;   // Foreground color | ||||||
|   bool bco2_is_set_ = false; |   Color pco2_;  // Pressed foreground color | ||||||
|   Color bco2_; |  | ||||||
|   bool pco_needs_update_ = false; |  | ||||||
|   bool pco_is_set_ = false; |  | ||||||
|   Color pco_; |  | ||||||
|   bool pco2_needs_update_ = false; |  | ||||||
|   bool pco2_is_set_ = false; |  | ||||||
|   Color pco2_; |  | ||||||
|   uint8_t font_id_ = 0; |   uint8_t font_id_ = 0; | ||||||
|   bool font_id_needs_update_ = false; |  | ||||||
|   bool font_id_is_set_ = false; |  | ||||||
|  |  | ||||||
|   bool visible_ = true; |   /** | ||||||
|   bool visible_needs_update_ = false; |    * @brief Component state management using compact bitfield structure | ||||||
|   bool visible_is_set_ = false; |    * | ||||||
|  |    * Stores all component state flags and properties in a single 16-bit bitfield | ||||||
|  |    * for efficient memory usage and improved cache locality. | ||||||
|  |    * | ||||||
|  |    * Each component property maintains two state flags: | ||||||
|  |    * - needs_update: Indicates the property requires synchronization with the display | ||||||
|  |    * - is_set: Tracks whether the property has been explicitly configured | ||||||
|  |    * | ||||||
|  |    * The visible field stores both the update flags and the actual visibility state. | ||||||
|  |    */ | ||||||
|  |   struct ComponentState { | ||||||
|  |     // Background color flags | ||||||
|  |     uint16_t bco_needs_update : 1; | ||||||
|  |     uint16_t bco_is_set : 1; | ||||||
|  |  | ||||||
|   // void send_state_to_nextion() = 0; |     // Pressed background color flags | ||||||
|  |     uint16_t bco2_needs_update : 1; | ||||||
|  |     uint16_t bco2_is_set : 1; | ||||||
|  |  | ||||||
|  |     // Foreground color flags | ||||||
|  |     uint16_t pco_needs_update : 1; | ||||||
|  |     uint16_t pco_is_set : 1; | ||||||
|  |  | ||||||
|  |     // Pressed foreground color flags | ||||||
|  |     uint16_t pco2_needs_update : 1; | ||||||
|  |     uint16_t pco2_is_set : 1; | ||||||
|  |  | ||||||
|  |     // Font ID flags | ||||||
|  |     uint16_t font_id_needs_update : 1; | ||||||
|  |     uint16_t font_id_is_set : 1; | ||||||
|  |  | ||||||
|  |     // Visibility flags | ||||||
|  |     uint16_t visible_needs_update : 1; | ||||||
|  |     uint16_t visible_is_set : 1; | ||||||
|  |     uint16_t visible : 1;  // Actual visibility state | ||||||
|  |  | ||||||
|  |     // Reserved bits for future expansion | ||||||
|  |     uint16_t reserved : 3; | ||||||
|  |   } component_flags_; | ||||||
| }; | }; | ||||||
| }  // namespace nextion | }  // namespace nextion | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -53,7 +53,7 @@ void NextionSensor::set_state(float state, bool publish, bool send_to_nextion) { | |||||||
|  |  | ||||||
|   if (this->wave_chan_id_ == UINT8_MAX) { |   if (this->wave_chan_id_ == UINT8_MAX) { | ||||||
|     if (send_to_nextion) { |     if (send_to_nextion) { | ||||||
|       if (this->nextion_->is_sleeping() || !this->visible_) { |       if (this->nextion_->is_sleeping() || !this->component_flags_.visible) { | ||||||
|         this->needs_to_send_update_ = true; |         this->needs_to_send_update_ = true; | ||||||
|       } else { |       } else { | ||||||
|         this->needs_to_send_update_ = false; |         this->needs_to_send_update_ = false; | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ void NextionSwitch::set_state(bool state, bool publish, bool send_to_nextion) { | |||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   if (send_to_nextion) { |   if (send_to_nextion) { | ||||||
|     if (this->nextion_->is_sleeping() || !this->visible_) { |     if (this->nextion_->is_sleeping() || !this->component_flags_.visible) { | ||||||
|       this->needs_to_send_update_ = true; |       this->needs_to_send_update_ = true; | ||||||
|     } else { |     } else { | ||||||
|       this->needs_to_send_update_ = false; |       this->needs_to_send_update_ = false; | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ void NextionTextSensor::set_state(const std::string &state, bool publish, bool s | |||||||
|     return; |     return; | ||||||
|  |  | ||||||
|   if (send_to_nextion) { |   if (send_to_nextion) { | ||||||
|     if (this->nextion_->is_sleeping() || !this->visible_) { |     if (this->nextion_->is_sleeping() || !this->component_flags_.visible) { | ||||||
|       this->needs_to_send_update_ = true; |       this->needs_to_send_update_ = true; | ||||||
|     } else { |     } else { | ||||||
|       this->nextion_->add_no_result_to_queue_with_set(this, state); |       this->nextion_->add_no_result_to_queue_with_set(this, state); | ||||||
|   | |||||||
| @@ -224,7 +224,7 @@ bool SSD1306::is_sh1106_() const { | |||||||
| } | } | ||||||
| bool SSD1306::is_sh1107_() const { return this->model_ == SH1107_MODEL_128_64 || this->model_ == SH1107_MODEL_128_128; } | bool SSD1306::is_sh1107_() const { return this->model_ == SH1107_MODEL_128_64 || this->model_ == SH1107_MODEL_128_128; } | ||||||
| bool SSD1306::is_ssd1305_() const { | bool SSD1306::is_ssd1305_() const { | ||||||
|   return this->model_ == SSD1305_MODEL_128_64 || this->model_ == SSD1305_MODEL_128_64; |   return this->model_ == SSD1305_MODEL_128_64 || this->model_ == SSD1305_MODEL_128_32; | ||||||
| } | } | ||||||
| void SSD1306::update() { | void SSD1306::update() { | ||||||
|   this->do_update_(); |   this->do_update_(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user