mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 07:03:55 +00:00 
			
		
		
		
	Reduce entity memory usage by eliminating field shadowing and bit-packing
This commit is contained in:
		| @@ -11,25 +11,25 @@ static const char *const TAG = "datetime.date_entity"; | |||||||
|  |  | ||||||
| void DateEntity::publish_state() { | void DateEntity::publish_state() { | ||||||
|   if (this->year_ == 0 || this->month_ == 0 || this->day_ == 0) { |   if (this->year_ == 0 || this->month_ == 0 || this->day_ == 0) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->year_ < 1970 || this->year_ > 3000) { |   if (this->year_ < 1970 || this->year_ > 3000) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Year must be between 1970 and 3000"); |     ESP_LOGE(TAG, "Year must be between 1970 and 3000"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->month_ < 1 || this->month_ > 12) { |   if (this->month_ < 1 || this->month_ > 12) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Month must be between 1 and 12"); |     ESP_LOGE(TAG, "Month must be between 1 and 12"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->day_ > days_in_month(this->month_, this->year_)) { |   if (this->day_ > days_in_month(this->month_, this->year_)) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Day must be between 1 and %d for month %d", days_in_month(this->month_, this->year_), this->month_); |     ESP_LOGE(TAG, "Day must be between 1 and %d for month %d", days_in_month(this->month_, this->year_), this->month_); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   this->has_state_ = true; |   this->set_has_state(true); | ||||||
|   ESP_LOGD(TAG, "'%s': Sending date %d-%d-%d", this->get_name().c_str(), this->year_, this->month_, this->day_); |   ESP_LOGD(TAG, "'%s': Sending date %d-%d-%d", this->get_name().c_str(), this->year_, this->month_, this->day_); | ||||||
|   this->state_callback_.call(); |   this->state_callback_.call(); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -13,9 +13,6 @@ namespace datetime { | |||||||
|  |  | ||||||
| class DateTimeBase : public EntityBase { | class DateTimeBase : public EntityBase { | ||||||
|  public: |  public: | ||||||
|   /// Return whether this Datetime has gotten a full state yet. |  | ||||||
|   bool has_state() const { return this->has_state_; } |  | ||||||
|  |  | ||||||
|   virtual ESPTime state_as_esptime() const = 0; |   virtual ESPTime state_as_esptime() const = 0; | ||||||
|  |  | ||||||
|   void add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); } |   void add_on_state_callback(std::function<void()> &&callback) { this->state_callback_.add(std::move(callback)); } | ||||||
| @@ -31,8 +28,6 @@ class DateTimeBase : public EntityBase { | |||||||
| #ifdef USE_TIME | #ifdef USE_TIME | ||||||
|   time::RealTimeClock *rtc_; |   time::RealTimeClock *rtc_; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   bool has_state_{false}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #ifdef USE_TIME | #ifdef USE_TIME | ||||||
|   | |||||||
| @@ -11,40 +11,40 @@ static const char *const TAG = "datetime.datetime_entity"; | |||||||
|  |  | ||||||
| void DateTimeEntity::publish_state() { | void DateTimeEntity::publish_state() { | ||||||
|   if (this->year_ == 0 || this->month_ == 0 || this->day_ == 0) { |   if (this->year_ == 0 || this->month_ == 0 || this->day_ == 0) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->year_ < 1970 || this->year_ > 3000) { |   if (this->year_ < 1970 || this->year_ > 3000) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Year must be between 1970 and 3000"); |     ESP_LOGE(TAG, "Year must be between 1970 and 3000"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->month_ < 1 || this->month_ > 12) { |   if (this->month_ < 1 || this->month_ > 12) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Month must be between 1 and 12"); |     ESP_LOGE(TAG, "Month must be between 1 and 12"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->day_ > days_in_month(this->month_, this->year_)) { |   if (this->day_ > days_in_month(this->month_, this->year_)) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Day must be between 1 and %d for month %d", days_in_month(this->month_, this->year_), this->month_); |     ESP_LOGE(TAG, "Day must be between 1 and %d for month %d", days_in_month(this->month_, this->year_), this->month_); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->hour_ > 23) { |   if (this->hour_ > 23) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Hour must be between 0 and 23"); |     ESP_LOGE(TAG, "Hour must be between 0 and 23"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->minute_ > 59) { |   if (this->minute_ > 59) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Minute must be between 0 and 59"); |     ESP_LOGE(TAG, "Minute must be between 0 and 59"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->second_ > 59) { |   if (this->second_ > 59) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Second must be between 0 and 59"); |     ESP_LOGE(TAG, "Second must be between 0 and 59"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   this->has_state_ = true; |   this->set_has_state(true); | ||||||
|   ESP_LOGD(TAG, "'%s': Sending datetime %04u-%02u-%02u %02d:%02d:%02d", this->get_name().c_str(), this->year_, |   ESP_LOGD(TAG, "'%s': Sending datetime %04u-%02u-%02u %02d:%02d:%02d", this->get_name().c_str(), this->year_, | ||||||
|            this->month_, this->day_, this->hour_, this->minute_, this->second_); |            this->month_, this->day_, this->hour_, this->minute_, this->second_); | ||||||
|   this->state_callback_.call(); |   this->state_callback_.call(); | ||||||
|   | |||||||
| @@ -11,21 +11,21 @@ static const char *const TAG = "datetime.time_entity"; | |||||||
|  |  | ||||||
| void TimeEntity::publish_state() { | void TimeEntity::publish_state() { | ||||||
|   if (this->hour_ > 23) { |   if (this->hour_ > 23) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Hour must be between 0 and 23"); |     ESP_LOGE(TAG, "Hour must be between 0 and 23"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->minute_ > 59) { |   if (this->minute_ > 59) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Minute must be between 0 and 59"); |     ESP_LOGE(TAG, "Minute must be between 0 and 59"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   if (this->second_ > 59) { |   if (this->second_ > 59) { | ||||||
|     this->has_state_ = false; |     this->set_has_state(false); | ||||||
|     ESP_LOGE(TAG, "Second must be between 0 and 59"); |     ESP_LOGE(TAG, "Second must be between 0 and 59"); | ||||||
|     return; |     return; | ||||||
|   } |   } | ||||||
|   this->has_state_ = true; |   this->set_has_state(true); | ||||||
|   ESP_LOGD(TAG, "'%s': Sending time %02d:%02d:%02d", this->get_name().c_str(), this->hour_, this->minute_, |   ESP_LOGD(TAG, "'%s': Sending time %02d:%02d:%02d", this->get_name().c_str(), this->hour_, this->minute_, | ||||||
|            this->second_); |            this->second_); | ||||||
|   this->state_callback_.call(); |   this->state_callback_.call(); | ||||||
|   | |||||||
| @@ -56,7 +56,7 @@ void NextionBinarySensor::set_state(bool state, bool publish, bool send_to_nexti | |||||||
|     this->publish_state(state); |     this->publish_state(state); | ||||||
|   } else { |   } else { | ||||||
|     this->state = state; |     this->state = state; | ||||||
|     this->has_state_ = true; |     this->set_has_state(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
|   | |||||||
| @@ -88,7 +88,7 @@ void NextionSensor::set_state(float state, bool publish, bool send_to_nextion) { | |||||||
|     } else { |     } else { | ||||||
|       this->raw_state = state; |       this->raw_state = state; | ||||||
|       this->state = state; |       this->state = state; | ||||||
|       this->has_state_ = true; |       this->set_has_state(true); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
|   | |||||||
| @@ -37,7 +37,7 @@ void NextionTextSensor::set_state(const std::string &state, bool publish, bool s | |||||||
|     this->publish_state(state); |     this->publish_state(state); | ||||||
|   } else { |   } else { | ||||||
|     this->state = state; |     this->state = state; | ||||||
|     this->has_state_ = true; |     this->set_has_state(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   this->update_component_settings(); |   this->update_component_settings(); | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ namespace number { | |||||||
| static const char *const TAG = "number"; | static const char *const TAG = "number"; | ||||||
|  |  | ||||||
| void Number::publish_state(float state) { | void Number::publish_state(float state) { | ||||||
|   this->has_state_ = true; |   this->set_has_state(true); | ||||||
|   this->state = state; |   this->state = state; | ||||||
|   ESP_LOGD(TAG, "'%s': Sending state %f", this->get_name().c_str(), state); |   ESP_LOGD(TAG, "'%s': Sending state %f", this->get_name().c_str(), state); | ||||||
|   this->state_callback_.call(state); |   this->state_callback_.call(state); | ||||||
|   | |||||||
| @@ -48,9 +48,6 @@ class Number : public EntityBase { | |||||||
|  |  | ||||||
|   NumberTraits traits; |   NumberTraits traits; | ||||||
|  |  | ||||||
|   /// Return whether this number has gotten a full state yet. |  | ||||||
|   bool has_state() const { return has_state_; } |  | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   friend class NumberCall; |   friend class NumberCall; | ||||||
|  |  | ||||||
| @@ -63,7 +60,6 @@ class Number : public EntityBase { | |||||||
|   virtual void control(float value) = 0; |   virtual void control(float value) = 0; | ||||||
|  |  | ||||||
|   CallbackManager<void(float)> state_callback_; |   CallbackManager<void(float)> state_callback_; | ||||||
|   bool has_state_{false}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace number | }  // namespace number | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ void Select::publish_state(const std::string &state) { | |||||||
|   auto index = this->index_of(state); |   auto index = this->index_of(state); | ||||||
|   const auto *name = this->get_name().c_str(); |   const auto *name = this->get_name().c_str(); | ||||||
|   if (index.has_value()) { |   if (index.has_value()) { | ||||||
|     this->has_state_ = true; |     this->set_has_state(true); | ||||||
|     this->state = state; |     this->state = state; | ||||||
|     ESP_LOGD(TAG, "'%s': Sending state %s (index %zu)", name, state.c_str(), index.value()); |     ESP_LOGD(TAG, "'%s': Sending state %s (index %zu)", name, state.c_str(), index.value()); | ||||||
|     this->state_callback_.call(state, index.value()); |     this->state_callback_.call(state, index.value()); | ||||||
|   | |||||||
| @@ -35,9 +35,6 @@ class Select : public EntityBase { | |||||||
|  |  | ||||||
|   void publish_state(const std::string &state); |   void publish_state(const std::string &state); | ||||||
|  |  | ||||||
|   /// Return whether this select component has gotten a full state yet. |  | ||||||
|   bool has_state() const { return has_state_; } |  | ||||||
|  |  | ||||||
|   /// Instantiate a SelectCall object to modify this select component's state. |   /// Instantiate a SelectCall object to modify this select component's state. | ||||||
|   SelectCall make_call() { return SelectCall(this); } |   SelectCall make_call() { return SelectCall(this); } | ||||||
|  |  | ||||||
| @@ -73,7 +70,6 @@ class Select : public EntityBase { | |||||||
|   virtual void control(const std::string &value) = 0; |   virtual void control(const std::string &value) = 0; | ||||||
|  |  | ||||||
|   CallbackManager<void(std::string, size_t)> state_callback_; |   CallbackManager<void(std::string, size_t)> state_callback_; | ||||||
|   bool has_state_{false}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace select | }  // namespace select | ||||||
|   | |||||||
| @@ -88,13 +88,12 @@ float Sensor::get_raw_state() const { return this->raw_state; } | |||||||
| std::string Sensor::unique_id() { return ""; } | std::string Sensor::unique_id() { return ""; } | ||||||
|  |  | ||||||
| void Sensor::internal_send_state_to_frontend(float state) { | void Sensor::internal_send_state_to_frontend(float state) { | ||||||
|   this->has_state_ = true; |   this->set_has_state(true); | ||||||
|   this->state = state; |   this->state = state; | ||||||
|   ESP_LOGD(TAG, "'%s': Sending state %.5f %s with %d decimals of accuracy", this->get_name().c_str(), state, |   ESP_LOGD(TAG, "'%s': Sending state %.5f %s with %d decimals of accuracy", this->get_name().c_str(), state, | ||||||
|            this->get_unit_of_measurement().c_str(), this->get_accuracy_decimals()); |            this->get_unit_of_measurement().c_str(), this->get_accuracy_decimals()); | ||||||
|   this->callback_.call(state); |   this->callback_.call(state); | ||||||
| } | } | ||||||
| bool Sensor::has_state() const { return this->has_state_; } |  | ||||||
|  |  | ||||||
| }  // namespace sensor | }  // namespace sensor | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -140,9 +140,6 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa | |||||||
|    */ |    */ | ||||||
|   float raw_state; |   float raw_state; | ||||||
|  |  | ||||||
|   /// Return whether this sensor has gotten a full state (that passed through all filters) yet. |  | ||||||
|   bool has_state() const; |  | ||||||
|  |  | ||||||
|   /** Override this method to set the unique ID of this sensor. |   /** Override this method to set the unique ID of this sensor. | ||||||
|    * |    * | ||||||
|    * @deprecated Do not use for new sensors, a suitable unique ID is automatically generated (2023.4). |    * @deprecated Do not use for new sensors, a suitable unique ID is automatically generated (2023.4). | ||||||
| @@ -160,7 +157,6 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa | |||||||
|   optional<int8_t> accuracy_decimals_;                  ///< Accuracy in decimals override |   optional<int8_t> accuracy_decimals_;                  ///< Accuracy in decimals override | ||||||
|   optional<StateClass> state_class_{STATE_CLASS_NONE};  ///< State class override |   optional<StateClass> state_class_{STATE_CLASS_NONE};  ///< State class override | ||||||
|   bool force_update_{false};                            ///< Force update mode |   bool force_update_{false};                            ///< Force update mode | ||||||
|   bool has_state_{false}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace sensor | }  // namespace sensor | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ namespace text { | |||||||
| static const char *const TAG = "text"; | static const char *const TAG = "text"; | ||||||
|  |  | ||||||
| void Text::publish_state(const std::string &state) { | void Text::publish_state(const std::string &state) { | ||||||
|   this->has_state_ = true; |   this->set_has_state(true); | ||||||
|   this->state = state; |   this->state = state; | ||||||
|   if (this->traits.get_mode() == TEXT_MODE_PASSWORD) { |   if (this->traits.get_mode() == TEXT_MODE_PASSWORD) { | ||||||
|     ESP_LOGD(TAG, "'%s': Sending state " LOG_SECRET("'%s'"), this->get_name().c_str(), state.c_str()); |     ESP_LOGD(TAG, "'%s': Sending state " LOG_SECRET("'%s'"), this->get_name().c_str(), state.c_str()); | ||||||
|   | |||||||
| @@ -28,9 +28,6 @@ class Text : public EntityBase { | |||||||
|  |  | ||||||
|   void publish_state(const std::string &state); |   void publish_state(const std::string &state); | ||||||
|  |  | ||||||
|   /// Return whether this text input has gotten a full state yet. |  | ||||||
|   bool has_state() const { return has_state_; } |  | ||||||
|  |  | ||||||
|   /// Instantiate a TextCall object to modify this text component's state. |   /// Instantiate a TextCall object to modify this text component's state. | ||||||
|   TextCall make_call() { return TextCall(this); } |   TextCall make_call() { return TextCall(this); } | ||||||
|  |  | ||||||
| @@ -48,7 +45,6 @@ class Text : public EntityBase { | |||||||
|   virtual void control(const std::string &value) = 0; |   virtual void control(const std::string &value) = 0; | ||||||
|  |  | ||||||
|   CallbackManager<void(std::string)> state_callback_; |   CallbackManager<void(std::string)> state_callback_; | ||||||
|   bool has_state_{false}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace text | }  // namespace text | ||||||
|   | |||||||
| @@ -60,13 +60,12 @@ std::string TextSensor::get_state() const { return this->state; } | |||||||
| std::string TextSensor::get_raw_state() const { return this->raw_state; } | std::string TextSensor::get_raw_state() const { return this->raw_state; } | ||||||
| void TextSensor::internal_send_state_to_frontend(const std::string &state) { | void TextSensor::internal_send_state_to_frontend(const std::string &state) { | ||||||
|   this->state = state; |   this->state = state; | ||||||
|   this->has_state_ = true; |   this->set_has_state(true); | ||||||
|   ESP_LOGD(TAG, "'%s': Sending state '%s'", this->name_.c_str(), state.c_str()); |   ESP_LOGD(TAG, "'%s': Sending state '%s'", this->name_.c_str(), state.c_str()); | ||||||
|   this->callback_.call(state); |   this->callback_.call(state); | ||||||
| } | } | ||||||
|  |  | ||||||
| std::string TextSensor::unique_id() { return ""; } | std::string TextSensor::unique_id() { return ""; } | ||||||
| bool TextSensor::has_state() { return this->has_state_; } |  | ||||||
|  |  | ||||||
| }  // namespace text_sensor | }  // namespace text_sensor | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -67,8 +67,6 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass { | |||||||
|    */ |    */ | ||||||
|   virtual std::string unique_id(); |   virtual std::string unique_id(); | ||||||
|  |  | ||||||
|   bool has_state(); |  | ||||||
|  |  | ||||||
|   void internal_send_state_to_frontend(const std::string &state); |   void internal_send_state_to_frontend(const std::string &state); | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
| @@ -76,8 +74,6 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass { | |||||||
|   CallbackManager<void(std::string)> callback_;      ///< Storage for filtered state callbacks. |   CallbackManager<void(std::string)> callback_;      ///< Storage for filtered state callbacks. | ||||||
|  |  | ||||||
|   Filter *filter_list_{nullptr};  ///< Store all active filters. |   Filter *filter_list_{nullptr};  ///< Store all active filters. | ||||||
|  |  | ||||||
|   bool has_state_{false}; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace text_sensor | }  // namespace text_sensor | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ void UpdateEntity::publish_state() { | |||||||
|     ESP_LOGD(TAG, "  Progress: %.0f%%", this->update_info_.progress); |     ESP_LOGD(TAG, "  Progress: %.0f%%", this->update_info_.progress); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   this->has_state_ = true; |   this->set_has_state(true); | ||||||
|   this->state_callback_.call(); |   this->state_callback_.call(); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,8 +28,6 @@ enum UpdateState : uint8_t { | |||||||
|  |  | ||||||
| class UpdateEntity : public EntityBase, public EntityBase_DeviceClass { | class UpdateEntity : public EntityBase, public EntityBase_DeviceClass { | ||||||
|  public: |  public: | ||||||
|   bool has_state() const { return this->has_state_; } |  | ||||||
|  |  | ||||||
|   void publish_state(); |   void publish_state(); | ||||||
|  |  | ||||||
|   void perform() { this->perform(false); } |   void perform() { this->perform(false); } | ||||||
| @@ -44,7 +42,6 @@ class UpdateEntity : public EntityBase, public EntityBase_DeviceClass { | |||||||
|  protected: |  protected: | ||||||
|   UpdateState state_{UPDATE_STATE_UNKNOWN}; |   UpdateState state_{UPDATE_STATE_UNKNOWN}; | ||||||
|   UpdateInfo update_info_; |   UpdateInfo update_info_; | ||||||
|   bool has_state_{false}; |  | ||||||
|  |  | ||||||
|   CallbackManager<void()> state_callback_{}; |   CallbackManager<void()> state_callback_{}; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ static const char *const TAG = "uptime.sensor"; | |||||||
|  |  | ||||||
| void UptimeTimestampSensor::setup() { | void UptimeTimestampSensor::setup() { | ||||||
|   this->time_->add_on_time_sync_callback([this]() { |   this->time_->add_on_time_sync_callback([this]() { | ||||||
|     if (this->has_state_) |     if (this->has_state()) | ||||||
|       return;  // No need to update the timestamp if it's already set |       return;  // No need to update the timestamp if it's already set | ||||||
|  |  | ||||||
|     auto now = this->time_->now(); |     auto now = this->time_->now(); | ||||||
|   | |||||||
| @@ -12,20 +12,12 @@ void EntityBase::set_name(const char *name) { | |||||||
|   this->name_ = StringRef(name); |   this->name_ = StringRef(name); | ||||||
|   if (this->name_.empty()) { |   if (this->name_.empty()) { | ||||||
|     this->name_ = StringRef(App.get_friendly_name()); |     this->name_ = StringRef(App.get_friendly_name()); | ||||||
|     this->has_own_name_ = false; |     this->flags_.has_own_name = false; | ||||||
|   } else { |   } else { | ||||||
|     this->has_own_name_ = true; |     this->flags_.has_own_name = true; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| // Entity Internal |  | ||||||
| bool EntityBase::is_internal() const { return this->internal_; } |  | ||||||
| void EntityBase::set_internal(bool internal) { this->internal_ = internal; } |  | ||||||
|  |  | ||||||
| // Entity Disabled by Default |  | ||||||
| bool EntityBase::is_disabled_by_default() const { return this->disabled_by_default_; } |  | ||||||
| void EntityBase::set_disabled_by_default(bool disabled_by_default) { this->disabled_by_default_ = disabled_by_default; } |  | ||||||
|  |  | ||||||
| // Entity Icon | // Entity Icon | ||||||
| std::string EntityBase::get_icon() const { | std::string EntityBase::get_icon() const { | ||||||
|   if (this->icon_c_str_ == nullptr) { |   if (this->icon_c_str_ == nullptr) { | ||||||
| @@ -35,14 +27,10 @@ std::string EntityBase::get_icon() const { | |||||||
| } | } | ||||||
| void EntityBase::set_icon(const char *icon) { this->icon_c_str_ = icon; } | void EntityBase::set_icon(const char *icon) { this->icon_c_str_ = icon; } | ||||||
|  |  | ||||||
| // Entity Category |  | ||||||
| EntityCategory EntityBase::get_entity_category() const { return this->entity_category_; } |  | ||||||
| void EntityBase::set_entity_category(EntityCategory entity_category) { this->entity_category_ = entity_category; } |  | ||||||
|  |  | ||||||
| // Entity Object ID | // Entity Object ID | ||||||
| std::string EntityBase::get_object_id() const { | std::string EntityBase::get_object_id() const { | ||||||
|   // Check if `App.get_friendly_name()` is constant or dynamic. |   // Check if `App.get_friendly_name()` is constant or dynamic. | ||||||
|   if (!this->has_own_name_ && App.is_name_add_mac_suffix_enabled()) { |   if (!this->flags_.has_own_name && App.is_name_add_mac_suffix_enabled()) { | ||||||
|     // `App.get_friendly_name()` is dynamic. |     // `App.get_friendly_name()` is dynamic. | ||||||
|     return str_sanitize(str_snake_case(App.get_friendly_name())); |     return str_sanitize(str_snake_case(App.get_friendly_name())); | ||||||
|   } else { |   } else { | ||||||
| @@ -61,7 +49,7 @@ void EntityBase::set_object_id(const char *object_id) { | |||||||
| // Calculate Object ID Hash from Entity Name | // Calculate Object ID Hash from Entity Name | ||||||
| void EntityBase::calc_object_id_() { | void EntityBase::calc_object_id_() { | ||||||
|   // Check if `App.get_friendly_name()` is constant or dynamic. |   // Check if `App.get_friendly_name()` is constant or dynamic. | ||||||
|   if (!this->has_own_name_ && App.is_name_add_mac_suffix_enabled()) { |   if (!this->flags_.has_own_name && App.is_name_add_mac_suffix_enabled()) { | ||||||
|     // `App.get_friendly_name()` is dynamic. |     // `App.get_friendly_name()` is dynamic. | ||||||
|     const auto object_id = str_sanitize(str_snake_case(App.get_friendly_name())); |     const auto object_id = str_sanitize(str_snake_case(App.get_friendly_name())); | ||||||
|     // FNV-1 hash |     // FNV-1 hash | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ class EntityBase { | |||||||
|   void set_name(const char *name); |   void set_name(const char *name); | ||||||
|  |  | ||||||
|   // Get whether this Entity has its own name or it should use the device friendly_name. |   // Get whether this Entity has its own name or it should use the device friendly_name. | ||||||
|   bool has_own_name() const { return this->has_own_name_; } |   bool has_own_name() const { return this->flags_.has_own_name; } | ||||||
|  |  | ||||||
|   // Get the sanitized name of this Entity as an ID. |   // Get the sanitized name of this Entity as an ID. | ||||||
|   std::string get_object_id() const; |   std::string get_object_id() const; | ||||||
| @@ -32,38 +32,51 @@ class EntityBase { | |||||||
|   uint32_t get_object_id_hash(); |   uint32_t get_object_id_hash(); | ||||||
|  |  | ||||||
|   // Get/set whether this Entity should be hidden outside ESPHome |   // Get/set whether this Entity should be hidden outside ESPHome | ||||||
|   bool is_internal() const; |   bool is_internal() const { return this->flags_.internal; } | ||||||
|   void set_internal(bool internal); |   void set_internal(bool internal) { this->flags_.internal = internal; } | ||||||
|  |  | ||||||
|   // Check if this object is declared to be disabled by default. |   // Check if this object is declared to be disabled by default. | ||||||
|   // That means that when the device gets added to Home Assistant (or other clients) it should |   // That means that when the device gets added to Home Assistant (or other clients) it should | ||||||
|   // not be added to the default view by default, and a user action is necessary to manually add it. |   // not be added to the default view by default, and a user action is necessary to manually add it. | ||||||
|   bool is_disabled_by_default() const; |   bool is_disabled_by_default() const { return this->flags_.disabled_by_default; } | ||||||
|   void set_disabled_by_default(bool disabled_by_default); |   void set_disabled_by_default(bool disabled_by_default) { this->flags_.disabled_by_default = disabled_by_default; } | ||||||
|  |  | ||||||
|   // Get/set the entity category. |   // Get/set the entity category. | ||||||
|   EntityCategory get_entity_category() const; |   EntityCategory get_entity_category() const { return static_cast<EntityCategory>(this->flags_.entity_category); } | ||||||
|   void set_entity_category(EntityCategory entity_category); |   void set_entity_category(EntityCategory entity_category) { | ||||||
|  |     this->flags_.entity_category = static_cast<uint8_t>(entity_category); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // Get/set this entity's icon |   // Get/set this entity's icon | ||||||
|   std::string get_icon() const; |   std::string get_icon() const; | ||||||
|   void set_icon(const char *icon); |   void set_icon(const char *icon); | ||||||
|  |  | ||||||
|  |   // Check if this entity has state | ||||||
|  |   bool has_state() const { return this->flags_.has_state; } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   /// The hash_base() function has been deprecated. It is kept in this |   /// The hash_base() function has been deprecated. It is kept in this | ||||||
|   /// class for now, to prevent external components from not compiling. |   /// class for now, to prevent external components from not compiling. | ||||||
|   virtual uint32_t hash_base() { return 0L; } |   virtual uint32_t hash_base() { return 0L; } | ||||||
|   void calc_object_id_(); |   void calc_object_id_(); | ||||||
|  |  | ||||||
|  |   // Helper method for components that need to set has_state | ||||||
|  |   void set_has_state(bool state) { this->flags_.has_state = state; } | ||||||
|  |  | ||||||
|   StringRef name_; |   StringRef name_; | ||||||
|   const char *object_id_c_str_{nullptr}; |   const char *object_id_c_str_{nullptr}; | ||||||
|   const char *icon_c_str_{nullptr}; |   const char *icon_c_str_{nullptr}; | ||||||
|   uint32_t object_id_hash_{}; |   uint32_t object_id_hash_{}; | ||||||
|   bool has_own_name_{false}; |  | ||||||
|   bool internal_{false}; |   // Bit-packed flags to save memory (1 byte instead of 5) | ||||||
|   bool disabled_by_default_{false}; |   struct EntityFlags { | ||||||
|   EntityCategory entity_category_{ENTITY_CATEGORY_NONE}; |     uint8_t has_own_name : 1; | ||||||
|   bool has_state_{}; |     uint8_t internal : 1; | ||||||
|  |     uint8_t disabled_by_default : 1; | ||||||
|  |     uint8_t has_state : 1; | ||||||
|  |     uint8_t entity_category : 2;  // Supports up to 4 categories | ||||||
|  |     uint8_t reserved : 2;         // Reserved for future use | ||||||
|  |   } flags_{}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class EntityBase_DeviceClass {  // NOLINT(readability-identifier-naming) | class EntityBase_DeviceClass {  // NOLINT(readability-identifier-naming) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user