mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +00:00 
			
		
		
		
	Reduce API component memory usage with conditional compilation
This commit is contained in:
		| @@ -135,7 +135,9 @@ async def to_code(config): | |||||||
|     cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) |     cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT])) | ||||||
|     cg.add(var.set_batch_delay(config[CONF_BATCH_DELAY])) |     cg.add(var.set_batch_delay(config[CONF_BATCH_DELAY])) | ||||||
|  |  | ||||||
|     for conf in config.get(CONF_ACTIONS, []): |     if actions := config.get(CONF_ACTIONS, []): | ||||||
|  |         cg.add_define("USE_API_YAML_SERVICES") | ||||||
|  |         for conf in actions: | ||||||
|             template_args = [] |             template_args = [] | ||||||
|             func_args = [] |             func_args = [] | ||||||
|             service_arg_names = [] |             service_arg_names = [] | ||||||
| @@ -152,6 +154,7 @@ async def to_code(config): | |||||||
|             await automation.build_automation(trigger, func_args, conf) |             await automation.build_automation(trigger, func_args, conf) | ||||||
|  |  | ||||||
|     if CONF_ON_CLIENT_CONNECTED in config: |     if CONF_ON_CLIENT_CONNECTED in config: | ||||||
|  |         cg.add_define("USE_API_CLIENT_CONNECTED_TRIGGER") | ||||||
|         await automation.build_automation( |         await automation.build_automation( | ||||||
|             var.get_client_connected_trigger(), |             var.get_client_connected_trigger(), | ||||||
|             [(cg.std_string, "client_info"), (cg.std_string, "client_address")], |             [(cg.std_string, "client_info"), (cg.std_string, "client_address")], | ||||||
| @@ -159,6 +162,7 @@ async def to_code(config): | |||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     if CONF_ON_CLIENT_DISCONNECTED in config: |     if CONF_ON_CLIENT_DISCONNECTED in config: | ||||||
|  |         cg.add_define("USE_API_CLIENT_DISCONNECTED_TRIGGER") | ||||||
|         await automation.build_automation( |         await automation.build_automation( | ||||||
|             var.get_client_disconnected_trigger(), |             var.get_client_disconnected_trigger(), | ||||||
|             [(cg.std_string, "client_info"), (cg.std_string, "client_address")], |             [(cg.std_string, "client_info"), (cg.std_string, "client_address")], | ||||||
|   | |||||||
| @@ -1582,7 +1582,9 @@ ConnectResponse APIConnection::connect(const ConnectRequest &msg) { | |||||||
|   if (correct) { |   if (correct) { | ||||||
|     ESP_LOGD(TAG, "%s connected", this->get_client_combined_info().c_str()); |     ESP_LOGD(TAG, "%s connected", this->get_client_combined_info().c_str()); | ||||||
|     this->connection_state_ = ConnectionState::AUTHENTICATED; |     this->connection_state_ = ConnectionState::AUTHENTICATED; | ||||||
|  | #ifdef USE_API_CLIENT_CONNECTED_TRIGGER | ||||||
|     this->parent_->get_client_connected_trigger()->trigger(this->client_info_, this->client_peername_); |     this->parent_->get_client_connected_trigger()->trigger(this->client_info_, this->client_peername_); | ||||||
|  | #endif | ||||||
| #ifdef USE_HOMEASSISTANT_TIME | #ifdef USE_HOMEASSISTANT_TIME | ||||||
|     if (homeassistant::global_homeassistant_time != nullptr) { |     if (homeassistant::global_homeassistant_time != nullptr) { | ||||||
|       this->send_time_request(); |       this->send_time_request(); | ||||||
|   | |||||||
| @@ -184,7 +184,9 @@ void APIServer::loop() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Rare case: handle disconnection |     // Rare case: handle disconnection | ||||||
|  | #ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER | ||||||
|     this->client_disconnected_trigger_->trigger(client->client_info_, client->client_peername_); |     this->client_disconnected_trigger_->trigger(client->client_info_, client->client_peername_); | ||||||
|  | #endif | ||||||
|     ESP_LOGV(TAG, "Remove connection %s", client->client_info_.c_str()); |     ESP_LOGV(TAG, "Remove connection %s", client->client_info_.c_str()); | ||||||
|  |  | ||||||
|     // Swap with the last element and pop (avoids expensive vector shifts) |     // Swap with the last element and pop (avoids expensive vector shifts) | ||||||
|   | |||||||
| @@ -105,7 +105,18 @@ class APIServer : public Component, public Controller { | |||||||
|   void on_media_player_update(media_player::MediaPlayer *obj) override; |   void on_media_player_update(media_player::MediaPlayer *obj) override; | ||||||
| #endif | #endif | ||||||
|   void send_homeassistant_service_call(const HomeassistantServiceResponse &call); |   void send_homeassistant_service_call(const HomeassistantServiceResponse &call); | ||||||
|   void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); } |   void register_user_service(UserServiceDescriptor *descriptor) { | ||||||
|  | #ifdef USE_API_YAML_SERVICES | ||||||
|  |     // Vector is pre-allocated when services are defined in YAML | ||||||
|  |     this->user_services_.push_back(descriptor); | ||||||
|  | #else | ||||||
|  |     // Lazy allocate vector on first use for CustomAPIDevice | ||||||
|  |     if (!this->user_services_) { | ||||||
|  |       this->user_services_ = std::make_unique<std::vector<UserServiceDescriptor *>>(); | ||||||
|  |     } | ||||||
|  |     this->user_services_->push_back(descriptor); | ||||||
|  | #endif | ||||||
|  |   } | ||||||
| #ifdef USE_HOMEASSISTANT_TIME | #ifdef USE_HOMEASSISTANT_TIME | ||||||
|   void request_time(); |   void request_time(); | ||||||
| #endif | #endif | ||||||
| @@ -134,19 +145,34 @@ class APIServer : public Component, public Controller { | |||||||
|   void get_home_assistant_state(std::string entity_id, optional<std::string> attribute, |   void get_home_assistant_state(std::string entity_id, optional<std::string> attribute, | ||||||
|                                 std::function<void(std::string)> f); |                                 std::function<void(std::string)> f); | ||||||
|   const std::vector<HomeAssistantStateSubscription> &get_state_subs() const; |   const std::vector<HomeAssistantStateSubscription> &get_state_subs() const; | ||||||
|   const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; } |   const std::vector<UserServiceDescriptor *> &get_user_services() const { | ||||||
|  | #ifdef USE_API_YAML_SERVICES | ||||||
|  |     return this->user_services_; | ||||||
|  | #else | ||||||
|  |     static const std::vector<UserServiceDescriptor *> empty; | ||||||
|  |     return this->user_services_ ? *this->user_services_ : empty; | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #ifdef USE_API_CLIENT_CONNECTED_TRIGGER | ||||||
|   Trigger<std::string, std::string> *get_client_connected_trigger() const { return this->client_connected_trigger_; } |   Trigger<std::string, std::string> *get_client_connected_trigger() const { return this->client_connected_trigger_; } | ||||||
|  | #endif | ||||||
|  | #ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER | ||||||
|   Trigger<std::string, std::string> *get_client_disconnected_trigger() const { |   Trigger<std::string, std::string> *get_client_disconnected_trigger() const { | ||||||
|     return this->client_disconnected_trigger_; |     return this->client_disconnected_trigger_; | ||||||
|   } |   } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   void schedule_reboot_timeout_(); |   void schedule_reboot_timeout_(); | ||||||
|   // Pointers and pointer-like types first (4 bytes each) |   // Pointers and pointer-like types first (4 bytes each) | ||||||
|   std::unique_ptr<socket::Socket> socket_ = nullptr; |   std::unique_ptr<socket::Socket> socket_ = nullptr; | ||||||
|  | #ifdef USE_API_CLIENT_CONNECTED_TRIGGER | ||||||
|   Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>(); |   Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>(); | ||||||
|  | #endif | ||||||
|  | #ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER | ||||||
|   Trigger<std::string, std::string> *client_disconnected_trigger_ = new Trigger<std::string, std::string>(); |   Trigger<std::string, std::string> *client_disconnected_trigger_ = new Trigger<std::string, std::string>(); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|   // 4-byte aligned types |   // 4-byte aligned types | ||||||
|   uint32_t reboot_timeout_{300000}; |   uint32_t reboot_timeout_{300000}; | ||||||
| @@ -157,7 +183,15 @@ class APIServer : public Component, public Controller { | |||||||
|   std::string password_; |   std::string password_; | ||||||
|   std::vector<uint8_t> shared_write_buffer_;  // Shared proto write buffer for all connections |   std::vector<uint8_t> shared_write_buffer_;  // Shared proto write buffer for all connections | ||||||
|   std::vector<HomeAssistantStateSubscription> state_subs_; |   std::vector<HomeAssistantStateSubscription> state_subs_; | ||||||
|  | #ifdef USE_API_YAML_SERVICES | ||||||
|  |   // When services are defined in YAML, we know at compile time that services will be registered | ||||||
|   std::vector<UserServiceDescriptor *> user_services_; |   std::vector<UserServiceDescriptor *> user_services_; | ||||||
|  | #else | ||||||
|  |   // Services can still be registered at runtime by CustomAPIDevice components even when not | ||||||
|  |   // defined in YAML. Using unique_ptr allows lazy allocation, saving 12 bytes in the common | ||||||
|  |   // case where no services (YAML or custom) are used. | ||||||
|  |   std::unique_ptr<std::vector<UserServiceDescriptor *>> user_services_; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|   // Group smaller types together |   // Group smaller types together | ||||||
|   uint16_t port_{6053}; |   uint16_t port_{6053}; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user