ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
api_server.h
Go to the documentation of this file.
1#pragma once
2
4#ifdef USE_API
5#include "api_noise_context.h"
6#include "api_pb2.h"
7#include "api_pb2_service.h"
12#include "esphome/core/log.h"
14#include "list_entities.h"
15#include "subscribe_state.h"
16#ifdef USE_LOGGER
18#endif
19#ifdef USE_CAMERA
21#endif
22
23#include <vector>
24
25namespace esphome::api {
26
27#ifdef USE_API_USER_DEFINED_ACTIONS
28// Forward declaration - full definition in user_services.h
29class UserServiceDescriptor;
30#endif
31
32#ifdef USE_API_NOISE
35} PACKED; // NOLINT
36#endif
37
38class APIServer : public Component,
39 public Controller
40#ifdef USE_CAMERA
41 ,
43#endif
44{
45 public:
46 APIServer();
47 void setup() override;
48 uint16_t get_port() const;
49 float get_setup_priority() const override;
50 void loop() override;
51 void dump_config() override;
52 void on_shutdown() override;
53 bool teardown() override;
54#ifdef USE_LOGGER
55 void on_log(uint8_t level, const char *tag, const char *message, size_t message_len);
56#endif
57#ifdef USE_CAMERA
58 void on_camera_image(const std::shared_ptr<camera::CameraImage> &image) override;
59#endif
60 void set_port(uint16_t port);
61 void set_reboot_timeout(uint32_t reboot_timeout);
62 void set_batch_delay(uint16_t batch_delay);
63 uint16_t get_batch_delay() const { return batch_delay_; }
64 void set_listen_backlog(uint8_t listen_backlog) { this->listen_backlog_ = listen_backlog; }
65 void set_max_connections(uint8_t max_connections) { this->max_connections_ = max_connections; }
66
67 // Get reference to shared buffer for API connections
68 std::vector<uint8_t> &get_shared_buffer_ref() { return shared_write_buffer_; }
69
70#ifdef USE_API_NOISE
71 bool save_noise_psk(psk_t psk, bool make_active = true);
72 bool clear_noise_psk(bool make_active = true);
73 void set_noise_psk(psk_t psk) { this->noise_ctx_.set_psk(psk); }
75#endif // USE_API_NOISE
76
78#ifdef USE_BINARY_SENSOR
80#endif
81#ifdef USE_COVER
82 void on_cover_update(cover::Cover *obj) override;
83#endif
84#ifdef USE_FAN
85 void on_fan_update(fan::Fan *obj) override;
86#endif
87#ifdef USE_LIGHT
89#endif
90#ifdef USE_SENSOR
91 void on_sensor_update(sensor::Sensor *obj) override;
92#endif
93#ifdef USE_SWITCH
94 void on_switch_update(switch_::Switch *obj) override;
95#endif
96#ifdef USE_TEXT_SENSOR
98#endif
99#ifdef USE_CLIMATE
101#endif
102#ifdef USE_NUMBER
103 void on_number_update(number::Number *obj) override;
104#endif
105#ifdef USE_DATETIME_DATE
107#endif
108#ifdef USE_DATETIME_TIME
110#endif
111#ifdef USE_DATETIME_DATETIME
113#endif
114#ifdef USE_TEXT
115 void on_text_update(text::Text *obj) override;
116#endif
117#ifdef USE_SELECT
118 void on_select_update(select::Select *obj) override;
119#endif
120#ifdef USE_LOCK
121 void on_lock_update(lock::Lock *obj) override;
122#endif
123#ifdef USE_VALVE
124 void on_valve_update(valve::Valve *obj) override;
125#endif
126#ifdef USE_MEDIA_PLAYER
128#endif
129#ifdef USE_WATER_HEATER
131#endif
132#ifdef USE_API_HOMEASSISTANT_SERVICES
134
135#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
136 // Action response handling
137 using ActionResponseCallback = std::function<void(const class ActionResponse &)>;
138 void register_action_response_callback(uint32_t call_id, ActionResponseCallback callback);
139 void handle_action_response(uint32_t call_id, bool success, StringRef error_message);
140#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
141 void handle_action_response(uint32_t call_id, bool success, StringRef error_message, const uint8_t *response_data,
142 size_t response_data_len);
143#endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
144#endif // USE_API_HOMEASSISTANT_ACTION_RESPONSES
145#endif // USE_API_HOMEASSISTANT_SERVICES
146#ifdef USE_API_USER_DEFINED_ACTIONS
147 void initialize_user_services(std::initializer_list<UserServiceDescriptor *> services) {
148 this->user_services_.assign(services);
149 }
150#ifdef USE_API_CUSTOM_SERVICES
151 // Only compile push_back method when custom_services: true (external components)
152 void register_user_service(UserServiceDescriptor *descriptor) { this->user_services_.push_back(descriptor); }
153#endif
154#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
155 // Action call context management - supports concurrent calls from multiple clients
156 // Returns server-generated action_call_id to avoid collisions when clients use same call_id
157 uint32_t register_active_action_call(uint32_t client_call_id, APIConnection *conn);
158 void unregister_active_action_call(uint32_t action_call_id);
160 // Send response for a specific action call (uses action_call_id, sends client_call_id in response)
161 void send_action_response(uint32_t action_call_id, bool success, StringRef error_message);
162#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
163 void send_action_response(uint32_t action_call_id, bool success, StringRef error_message,
164 const uint8_t *response_data, size_t response_data_len);
165#endif // USE_API_USER_DEFINED_ACTION_RESPONSES_JSON
166#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
167#endif
168#ifdef USE_HOMEASSISTANT_TIME
169 void request_time();
170#endif
171
172#ifdef USE_ALARM_CONTROL_PANEL
174#endif
175#ifdef USE_EVENT
176 void on_event(event::Event *obj) override;
177#endif
178#ifdef USE_UPDATE
179 void on_update(update::UpdateEntity *obj) override;
180#endif
181#ifdef USE_ZWAVE_PROXY
183#endif
184#ifdef USE_IR_RF
185 void send_infrared_rf_receive_event(uint32_t device_id, uint32_t key, const std::vector<int32_t> *timings);
186#endif
187
188 bool is_connected(bool state_subscription_only = false) const;
189
190#ifdef USE_API_HOMEASSISTANT_STATES
192 const char *entity_id; // Pointer to flash (internal) or heap (external)
193 const char *attribute; // Pointer to flash or nullptr (nullptr means no attribute)
194 std::function<void(StringRef)> callback;
195 bool once;
196
197 // Dynamic storage for external components using std::string API (custom_api_device.h)
198 // These are only allocated when using the std::string overload (nullptr for const char* overload)
199 std::unique_ptr<std::string> entity_id_dynamic_storage;
200 std::unique_ptr<std::string> attribute_dynamic_storage;
201 };
202
203 // New const char* overload (for internal components - zero allocation)
204 void subscribe_home_assistant_state(const char *entity_id, const char *attribute, std::function<void(StringRef)> &&f);
205 void get_home_assistant_state(const char *entity_id, const char *attribute, std::function<void(StringRef)> &&f);
206
207 // std::string overload with StringRef callback (for custom_api_device.h with zero-allocation callback)
208 void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
209 std::function<void(StringRef)> &&f);
210 void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
211 std::function<void(StringRef)> &&f);
212
213 // Legacy std::string overload (for custom_api_device.h - converts StringRef to std::string for callback)
214 void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
215 std::function<void(const std::string &)> &&f);
216 void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
217 std::function<void(const std::string &)> &&f);
218
219 const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
220#endif
221#ifdef USE_API_USER_DEFINED_ACTIONS
222 const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; }
223#endif
224
225#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
227#endif
228#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
230#endif
231
232 protected:
233 // Accept incoming socket connections. Only called when socket has pending connections.
234 void __attribute__((noinline)) accept_new_connections_();
235 // Remove a disconnected client by index. Swaps with last element and pops.
236 void __attribute__((noinline)) remove_client_(size_t client_index);
237
238#ifdef USE_API_NOISE
239 bool update_noise_psk_(const SavedNoisePsk &new_psk, const LogString *save_log_msg, const LogString *fail_log_msg,
240 const psk_t &active_psk, bool make_active);
241#endif // USE_API_NOISE
242#ifdef USE_API_HOMEASSISTANT_STATES
243 // Helper methods to reduce code duplication
244 void add_state_subscription_(const char *entity_id, const char *attribute, std::function<void(StringRef)> &&f,
245 bool once);
246 void add_state_subscription_(std::string entity_id, optional<std::string> attribute,
247 std::function<void(StringRef)> &&f, bool once);
248 // Legacy helper: wraps std::string callback and delegates to StringRef version
249 void add_state_subscription_(std::string entity_id, optional<std::string> attribute,
250 std::function<void(const std::string &)> &&f, bool once);
251#endif // USE_API_HOMEASSISTANT_STATES
252 // No explicit close() needed — listen sockets have no active connections on
253 // failure/shutdown. Destructor handles fd cleanup (close or abort per platform).
254 inline void destroy_socket_() {
255 delete this->socket_;
256 this->socket_ = nullptr;
257 }
258 void socket_failed_(const LogString *msg);
259 // Pointers and pointer-like types first (4 bytes each)
261#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
263#endif
264#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
266#endif
267
268 // 4-byte aligned types
269 uint32_t reboot_timeout_{300000};
270 uint32_t last_connected_{0};
271
272 // Vectors and strings (12 bytes each on 32-bit)
273 std::vector<std::unique_ptr<APIConnection>> clients_;
274 // Shared proto write buffer for all connections.
275 // Not pre-allocated: all send paths call prepare_first_message_buffer() which
276 // reserves the exact needed size. Pre-allocating here would cause heap fragmentation
277 // since the buffer would almost always reallocate on first use.
278 std::vector<uint8_t> shared_write_buffer_;
279#ifdef USE_API_HOMEASSISTANT_STATES
280 std::vector<HomeAssistantStateSubscription> state_subs_;
281#endif
282#ifdef USE_API_USER_DEFINED_ACTIONS
283 std::vector<UserServiceDescriptor *> user_services_;
284#ifdef USE_API_USER_DEFINED_ACTION_RESPONSES
285 // Active action calls - supports concurrent calls from multiple clients
286 // Uses server-generated action_call_id to avoid collisions when multiple clients use same call_id
288 uint32_t action_call_id; // Server-generated unique ID (passed to actions)
289 uint32_t client_call_id; // Client's original call_id (used in response)
291 };
292 std::vector<ActiveActionCall> active_action_calls_;
293 uint32_t next_action_call_id_{1}; // Counter for generating unique action_call_ids
294#endif // USE_API_USER_DEFINED_ACTION_RESPONSES
295#endif
296#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES
301 std::vector<PendingActionResponse> action_response_callbacks_;
302#endif
303
304 // Group smaller types together
305 uint16_t port_{6053};
306 uint16_t batch_delay_{100};
307 // Connection limits - these defaults will be overridden by config values
308 // from cv.SplitDefault in __init__.py which sets platform-specific defaults
309 uint8_t listen_backlog_{4};
311 bool shutting_down_ = false;
312 // 7 bytes used, 1 byte padding
313
314#ifdef USE_API_NOISE
317#endif // USE_API_NOISE
318};
319
320extern APIServer *global_api_server; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
321
322template<typename... Ts> class APIConnectedCondition : public Condition<Ts...> {
323 TEMPLATABLE_VALUE(bool, state_subscription_only)
324 public:
325 bool check(const Ts &...x) override {
326 return global_api_server->is_connected(this->state_subscription_only_.value(x...));
327 }
328};
329
330} // namespace esphome::api
331#endif
ESPDEPRECATED("set_retry is deprecated and will be removed in 2026.8.0. Use set_timeout or set_interval instead.", "2026.2.0") void set_retry(const std uint32_t uint8_t std::function< RetryResult(uint8_t)> && f
Definition component.h:387
Base class for all automation conditions.
Definition automation.h:304
virtual bool check(const Ts &...x)=0
StringRef is a reference to a string owned by something else.
Definition string_ref.h:26
void on_log(uint8_t level, const char *tag, const char *message, size_t message_len)
Trigger< std::string, std::string > * get_client_connected_trigger()
Definition api_server.h:226
void on_valve_update(valve::Valve *obj) override
uint16_t get_batch_delay() const
Definition api_server.h:63
void on_switch_update(switch_::Switch *obj) override
void register_action_response_callback(uint32_t call_id, ActionResponseCallback callback)
std::vector< std::unique_ptr< APIConnection > > clients_
Definition api_server.h:273
void send_infrared_rf_receive_event(uint32_t device_id, uint32_t key, const std::vector< int32_t > *timings)
void on_time_update(datetime::TimeEntity *obj) override
void on_cover_update(cover::Cover *obj) override
void add_state_subscription_(const char *entity_id, const char *attribute, std::function< void(StringRef)> &&f, bool once)
void get_home_assistant_state(const char *entity_id, const char *attribute, std::function< void(StringRef)> &&f)
Trigger< std::string, std::string > * get_client_disconnected_trigger()
Definition api_server.h:229
void on_camera_image(const std::shared_ptr< camera::CameraImage > &image) override
std::vector< UserServiceDescriptor * > user_services_
Definition api_server.h:283
void on_light_update(light::LightState *obj) override
void socket_failed_(const LogString *msg)
void on_media_player_update(media_player::MediaPlayer *obj) override
const std::vector< UserServiceDescriptor * > & get_user_services() const
Definition api_server.h:222
void initialize_user_services(std::initializer_list< UserServiceDescriptor * > services)
Definition api_server.h:147
void on_water_heater_update(water_heater::WaterHeater *obj) override
void set_port(uint16_t port)
void dump_config() override
void unregister_active_action_calls_for_connection(APIConnection *conn)
void handle_disconnect(APIConnection *conn)
void set_batch_delay(uint16_t batch_delay)
void set_reboot_timeout(uint32_t reboot_timeout)
Trigger< std::string, std::string > client_connected_trigger_
Definition api_server.h:262
void set_listen_backlog(uint8_t listen_backlog)
Definition api_server.h:64
void send_action_response(uint32_t action_call_id, bool success, StringRef error_message)
APINoiseContext & get_noise_ctx()
Definition api_server.h:74
void register_user_service(UserServiceDescriptor *descriptor)
Definition api_server.h:152
bool save_noise_psk(psk_t psk, bool make_active=true)
void on_lock_update(lock::Lock *obj) override
void setup() override
void on_date_update(datetime::DateEntity *obj) override
bool teardown() override
APINoiseContext noise_ctx_
Definition api_server.h:315
void unregister_active_action_call(uint32_t action_call_id)
void on_number_update(number::Number *obj) override
void send_homeassistant_action(const HomeassistantActionRequest &call)
socket::ListenSocket * socket_
Definition api_server.h:260
void on_event(event::Event *obj) override
void on_update(update::UpdateEntity *obj) override
void __attribute__((noinline)) remove_client_(size_t client_index)
std::vector< PendingActionResponse > action_response_callbacks_
Definition api_server.h:301
const std::vector< HomeAssistantStateSubscription > & get_state_subs() const
void subscribe_home_assistant_state(const char *entity_id, const char *attribute, std::function< void(StringRef)> &&f)
std::vector< uint8_t > shared_write_buffer_
Definition api_server.h:278
void on_climate_update(climate::Climate *obj) override
void handle_action_response(uint32_t call_id, bool success, StringRef error_message)
std::function< void(const class ActionResponse &)> ActionResponseCallback
Definition api_server.h:137
bool update_noise_psk_(const SavedNoisePsk &new_psk, const LogString *save_log_msg, const LogString *fail_log_msg, const psk_t &active_psk, bool make_active)
void set_max_connections(uint8_t max_connections)
Definition api_server.h:65
void on_binary_sensor_update(binary_sensor::BinarySensor *obj) override
bool is_connected(bool state_subscription_only=false) const
ESPPreferenceObject noise_pref_
Definition api_server.h:316
void on_fan_update(fan::Fan *obj) override
Trigger< std::string, std::string > client_disconnected_trigger_
Definition api_server.h:265
std::vector< HomeAssistantStateSubscription > state_subs_
Definition api_server.h:280
void on_zwave_proxy_request(const esphome::api::ProtoMessage &msg)
bool clear_noise_psk(bool make_active=true)
void on_select_update(select::Select *obj) override
uint16_t get_port() const
std::vector< uint8_t > & get_shared_buffer_ref()
Definition api_server.h:68
void __attribute__((noinline)) accept_new_connections_()
void on_text_update(text::Text *obj) override
void on_text_sensor_update(text_sensor::TextSensor *obj) override
std::vector< ActiveActionCall > active_action_calls_
Definition api_server.h:292
void set_noise_psk(psk_t psk)
Definition api_server.h:73
void on_datetime_update(datetime::DateTimeEntity *obj) override
void on_sensor_update(sensor::Sensor *obj) override
float get_setup_priority() const override
uint32_t register_active_action_call(uint32_t client_call_id, APIConnection *conn)
void on_shutdown() override
void on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) override
Base class for all binary_sensor-type classes.
Listener interface for camera events.
Definition camera.h:46
ClimateDevice - This is the base class for all climate integrations.
Definition climate.h:186
Base class for all cover devices.
Definition cover.h:110
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Definition light_state.h:93
Base class for all locks.
Definition lock.h:110
Base-class for all numbers.
Definition number.h:29
Base-class for all selects.
Definition select.h:29
Base-class for all sensors.
Definition sensor.h:47
Base class for all switches.
Definition switch.h:38
Base-class for all text inputs.
Definition text.h:21
Base class for all valve devices.
Definition valve.h:104
const char * message
Definition component.cpp:38
APIServer * global_api_server
struct esphome::api::SavedNoisePsk PACKED
std::array< uint8_t, 32 > psk_t
std::unique_ptr< std::string > entity_id_dynamic_storage
Definition api_server.h:199
std::unique_ptr< std::string > attribute_dynamic_storage
Definition api_server.h:200
uint16_t x
Definition tt21100.cpp:5