mirror of
https://github.com/esphome/esphome.git
synced 2025-08-10 12:27:46 +00:00
Reduce API component memory usage with conditional compilation
This commit is contained in:
@@ -135,23 +135,26 @@ 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, []):
|
||||||
template_args = []
|
cg.add_define("USE_API_YAML_SERVICES")
|
||||||
func_args = []
|
for conf in actions:
|
||||||
service_arg_names = []
|
template_args = []
|
||||||
for name, var_ in conf[CONF_VARIABLES].items():
|
func_args = []
|
||||||
native = SERVICE_ARG_NATIVE_TYPES[var_]
|
service_arg_names = []
|
||||||
template_args.append(native)
|
for name, var_ in conf[CONF_VARIABLES].items():
|
||||||
func_args.append((native, name))
|
native = SERVICE_ARG_NATIVE_TYPES[var_]
|
||||||
service_arg_names.append(name)
|
template_args.append(native)
|
||||||
templ = cg.TemplateArguments(*template_args)
|
func_args.append((native, name))
|
||||||
trigger = cg.new_Pvariable(
|
service_arg_names.append(name)
|
||||||
conf[CONF_TRIGGER_ID], templ, conf[CONF_ACTION], service_arg_names
|
templ = cg.TemplateArguments(*template_args)
|
||||||
)
|
trigger = cg.new_Pvariable(
|
||||||
cg.add(var.register_user_service(trigger))
|
conf[CONF_TRIGGER_ID], templ, conf[CONF_ACTION], service_arg_names
|
||||||
await automation.build_automation(trigger, func_args, conf)
|
)
|
||||||
|
cg.add(var.register_user_service(trigger))
|
||||||
|
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